//
//  CaptureEventInteraction.swift
//  SelfieCam
//
//  Handles hardware capture events using AVCaptureEventInteraction.
//  Supports Camera Control button (iPhone 16+), Action button, and volume buttons.
//

import AVFoundation
import AVKit
import Bedrock
import SwiftUI
import UIKit

/// Manager for AVCaptureEventInteraction that handles Camera Control button events
///
/// This class wraps `AVCaptureEventInteraction` to provide hardware button support:
/// - **Camera Control button** (iPhone 16+): Full press to capture, light press for focus/exposure
/// - **Action button** (iPhone 15 Pro+): When configured for camera
/// - **Volume buttons**: Hardware shutter via system integration
@Observable @MainActor
final class CaptureEventManager {
    private(set) var isActive = false
    private(set) var isFocusLocked = false
    
    private var eventInteraction: AVCaptureEventInteraction?
    private var onCapture: (() -> Void)?
    private var onFocusLock: ((Bool) -> Void)?
    
    /// Pre-initialized haptic generators for immediate response
    private let lightHaptic = UIImpactFeedbackGenerator(style: .light)
    private let mediumHaptic = UIImpactFeedbackGenerator(style: .medium)
    private let heavyHaptic = UIImpactFeedbackGenerator(style: .heavy)
    
    /// Sets up capture event handling with the provided callbacks
    /// - Parameters:
    ///   - onCapture: Called when a capture event is triggered (full press)
    ///   - onFocusLock: Called when focus/exposure lock state changes (light press)
    func configure(
        onCapture: @escaping () -> Void,
        onFocusLock: ((Bool) -> Void)? = nil
    ) {
        self.onCapture = onCapture
        self.onFocusLock = onFocusLock
    }
    
    /// Creates and returns the AVCaptureEventInteraction to be added to a view
    func createInteraction() -> AVCaptureEventInteraction {
        Design.debugLog("📸 [CameraControl] Creating AVCaptureEventInteraction...")
        
        let interaction = AVCaptureEventInteraction(
            primary: { [weak self] event in
                Task { @MainActor [weak self] in
                    self?.handlePrimaryEvent(event)
                }
            },
            secondary: { [weak self] event in
                Task { @MainActor [weak self] in
                    self?.handleSecondaryEvent(event)
                }
            }
        )
        
        // Must explicitly enable the interaction
        interaction.isEnabled = true
        
        // Prepare haptic engines for immediate response
        prepareHaptics()
        
        self.eventInteraction = interaction
        self.isActive = true
        Design.debugLog("📸 [CameraControl] ✅ Hardware capture events ENABLED")
        Design.debugLog("📸 [CameraControl] Supported: Full press (capture), Light press (focus lock)")
        
        return interaction
    }
    
    /// Removes the interaction and cleans up
    func invalidate() {
        eventInteraction = nil
        isActive = false
        isFocusLocked = false
        Design.debugLog("📸 [CameraControl] Hardware capture events disabled")
    }
    
    // MARK: - Event Handlers
    
    private func handlePrimaryEvent(_ event: AVCaptureEvent) {
        Design.debugLog("📸 [CameraControl] PRIMARY - phase: \(event.phase.rawValue)")
        
        switch event.phase {
        case .began:
            Design.debugLog("📸 [CameraControl] PRIMARY BEGAN - Full press started")
            triggerHaptic(.medium)
            
        case .ended:
            Design.debugLog("📸 [CameraControl] PRIMARY ENDED - Triggering capture!")
            triggerHaptic(.heavy)
            onCapture?()
            
        case .cancelled:
            Design.debugLog("📸 [CameraControl] PRIMARY CANCELLED")
            
        @unknown default:
            Design.debugLog("📸 [CameraControl] PRIMARY UNKNOWN phase: \(event.phase.rawValue)")
        }
    }
    
    private func handleSecondaryEvent(_ event: AVCaptureEvent) {
        Design.debugLog("🔒 [CameraControl] SECONDARY - phase: \(event.phase.rawValue)")
        
        switch event.phase {
        case .began:
            Design.debugLog("🔒 [CameraControl] SECONDARY BEGAN - Light press! Locking focus...")
            isFocusLocked = true
            onFocusLock?(true)
            triggerHaptic(.medium)
            
        case .ended:
            Design.debugLog("🔒 [CameraControl] SECONDARY ENDED - Unlocking focus")
            isFocusLocked = false
            onFocusLock?(false)
            triggerHaptic(.light)
            
        case .cancelled:
            Design.debugLog("🔒 [CameraControl] SECONDARY CANCELLED")
            isFocusLocked = false
            onFocusLock?(false)
            
        @unknown default:
            Design.debugLog("🔒 [CameraControl] SECONDARY UNKNOWN phase: \(event.phase.rawValue)")
        }
    }
    
    // MARK: - Haptic Feedback
    
    /// Prepares haptic engines for low-latency feedback
    func prepareHaptics() {
        lightHaptic.prepare()
        mediumHaptic.prepare()
        heavyHaptic.prepare()
    }
    
    private func triggerHaptic(_ style: UIImpactFeedbackGenerator.FeedbackStyle) {
        switch style {
        case .light:
            lightHaptic.impactOccurred()
            lightHaptic.prepare()
        case .medium:
            mediumHaptic.impactOccurred()
            mediumHaptic.prepare()
        case .heavy:
            heavyHaptic.impactOccurred()
            heavyHaptic.prepare()
        default:
            let generator = UIImpactFeedbackGenerator(style: style)
            generator.impactOccurred()
        }
    }
}

// MARK: - Device Capability Check

extension CaptureEventManager {
    /// Checks if the device supports Camera Control button
    /// Note: The API is always available on iOS 18+, but the physical button is iPhone 16+ only
    static var isCameraControlSupported: Bool {
        return true
    }
    
    /// Returns a description of supported hardware capture methods
    static var supportedHardwareMethods: String {
        return "Camera Control (iPhone 16+), Action Button, Volume Buttons"
    }
}

// MARK: - AVCaptureEventPhase Extension

extension AVCaptureEventPhase {
    /// Converts AVCaptureEventPhase to our CaptureEventPhase enum
    var toCaptureEventPhase: CaptureEventPhase {
        switch self {
        case .began: return .began
        case .ended: return .ended
        case .cancelled: return .cancelled
        @unknown default: return .cancelled
        }
    }
}
