//
//  ClockView.swift
//  TheNoiseClock
//
//  Created by Matt Bruce on 9/7/25.
//

import SwiftUI
import Bedrock

/// Main clock display view with settings and display mode
struct ClockView: View {
    
    // MARK: - Debug Configuration
    private static let debugShowSafeAreas = false
    
    // MARK: - Properties
    @Bindable var viewModel: ClockViewModel
    /// Whether this view is currently the selected tab - prevents race conditions on tab switch
    let isOnClockTab: Bool
    @State private var idleTimer: Timer?
    @State private var didHandleTouch = false
    @State private var isViewActive = false
    
    /// Tab bar should ONLY be hidden when BOTH conditions are true:
    /// 1. We're on the clock tab (prevents hiding when user switches away)
    /// 2. Display mode is active
    private var shouldHideTabBar: Bool {
        isOnClockTab && viewModel.isDisplayMode
    }
    
    // MARK: - Body
    var body: some View {
        GeometryReader { geometry in
            // When ignoring safe areas, geometry.size IS the full screen
            let screenWidth = geometry.size.width
            let screenHeight = geometry.size.height
            let isLandscape = screenWidth > screenHeight
            
            // Get safe area insets from UIWindow since GeometryReader ignores them
            let windowInsets = Self.getWindowSafeAreaInsets()
            let safeInsets = geometry.safeAreaInsets // May be 0 due to ignoresSafeArea
            
            // Dynamic Island handling:
            // In landscape, apply symmetric padding to keep content centered
            let dynamicIslandInset = max(windowInsets.left, windowInsets.right)
            let symmetricInset = isLandscape ? dynamicIslandInset : 0

            ZStack {
                // Background extends to full screen
                viewModel.style.effectiveBackgroundColor
                
                // Main clock display container with symmetric padding for Dynamic Island
                ClockDisplayContainer(
                    currentTime: viewModel.currentTime,
                    style: viewModel.style,
                    isDisplayMode: viewModel.isDisplayMode
                )
                .padding(.leading, symmetricInset)
                .padding(.trailing, symmetricInset)
                .debugBorder(Self.debugShowSafeAreas, color: .yellow, label: "ClockDisplayContainer")
                
                // Top overlay container with symmetric padding
                ClockOverlayContainer(style: viewModel.style)
                    .padding(.leading, symmetricInset)
                    .padding(.trailing, symmetricInset)
            }
            .frame(width: screenWidth, height: screenHeight)
            .overlay(alignment: .bottomLeading) {
                if Self.debugShowSafeAreas {
                    safeAreaDebugInfo(
                        size: geometry.size,
                        windowInsets: windowInsets,
                        symmetricInset: symmetricInset
                    )
                }
            }
//            .onAppear {
//                logClockLayout(size: geometry.size, safeAreaInsets: safeInsets)
//            }
//            .onChange(of: geometry.size) { _, newSize in
//                logClockLayout(size: newSize, safeAreaInsets: safeInsets)
//            }
//            .onChange(of: safeInsets) { _, newInsets in
//                logClockLayout(size: geometry.size, safeAreaInsets: newInsets)
//            }
        }
        .ignoresSafeArea() // Extend GeometryReader to full screen, we handle safe areas manually
        .toolbar(.hidden, for: .navigationBar)
        .statusBarHidden(true)
        // Tab bar visibility controlled here but decision includes isOnClockTab from parent
        // This prevents race conditions: when tab changes, isOnClockTab becomes false immediately
        .toolbar(shouldHideTabBar ? .hidden : .visible, for: .tabBar)
        .onChange(of: shouldHideTabBar) { oldValue, newValue in
            Design.debugLog("[ClockView] shouldHideTabBar changed: \(oldValue) -> \(newValue) (isOnClockTab=\(isOnClockTab), isDisplayMode=\(viewModel.isDisplayMode))")
        }
        .simultaneousGesture(
            DragGesture(minimumDistance: 0)
                .onChanged { _ in
                    guard !didHandleTouch else { return }
                    didHandleTouch = true
                    handleUserInteraction()
                }
                .onEnded { _ in
                    didHandleTouch = false
                }
        )
        .onAppear {
            Design.debugLog("[ClockView] onAppear - setting isViewActive = true")
            isViewActive = true
            resetIdleTimer()
        }
        .onDisappear {
            Design.debugLog("[ClockView] onDisappear - setting isViewActive = false, invalidating timer")
            isViewActive = false
            idleTimer?.invalidate()
            idleTimer = nil
        }
        .onChange(of: viewModel.isDisplayMode) { _, isDisplayMode in
            if isDisplayMode {
                idleTimer?.invalidate()
                idleTimer = nil
            } else {
                resetIdleTimer()
            }
        }
    }

    // MARK: - Idle Timer
    private func resetIdleTimer() {
        idleTimer?.invalidate()
        idleTimer = nil
        guard !viewModel.isDisplayMode else { return }
        idleTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { _ in
            enterDisplayModeFromIdle()
        }
    }

    private func enterDisplayModeFromIdle() {
        // Guard against entering display mode if we're no longer on the clock tab
        guard isViewActive else {
            Design.debugLog("[ClockView] enterDisplayModeFromIdle - BLOCKED: view is not active (user switched tabs)")
            return
        }
        guard !viewModel.isDisplayMode else {
            Design.debugLog("[ClockView] enterDisplayModeFromIdle - BLOCKED: already in display mode")
            return
        }
        Design.debugLog("[ClockView] enterDisplayModeFromIdle - entering display mode")
        viewModel.toggleDisplayMode()
    }

    private func handleUserInteraction() {
        if viewModel.isDisplayMode {
            viewModel.toggleDisplayMode()
        }
        resetIdleTimer()
    }
    
    // MARK: - Safe Area Helpers
    /// Get safe area insets from the key window (works even when ignoring safe areas)
    private static func getWindowSafeAreaInsets() -> UIEdgeInsets {
        guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
              let window = scene.windows.first else {
            return .zero
        }
        return window.safeAreaInsets
    }
    
    // MARK: - Debug Views
    @ViewBuilder
    private func safeAreaDebugInfo(
        size: CGSize,
        windowInsets: UIEdgeInsets,
        symmetricInset: CGFloat
    ) -> some View {
        let isLandscape = size.width > size.height
        let hasDynamicIsland = windowInsets.left > 0 || windowInsets.right > 0
        
        VStack(alignment: .leading, spacing: 2) {
            Text("Screen: \(Int(size.width))×\(Int(size.height))")
            Text("Window Insets: L:\(Int(windowInsets.left)) R:\(Int(windowInsets.right)) T:\(Int(windowInsets.top)) B:\(Int(windowInsets.bottom))")
            Text("Symmetric Inset: \(Int(symmetricInset))")
            Text("Dynamic Island: \(hasDynamicIsland && isLandscape ? "Yes" : "No")")
            Text("Orientation: \(isLandscape ? "Landscape" : "Portrait")")
        }
        .font(.system(size: 10, weight: .bold, design: .monospaced))
        .foregroundStyle(.green)
        .padding(4)
        .background(Color.black.opacity(0.7))
        .clipShape(.rect(cornerRadius: 4))
        .padding(8)
    }
    
    // MARK: - Debug Logging
    private func logClockLayout(size: CGSize, safeAreaInsets: EdgeInsets) {
        let isLandscape = size.width > size.height
        let safeInset = max(safeAreaInsets.leading, safeAreaInsets.trailing)
        let symmetricInset = isLandscape ? safeInset : 0
        Design.debugLog("[clockLayout] size=\(String(format: "%.1f", size.width))x\(String(format: "%.1f", size.height))")
        Design.debugLog("[clockLayout] insets=(t:\(String(format: "%.1f", safeAreaInsets.top)), l:\(String(format: "%.1f", safeAreaInsets.leading)), b:\(String(format: "%.1f", safeAreaInsets.bottom)), r:\(String(format: "%.1f", safeAreaInsets.trailing)))")
        Design.debugLog("[clockLayout] isLandscape=\(isLandscape), safeInset=\(String(format: "%.1f", safeInset)), symmetricInset=\(String(format: "%.1f", symmetricInset))")
    }
}

// MARK: - Preview
#Preview {
    NavigationStack {
        ClockView(viewModel: ClockViewModel(), isOnClockTab: true)
    }
    .frame(width: 400, height: 600)
    .background(Color.black)
}
