import Foundation

/// Authentication, session, and system info.
@MainActor
final class AuthRepository {
    private let client: APIClient
    private let session: SessionStore
    private let config: APIConfiguration

    init(client: APIClient, session: SessionStore, config: APIConfiguration) {
        self.client = client
        self.session = session
        self.config = config
    }

    /// Logs in, then (optionally) selects the configured database. Auth state is
    /// carried by cookies that `URLSession` stores automatically.
    @discardableResult
    func login(email: String, password: String) async throws -> AuthResponse {
        let response: AuthResponse = try await client.send(
            "POST", .authenticate,
            body: AuthRequest(email: email, password: password),
            wrapInData: false,                 // login body is sent unwrapped
            as: AuthResponse.self
        )
        session.markAuthenticated()
        if let db = config.databaseId {
            try await selectDatabase(db)
        }
        return response
    }

    func selectDatabase(_ id: String) async throws {
        // Body is `{ "data": "<db id>" }` — a bare string under the envelope.
        let _: JSONValue = try await client.send(
            "PUT", .databaseSelection,
            body: id,
            wrapInData: true,
            as: JSONValue.self
        )
    }

    func logout() async {
        // Best effort; clear local session regardless of outcome.
        _ = try? await client.action("GET", .logout, as: JSONValue.self)
        session.clear()
    }

    func version() async throws -> VersionInfo {
        try await client.get(.version, as: VersionInfo.self)
    }
}
