import Foundation

@Observable
final class AuthManager {
    var isLoggedIn = false
    var isCheckingAuth = true
    var currentUser: GatewayUser?
    var error: String?

    private let api = APIClient.shared
    private let loggedInKey = "isLoggedIn"

    init() {
        isLoggedIn = UserDefaults.standard.bool(forKey: loggedInKey)
    }

    struct LoginRequest: Encodable {
        let username: String
        let password: String
    }

    struct LoginResponse: Decodable {
        let success: Bool
        let user: GatewayUser
    }

    struct AuthCheckResponse: Decodable {
        let authenticated: Bool
        let user: GatewayUser?
    }

    struct GatewayUser: Decodable, Sendable {
        let id: Int
        let username: String
        let displayName: String
    }

    func checkAuth() async {
        guard UserDefaults.standard.bool(forKey: loggedInKey) else {
            isCheckingAuth = false
            isLoggedIn = false
            return
        }
        do {
            let response: AuthCheckResponse = try await api.get("/api/auth/me")
            if response.authenticated, let user = response.user {
                currentUser = user
                isLoggedIn = true
            } else {
                isLoggedIn = false
                UserDefaults.standard.set(false, forKey: loggedInKey)
            }
        } catch {
            isLoggedIn = false
            UserDefaults.standard.set(false, forKey: loggedInKey)
        }
        isCheckingAuth = false
    }

    func login(username: String, password: String) async {
        error = nil
        do {
            let response: LoginResponse = try await api.post(
                "/api/auth/login",
                body: LoginRequest(username: username, password: password)
            )
            if response.success {
                currentUser = response.user
                isLoggedIn = true
                UserDefaults.standard.set(true, forKey: loggedInKey)
            }
        } catch let apiError as APIError {
            error = apiError.localizedDescription
        } catch {
            self.error = error.localizedDescription
        }
    }

    func logout() async {
        struct LogoutResponse: Decodable { let success: Bool }
        _ = try? await api.post("/api/auth/logout", body: [String: String]()) as LogoutResponse
        api.clearCookies()
        currentUser = nil
        isLoggedIn = false
        UserDefaults.standard.set(false, forKey: loggedInKey)
    }
}
