import Foundation
import ComposeApp
import Combine

/// ViewModel for handling Apple Sign In flow.
/// Calls APILayer directly for backend authentication.
@MainActor
class AppleSignInViewModel: ObservableObject {
    // MARK: - Published Properties
    @Published var isLoading: Bool = false
    @Published var errorMessage: String?
    @Published var isNewUser: Bool = false

    // MARK: - Private Properties
    private let appleSignInManager = AppleSignInManager()
    private let dataManager: DataManagerObservable

    // MARK: - Initialization
    init(dataManager: DataManagerObservable = .shared) {
        self.dataManager = dataManager
    }

    // MARK: - Callbacks
    var onSignInSuccess: ((Bool) -> Void)? // Bool indicates if user is verified

    // MARK: - Public Methods

    /// Initiates the Apple Sign In flow
    func signInWithApple() {
        guard !isLoading else { return }

        isLoading = true
        errorMessage = nil

        appleSignInManager.signIn { [weak self] result in
            Task { @MainActor in
                switch result {
                case .success(let credential):
                    self?.sendCredentialToBackend(credential)
                case .failure(let error):
                    self?.handleAppleError(error)
                }
            }
        }
    }

    /// Resets the error state
    func clearError() {
        errorMessage = nil
    }

    // MARK: - Private Methods

    /// Sends Apple credential to backend for verification/authentication
    private func sendCredentialToBackend(_ credential: AppleSignInCredential) {
        Task {
            do {
                let request = AppleSignInRequest(
                    idToken: credential.identityToken,
                    userId: credential.userIdentifier,
                    email: credential.email,
                    firstName: credential.firstName,
                    lastName: credential.lastName
                )
                let result = try await APILayer.shared.appleSignIn(request: request)

                if let success = result as? ApiResultSuccess<AppleSignInResponse>, let response = success.data {
                    self.handleSuccess(response)
                } else if let error = ApiResultBridge.error(from: result) {
                    self.handleBackendError(error)
                } else {
                    self.isLoading = false
                    self.errorMessage = "Sign in failed. Please try again."
                }
            } catch {
                self.isLoading = false
                self.errorMessage = ErrorMessageParser.parse(error.localizedDescription)
            }
        }
    }

    /// Handles successful authentication
    private func handleSuccess(_ response: AppleSignInResponse) {
        isLoading = false

        let user = response.user

        // Track if this is a new user
        isNewUser = response.isNewUser

        // APILayer.appleSignIn already:
        // - Stores token in DataManager
        // - Sets current user in DataManager
        // - Initializes lookups
        // - Prefetches all data

        // Share token and API URL with widget extension
        WidgetDataManager.shared.saveAuthToken(response.token)
        WidgetDataManager.shared.saveAPIBaseURL(ApiClient.shared.getBaseUrl())

        // Track Apple Sign In
        AnalyticsManager.shared.track(.userSignedInApple(isNewUser: isNewUser))

        print("Apple Sign In successful! User: \(user.username), New user: \(isNewUser)")

        // Call success callback with verification status
        onSignInSuccess?(user.verified)
    }

    /// Handles Apple Sign In errors
    private func handleAppleError(_ error: Error) {
        isLoading = false

        if let appleError = error as? AppleSignInError {
            // Don't show error for user cancellation
            if appleError.isCancellation {
                return
            }
            errorMessage = appleError.errorDescription
        } else {
            errorMessage = ErrorMessageParser.parse(error.localizedDescription)
        }
    }

    /// Handles backend API errors
    private func handleBackendError(_ error: ApiResultError) {
        isLoading = false

        if let code = error.code?.intValue {
            switch code {
            case 401:
                errorMessage = "Authentication failed. Please try again."
            case 403:
                errorMessage = "Access denied"
            case 409:
                // Conflict - let backend message explain the issue
                errorMessage = ErrorMessageParser.parse(error.message)
            case 400:
                // Bad request - validation errors from backend
                errorMessage = ErrorMessageParser.parse(error.message)
            case 500...599:
                errorMessage = "Server error. Please try again later."
            default:
                errorMessage = ErrorMessageParser.parse(error.message)
            }
        } else {
            errorMessage = ErrorMessageParser.parse(error.message)
        }

        print("Apple Sign In backend error: \(error.message)")
    }
}
