//
//  vibesApp.swift
//  vibes
//
//  Created by Yamill Vallecillo on 6/30/25.
//

import SwiftUI
import FirebaseCore
import GoogleSignIn
import Nuke
import AVFoundation

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        guard let clientID = FirebaseApp.app()?.options.clientID else { fatalError() }
        let config = GIDConfiguration(clientID: clientID)
        GIDSignIn.sharedInstance.configuration = config

        return true
    }
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        return GIDSignIn.sharedInstance.handle(url)
    }
}

final class AppState: ObservableObject {
    @Published var selectedTab: NavTab = .hooks
    @Published var showOmniplayer: Bool = false
    @Published var showTweaksSheet: Bool = false
}

final class TabBarState: ObservableObject {
    // Tracks whether the tab bar bottom accessory is expanded (vs inline),
    // so player views can adjust their bottom padding accordingly.
    @Published var isTabBottomAccessoryExpanded: Bool = true
}

@main
struct vibesApp: App {
    @StateObject var appState = AppState()
    @StateObject var authViewModel = AuthenticationViewModel()
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    init() {
        // Clear UserDefaults for prototype testing
        clearPrototypeData()

        // Force dark mode for the entire app
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
            windowScene.windows.forEach { window in
                window.overrideUserInterfaceStyle = .dark
            }
        }

        // Set dark mode as default for all new windows
        UIWindow.appearance().overrideUserInterfaceStyle = .dark

        // Register custom fonts
        registerFonts()

        // Configure navigation bar fonts
        configureNavigationBarFonts()
        
        ImagePipeline.shared = .init(configuration: .withDataCache)
    }
    
    var body: some Scene {
        WindowGroup {
            RootSceneView()
                .environmentObject(authViewModel)
                .environmentObject(appState)
                .preferredColorScheme(.dark)
        }
    }
    
    private func clearPrototypeData() {
        let userDefaults = UserDefaults.standard
        
        // Clear workspace-related data
        userDefaults.removeObject(forKey: "SavedWorkspaces")
        userDefaults.removeObject(forKey: "WorkspaceSongs")
        
        // Clear any other prototype data keys here as needed
        // userDefaults.removeObject(forKey: "OtherPrototypeKey")
        
        // Force synchronization
        userDefaults.synchronize()
        
        print("🧹 Cleared all prototype data from UserDefaults")
    }
    
    private func registerFonts() {
        // Register fonts from the fonts directory
        let fontFiles = [
            "InputSans-Regular.ttf",
            "InputSans-Light.ttf",
            "InputSans-Medium.ttf",
            "InputSans-ExtraLight.ttf",
            "PPNeueMontreal-Regular.otf",
            "PPNeueMontreal-Medium.otf",
            "PPNeueMontreal-SemiBold.otf",
            "PPNeueMontreal-Book.otf",
            "PPNeueMontreal-Italic.otf",
            "PPNeueMontreal-MediumItalic.otf",
            "PPNeueMontreal-BookItalic.otf",
            "PPNeueMontreal-SemiBolditalic.otf",
            "PPEditorialNew-Regular.otf",
            "PPEditorialNew-Light.otf",
            "PPEditorialNew-Italic.otf",
            "PPEditorialNew-LightItalic.otf"
        ]

        // Try to register fonts with different approaches
        for fontFile in fontFiles {
            let components = fontFile.components(separatedBy: ".")
            let fileName = components.first!
            let fileExtension = components.last!

            var fontURL: URL?

            // Try different ways to find the font
            // 1. In fonts subdirectory
            fontURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension, subdirectory: "fonts")

            // 2. In main bundle
            if fontURL == nil {
                fontURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension)
            }

            // 3. Try with full path
            if fontURL == nil, let bundlePath = Bundle.main.resourcePath {
                let fullPath = "\(bundlePath)/fonts/\(fontFile)"
                if FileManager.default.fileExists(atPath: fullPath) {
                    fontURL = URL(fileURLWithPath: fullPath)
                }
            }

            if let url = fontURL {
                var error: Unmanaged<CFError>?
                CTFontManagerRegisterFontsForURL(url as CFURL, .process, &error)
            }
        }
    }

    private func configureNavigationBarFonts() {
        // MARK: - Navigation Bar Title Fonts (Placeholder Values - Adjust as Needed)

        // Large Title Font Configuration (default iOS size is 34pt)
        let largeTitleFontSize: CGFloat = 28
        let largeTitleFont = UIFont(name: "PPNeueMontreal-SemiBold", size: largeTitleFontSize)!

        // Inline/Regular Title Font Configuration (default iOS size is 17pt)
        let inlineTitleFontSize: CGFloat = 18
        let inlineTitleFont = UIFont(name: "PPNeueMontreal-SemiBold", size: inlineTitleFontSize)!

        // Configure appearance for navigation bar
        let appearance = UINavigationBarAppearance()

        // Set large title font
        appearance.largeTitleTextAttributes = [
            .font: largeTitleFont,
            .foregroundColor: UIColor(Color(hex: "#f7f4ef"))  // Foreground.primary
        ]

        // Set inline title font
        appearance.titleTextAttributes = [
            .font: inlineTitleFont,
            .foregroundColor: UIColor(Color(hex: "#f7f4ef"))  // Foreground.primary
        ]

        // Apply to all navigation bars
        UINavigationBar.appearance().standardAppearance = appearance
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
        UINavigationBar.appearance().compactAppearance = appearance
        
        UISegmentedControl.appearance().setTitleTextAttributes(
            [
                .font: UIFont(name: "PPNeueMontreal-Medium", size: 14)!,
            ], for: .normal)
    }
}

struct RootSceneView: View {
    private let audioManager = AudioManager.shared
    @Environment(\.scenePhase) private var scenePhase
    @EnvironmentObject private var authViewModel: AuthenticationViewModel
    @EnvironmentObject private var appState: AppState
    @State private var hasReplacedWindow = false

    var body: some View {
        AuthContainerView()
            .environmentObject(authViewModel)
            .environmentObject(appState)
            .environment(audioManager)
            .onAppear {
                // Ensure dark mode is applied when the view appears
                if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
                    windowScene.windows.forEach { window in
                        window.overrideUserInterfaceStyle = .dark
                    }
                }
            }
            .onChange(of: scenePhase) { _, newPhase in
                switch newPhase {
                case .background:
                    // If hooks is playing when app goes to background, stop hooks playback
                    if audioManager.playbackContext == .hooks {
                        audioManager.stopHooksPlayback()
                    }
                    // Primary context snapshot is kept for restoration
                case .active:
                    // No-op; primary snapshot restoration is handled by AudioManager init
                    break
                @unknown default:
                    break
                }
            }
    }
}
