//
//  OnboardingViewModel.swift
//  SelfieCam
//
//  Manages onboarding flow state including step navigation, permission tracking,
//  and premium status detection for dynamic content.
//

import SwiftUI
import AVFoundation
import Photos
import MijickCamera

// MARK: - Onboarding Step

/// Represents each step in the onboarding flow
enum OnboardingStep: Int, CaseIterable, Comparable {
    case welcome
    case cameraPermission
    case microphonePermission
    case photoPermission
    case settings
    case premiumOrPaywall
    
    static func < (lhs: OnboardingStep, rhs: OnboardingStep) -> Bool {
        lhs.rawValue < rhs.rawValue
    }
    
    /// Total number of steps (excluding dynamic premium/paywall which shows as one step)
    static var totalSteps: Int { 6 }
    
    /// Human-readable step number for progress indicator (1-indexed)
    var stepNumber: Int { rawValue + 1 }
}

// MARK: - Permission Status

/// Tracks the authorization status for required permissions
enum PermissionStatus: Sendable {
    case notDetermined
    case authorized
    case denied
}

// MARK: - Onboarding ViewModel

/// Observable view model for managing onboarding state and flow
@MainActor
@Observable
final class OnboardingViewModel {
    
    // MARK: - Step Navigation
    
    /// Current step in the onboarding flow
    var currentStep: OnboardingStep = .welcome
    
    /// Whether the user can proceed to the next step
    var canProceed: Bool {
        switch currentStep {
        case .welcome:
            return true
        case .cameraPermission:
            // Must have camera permission to proceed
            return cameraPermissionStatus == .authorized
        case .microphonePermission:
            // Must have microphone permission (required by camera framework)
            return microphonePermissionStatus == .authorized
        case .photoPermission:
            // Can proceed even if denied (share is an alternative)
            return true
        case .settings:
            return true
        case .premiumOrPaywall:
            return true
        }
    }
    
    // MARK: - Permission States
    
    /// Current camera permission status
    var cameraPermissionStatus: PermissionStatus = .notDetermined
    
    /// Current microphone permission status
    var microphonePermissionStatus: PermissionStatus = .notDetermined
    
    /// Current photo library permission status
    var photoPermissionStatus: PermissionStatus = .notDetermined
    
    // MARK: - Premium Status
    
    /// Premium manager instance for checking subscription status
    private let premiumManager = PremiumManager()
    
    /// Whether the user has premium access (dynamically checked)
    var isPremiumUser: Bool {
        premiumManager.isPremiumUnlocked
    }
    
    // MARK: - Settings During Onboarding
    
    /// Ring light enabled preference (applies to SettingsViewModel on completion)
    var isRingLightEnabled: Bool = true
    
    /// Camera position preference (applies to SettingsViewModel on completion)
    var prefersFrontCamera: Bool = true
    
    // MARK: - Completion
    
    /// Callback triggered when onboarding is completed
    var onComplete: (() -> Void)?
    
    // MARK: - Initialization
    
    init() {
        // Check initial permission states
        updatePermissionStates()
    }
    
    // MARK: - Permission Handling
    
    /// Updates cached permission states from system
    func updatePermissionStates() {
        // Camera permission
        switch AVCaptureDevice.authorizationStatus(for: .video) {
        case .notDetermined:
            cameraPermissionStatus = .notDetermined
        case .authorized:
            cameraPermissionStatus = .authorized
        case .denied, .restricted:
            cameraPermissionStatus = .denied
        @unknown default:
            cameraPermissionStatus = .notDetermined
        }
        
        // Microphone permission
        switch AVCaptureDevice.authorizationStatus(for: .audio) {
        case .notDetermined:
            microphonePermissionStatus = .notDetermined
        case .authorized:
            microphonePermissionStatus = .authorized
        case .denied, .restricted:
            microphonePermissionStatus = .denied
        @unknown default:
            microphonePermissionStatus = .notDetermined
        }
        
        // Photo library permission (add-only)
        switch PHPhotoLibrary.authorizationStatus(for: .addOnly) {
        case .notDetermined:
            photoPermissionStatus = .notDetermined
        case .authorized, .limited:
            photoPermissionStatus = .authorized
        case .denied, .restricted:
            photoPermissionStatus = .denied
        @unknown default:
            photoPermissionStatus = .notDetermined
        }
    }
    
    /// Requests camera permission and updates state
    func requestCameraPermission() async {
        let granted = await AVCaptureDevice.requestAccess(for: .video)
        cameraPermissionStatus = granted ? .authorized : .denied
    }
    
    /// Requests microphone permission and updates state
    func requestMicrophonePermission() async {
        let granted = await AVCaptureDevice.requestAccess(for: .audio)
        microphonePermissionStatus = granted ? .authorized : .denied
    }
    
    /// Requests photo library permission and updates state
    func requestPhotoPermission() async {
        let status = await PHPhotoLibrary.requestAuthorization(for: .addOnly)
        switch status {
        case .authorized, .limited:
            photoPermissionStatus = .authorized
        case .denied, .restricted:
            photoPermissionStatus = .denied
        case .notDetermined:
            photoPermissionStatus = .notDetermined
        @unknown default:
            photoPermissionStatus = .notDetermined
        }
    }
    
    // MARK: - Navigation
    
    /// Advances to the next step if possible
    func advanceToNextStep() {
        guard canProceed else { return }
        
        if let nextStep = OnboardingStep(rawValue: currentStep.rawValue + 1) {
            currentStep = nextStep
        }
    }
    
    /// Goes back to the previous step
    func goToPreviousStep() {
        if let previousStep = OnboardingStep(rawValue: currentStep.rawValue - 1) {
            currentStep = previousStep
        }
    }
    
    /// Completes onboarding and applies settings
    func completeOnboarding(settingsViewModel: SettingsViewModel) {
        // Apply user preferences from onboarding
        settingsViewModel.isRingLightEnabled = isRingLightEnabled
        
        if prefersFrontCamera {
            settingsViewModel.cameraPosition = .front
        } else {
            settingsViewModel.cameraPosition = .back
        }
        
        // Trigger completion callback
        onComplete?()
    }
    
    // MARK: - Settings URL
    
    /// Opens system Settings app for this app's permissions
    func openSettings() {
        guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
        UIApplication.shared.open(settingsURL)
    }
}
