//
//  CustomCameraScreen.swift
//  CameraTester
//
//  Created by Matt Bruce on 1/2/26.
//

import AVFoundation
import SwiftUI
import Bedrock
import MijickCamera

// MARK: - Custom Camera Screen

struct CustomCameraScreen: MCameraScreen {
    @ObservedObject var cameraManager: CameraManager
    let namespace: Namespace.ID
    let closeMCameraAction: () -> ()
    
    /// Shared camera settings state - using Observable class prevents MCamera recreation
    var cameraSettings: SettingsViewModel
    
    /// Callback when photo is captured - bypasses MijickCamera's callback system
    var onPhotoCaptured: ((UIImage) -> Void)?

    // Center Stage is now managed by settings


    
    // Screen flash state for front camera
    @State private var isShowingScreenFlash: Bool = false
    @State private var originalBrightness: CGFloat = UIScreen.main.brightness

    // Timer countdown state
    @State private var countdownSeconds: Int = 0
    @State private var isCountdownActive: Bool = false

    // Pinch to zoom gesture state
    @GestureState private var magnification: CGFloat = 1.0
    @State private var lastMagnification: CGFloat = 1.0

    var body: some View {
        ZStack {
            // Camera preview with pinch gesture - Metal layer doesn't respect SwiftUI clipping
            createCameraOutputView()
                .ignoresSafeArea()
                .scaleEffect(x: cameraSettings.isMirrorFlipped ? -1 : 1, y: 1) // Apply horizontal mirror flip
                .gesture(
                    MagnificationGesture()
                        .updating($magnification) { currentState, gestureState, transaction in
                            gestureState = currentState
                        }
                        .onEnded { value in
                            let newZoom = lastMagnification * value
                            lastMagnification = newZoom
                            // Clamp to reasonable range
                            let clampedZoom = min(max(newZoom, 1.0), 5.0)
                            do {
                                try setZoomFactor(clampedZoom)
                            } catch {
                                print("Failed to set zoom factor: \(error)")
                            }
                        }
                )

            // Ring light overlay - covers corners and creates rounded inner edge
            // When ring light is off, still show black corners to maintain rounded appearance
            RingLightOverlay(
                color: cameraSettings.isRingLightEnabled ? cameraSettings.lightColor : .black,
                width: cameraSettings.isRingLightEnabled ? cameraSettings.ringSize : Design.CornerRadius.large,
                opacity: cameraSettings.isRingLightEnabled ? cameraSettings.ringLightOpacity : 1.0,
                cornerRadius: Design.CornerRadius.large
            )
            .allowsHitTesting(false) // Allow touches to pass through to camera view

            // UI overlay - responsive to orientation
            GeometryReader { geometry in
                let isLandscape = geometry.size.width > geometry.size.height

                if isLandscape {
                    // Landscape layout: capture button on left with zoom above
                    VStack {
                        Spacer()
                        CaptureButton(action: { performCapture() })
                        Spacer()
                    }
                    .padding(.leading, Design.Spacing.large)
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                } else {
                    // Portrait layout: capture button at bottom
                    VStack(spacing: 0) {
                        Spacer()

                        // Bottom controls
                        VStack(spacing: Design.Spacing.large) {
                            // Zoom indicator (shows "Center Stage" when active)
                            ZoomControlView(
                                zoomFactor: zoomFactor,
                                isCenterStageActive: cameraSettings.isCenterStageEnabled
                            )

                            // Capture Button with timer indicator badge
                            CaptureButton(action: { performCapture() })
                                .overlay(alignment: .bottomTrailing) {
                                    if cameraSettings.selectedTimer.seconds > 0 {
                                        ZStack {
                                            Circle()
                                                .fill(Color.black.opacity(Design.Opacity.accent))
                                                .frame(width: 24, height: 24)
                                            Text(cameraSettings.selectedTimer.displayName)
                                                .font(.system(size: 10, weight: .bold))
                                                .foregroundColor(.white)
                                        }
                                        .offset(x: 4, y: 4)
                                    }
                                }
                                .padding(.bottom, Design.Spacing.large)
                        }
                        .padding(.horizontal, Design.Spacing.large)
                    }
                }
            }


            
            // Countdown overlay
            if isCountdownActive {
                ZStack {
                    Color.black.opacity(0.3)
                        .ignoresSafeArea()

                    VStack {
                        Text("\(countdownSeconds)")
                            .font(.system(size: 120, weight: .bold, design: .rounded))
                            .foregroundColor(.white)
                            .shadow(radius: 10)

                        Text("Get ready!")
                            .font(.title2)
                            .foregroundColor(.white.opacity(0.8))
                    }
                }
                .transition(.opacity)
            }

            // Screen flash overlay for front camera
            if isShowingScreenFlash {
                screenFlashColor
                    .ignoresSafeArea()
                    .transition(.opacity)
            }
        }
        .animation(.easeInOut(duration: 0.05), value: isShowingScreenFlash)
        .animation(.easeInOut(duration: 0.3), value: isCountdownActive)
        .onAppear {
            // Set flash mode from saved settings
            setFlashMode(cameraSettings.flashMode.toMijickFlashMode)
            // Tell MijickCamera whether to disable iOS flash (only matters if sync is on)
            updateFlashSyncState()
            // Initialize zoom gesture state
            lastMagnification = zoomFactor
        }
        .onChange(of: cameraSettings.isFlashSyncedWithRingLight) { _, _ in
            // Only update when sync setting changes, not on every color change
            updateFlashSyncState()
        }
        .onChange(of: cameraManager.capturedMedia) { _, newMedia in
            // Directly observe capture completion - bypasses MijickCamera's callback issues
            if let media = newMedia, let image = media.getImage() {
                print("CustomCameraScreen detected captured media!")
                onPhotoCaptured?(image)
                // Clear the captured media so next capture works
                cameraManager.setCapturedMedia(nil)
            }
        }
    }



    // MARK: - Actions

    private func updateFlashSyncState() {
        // Tell MijickCamera whether we're handling flash ourselves (sync enabled)
        // or if iOS should handle it (sync disabled)
        // We use .white as a placeholder - the actual color comes from ringLightColor in SwiftUI
        if cameraSettings.isFlashSyncedWithRingLight {
            setScreenFlashColor(.white) // Non-nil = we handle flash, disable iOS flash
        } else {
            setScreenFlashColor(nil) // nil = let iOS handle Retina Flash
        }
    }

    /// The color to use for screen flash overlay
    private var screenFlashColor: Color {
        cameraSettings.isFlashSyncedWithRingLight ? cameraSettings.lightColor : .white
    }

    /// Whether to use custom screen flash (front camera + flash on + sync enabled)
    private var shouldUseCustomScreenFlash: Bool {
        cameraPosition == .front && cameraSettings.flashMode != .off && cameraSettings.isFlashSyncedWithRingLight
    }

    /// Performs capture with timer countdown and screen flash if needed
    private func performCapture() {
        // Check if timer is enabled
        let timerSeconds = cameraSettings.selectedTimer.seconds

        if timerSeconds > 0 && !isCountdownActive {
            // Start countdown
            startCountdown(seconds: timerSeconds)
        } else if !isCountdownActive {
            // No timer or countdown already running, proceed with capture
            performActualCapture()
        }
    }

    /// Starts the countdown timer
    private func startCountdown(seconds: Int) {
        countdownSeconds = seconds
        isCountdownActive = true

        Task { @MainActor in
            while countdownSeconds > 0 {
                try? await Task.sleep(for: .seconds(1))
                countdownSeconds -= 1
            }

            // Countdown finished, perform capture
            isCountdownActive = false
            performActualCapture()
        }
    }

    /// Performs the actual capture with screen flash if needed
    private func performActualCapture() {
        print("performActualCapture called - shouldUseCustomScreenFlash: \(shouldUseCustomScreenFlash)")
        if shouldUseCustomScreenFlash {
            // Save original brightness and boost to max
            originalBrightness = UIScreen.main.brightness
            UIScreen.main.brightness = 1.0

            // Show flash overlay
            isShowingScreenFlash = true

            // Wait for camera to adjust to bright screen, then capture
            Task { @MainActor in
                try? await Task.sleep(for: .milliseconds(150))
                print("Calling captureOutput() with custom flash")
                captureOutput()

                // Keep flash visible briefly after capture
                try? await Task.sleep(for: .milliseconds(100))
                isShowingScreenFlash = false
                UIScreen.main.brightness = originalBrightness
            }
        } else {
            // Normal capture (iOS handles Retina Flash for front camera if needed)
            print("Calling captureOutput() without custom flash")
            captureOutput()
        }
    }
}
