import SwiftUI
import ComposeApp

/// User's intent during onboarding
enum OnboardingIntent: String {
    case unknown
    case startFresh    // Creating a new residence
    case joinExisting  // Joining with a share code
}

/// Manages the state of the onboarding flow
@MainActor
class OnboardingState: ObservableObject {
    static let shared = OnboardingState()

    // MARK: - Persisted State (via @AppStorage, survives app restarts)

    /// Whether the user has completed onboarding.
    /// This is the persisted flag read at launch to decide whether to show onboarding.
    /// When set to `true`, Kotlin DataManager is also updated to keep both layers in sync.
    @AppStorage("hasCompletedOnboarding") var hasCompletedOnboarding: Bool = false {
        didSet {
            // Keep Kotlin DataManager in sync so Android/shared code sees the same value.
            ComposeApp.DataManager.shared.setHasCompletedOnboarding(completed: hasCompletedOnboarding)
        }
    }

    /// The name of the residence being created during onboarding
    @AppStorage("onboardingResidenceName") var pendingResidenceName: String = ""

    /// Backing storage for user intent (persisted across app restarts)
    @AppStorage("onboardingUserIntent") private var userIntentRaw: String = OnboardingIntent.unknown.rawValue

    // MARK: - Transient State (via @Published, reset each session as needed)

    /// The ID of the residence created during onboarding (used for task creation)
    @Published var createdResidenceId: Int32? = nil

    // MARK: - Home Profile State (collected during onboarding)

    @Published var pendingHeatingType: String? = nil
    @Published var pendingCoolingType: String? = nil
    @Published var pendingWaterHeaterType: String? = nil
    @Published var pendingRoofType: String? = nil
    @Published var pendingHasPool: Bool = false
    @Published var pendingHasSprinklerSystem: Bool = false
    @Published var pendingHasSeptic: Bool = false
    @Published var pendingHasFireplace: Bool = false
    @Published var pendingHasGarage: Bool = false
    @Published var pendingHasBasement: Bool = false
    @Published var pendingHasAttic: Bool = false
    @Published var pendingExteriorType: String? = nil
    @Published var pendingFlooringPrimary: String? = nil
    @Published var pendingLandscapingType: String? = nil

    /// The user's selected intent (start fresh or join existing).
    /// Reads/writes the persisted @AppStorage value and notifies SwiftUI of the change.
    var userIntent: OnboardingIntent {
        get { OnboardingIntent(rawValue: userIntentRaw) ?? .unknown }
        set {
            userIntentRaw = newValue.rawValue
            objectWillChange.send()
        }
    }

    /// Current step in the onboarding flow
    @Published var currentStep: OnboardingStep = .welcome

    /// Whether onboarding is currently active
    @Published var isOnboardingActive: Bool = false

    private init() {}

    /// Start the onboarding flow
    func startOnboarding() {
        isOnboardingActive = true
        currentStep = .welcome
        userIntent = .unknown
    }

    /// Move to the next step in the flow
    /// Order: Welcome → Features → Name → Account → Verify → Home Profile → Tasks → Upsell
    func nextStep() {
        switch currentStep {
        case .welcome:
            if userIntent == .joinExisting {
                currentStep = .createAccount
            } else {
                currentStep = .valueProps
            }
        case .valueProps:
            currentStep = .nameResidence
        case .nameResidence:
            currentStep = .createAccount
        case .createAccount:
            currentStep = .verifyEmail
        case .verifyEmail:
            if userIntent == .joinExisting {
                currentStep = .joinResidence
            } else {
                currentStep = .homeProfile
            }
        case .joinResidence:
            completeOnboarding()
        case .residenceLocation:
            // Skip past this step if we somehow land here
            currentStep = .homeProfile
        case .homeProfile:
            currentStep = .firstTask
        case .firstTask:
            completeOnboarding()
        case .subscriptionUpsell:
            completeOnboarding()
        }
    }

    /// Skip to a specific step
    func skipTo(_ step: OnboardingStep) {
        currentStep = step
    }

    /// Complete the onboarding flow.
    /// Setting `hasCompletedOnboarding` also syncs with Kotlin DataManager via `didSet`.
    /// Guards against completing without authentication to prevent broken state.
    func completeOnboarding() {
        guard AuthenticationManager.shared.isAuthenticated else {
            // Don't complete onboarding without auth
            return
        }
        hasCompletedOnboarding = true
        isOnboardingActive = false
        pendingResidenceName = ""
        createdResidenceId = nil
        userIntent = .unknown
        resetHomeProfile()
    }

    /// Reset onboarding state (useful for testing or re-onboarding).
    /// Setting `hasCompletedOnboarding` also syncs with Kotlin DataManager via `didSet`.
    func reset() {
        hasCompletedOnboarding = false
        isOnboardingActive = false
        pendingResidenceName = ""
        createdResidenceId = nil
        userIntent = .unknown
        currentStep = .welcome
        resetHomeProfile()
    }

    /// Reset all home profile fields
    private func resetHomeProfile() {
        pendingHeatingType = nil
        pendingCoolingType = nil
        pendingWaterHeaterType = nil
        pendingRoofType = nil
        pendingHasPool = false
        pendingHasSprinklerSystem = false
        pendingHasSeptic = false
        pendingHasFireplace = false
        pendingHasGarage = false
        pendingHasBasement = false
        pendingHasAttic = false
        pendingExteriorType = nil
        pendingFlooringPrimary = nil
        pendingLandscapingType = nil
    }
}

/// Steps in the onboarding flow
enum OnboardingStep: Int, CaseIterable {
    case welcome = 0
    case nameResidence = 1
    case valueProps = 2
    case createAccount = 3
    case verifyEmail = 4
    case joinResidence = 5      // Only for users joining with a code
    case residenceLocation = 6  // ZIP code entry for regional templates
    case homeProfile = 7        // Home systems & features (optional)
    case firstTask = 8
    case subscriptionUpsell = 9

    var title: String {
        switch self {
        case .welcome:
            return "Welcome"
        case .nameResidence:
            return "Name Your Home"
        case .valueProps:
            return "Features"
        case .createAccount:
            return "Create Account"
        case .verifyEmail:
            return "Verify Email"
        case .joinResidence:
            return "Join Residence"
        case .residenceLocation:
            return "Your Location"
        case .homeProfile:
            return "Home Profile"
        case .firstTask:
            return "First Task"
        case .subscriptionUpsell:
            return "Go Pro"
        }
    }
}
