import SwiftUI

@main
struct simvisionApp: App {
    // DEVELOPMENT MODE: Set to true to bypass auth and use sample data
    private static let isDevelopmentMode = false

    @StateObject private var appState = AppState(developmentMode: simvisionApp.isDevelopmentMode)
    @State private var isInitialLoading = true
    @State private var loadingMessage = "Loading library..."

    var body: some Scene {
        WindowGroup {
            if Self.isDevelopmentMode {
                ZStack {
                    MainTabView()
                        .environmentObject(appState)
                        .opacity(isInitialLoading ? 0 : 1)

                    if isInitialLoading {
                        InitialLoadingView(message: loadingMessage)
                            .transition(.opacity)
                    }
                }
                .animation(.easeInOut(duration: 0.3), value: isInitialLoading)
                .onAppear {
                    loadSamplePlaylistAsync()
                }
                .onChange(of: appState.releaseDateFetchProgress?.current) { _, current in
                    if let current = current,
                       let total = appState.releaseDateFetchProgress?.total {
                        loadingMessage = "Loading recent releases... (\(current)/\(total))"
                    }
                }
            } else if appState.isLoading {
                InitialLoadingView(message: "Connecting...")
                    .environmentObject(appState)
            } else if appState.isAuthenticated {
                MainTabView()
                    .environmentObject(appState)
            } else {
                PasswordEntryView()
                    .environmentObject(appState)
            }
        }
    }

    @MainActor
    private func loadSamplePlaylistAsync() {
        guard let url = Bundle.main.url(forResource: "full_playlist_export", withExtension: "m3u") else {
            print("ERROR: sample_playlist.m3u not found in bundle")
            isInitialLoading = false
            return
        }

        Task.detached(priority: .userInitiated) {
            let totalStart = Date()
            print("⏱️ === LOADING TIMING START ===")

            do {
                // Step 1: Read playlist file
                await MainActor.run {
                    loadingMessage = "Reading playlist..."
                }

                var stepStart = Date()
                let content = try String(contentsOf: url, encoding: .utf8)
                let readTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 1 - Reading playlist file: \(String(format: "%.2f", readTime))s (\(content.count) characters)")

                // Step 2: Parse M3U data
                await MainActor.run {
                    loadingMessage = "Processing movies..."
                }

                stepStart = Date()
                let parser = M3UParser()
                let vodItems = try parser.parse(data: content)
                let parseTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 2 - Parsing M3U data: \(String(format: "%.2f", parseTime))s (\(vodItems.count) items)")

                // Step 3: Extract categories
                await MainActor.run {
                    loadingMessage = "Organizing categories..."
                }

                stepStart = Date()
                let categories = parser.extractCategories(from: vodItems)
                let categoryTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 3 - Extracting categories: \(String(format: "%.2f", categoryTime))s (\(categories.count) categories)")

                // Step 4: Create playlist object
                stepStart = Date()
                let playlist = Playlist(
                    vodItems: vodItems,
                    categories: categories,
                    lastUpdated: Date()
                )
                let playlistTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 4 - Creating playlist object: \(String(format: "%.2f", playlistTime))s")

                // Step 5: Compute movie groups (during loading screen)
                await MainActor.run {
                    loadingMessage = "Organizing library..."
                }

                stepStart = Date()
                let movies = vodItems.filter { $0.isMovie }
                let groups = movies.groupedByTitle()

                // Build lookup table
                var lookup: [String: MovieGroup] = [:]
                lookup.reserveCapacity(movies.count)
                for group in groups {
                    for version in group.versions {
                        lookup[version.id] = group
                    }
                }

                // Pre-compute release years for fast sorting (parallel)
                var releaseYears: [String: Int] = [:]
                releaseYears.reserveCapacity(groups.count)
                let groupCount = groups.count
                var yearsArray = [Int](repeating: 0, count: groupCount)
                let yearChunkSize = Swift.max(500, groupCount / 8)

                DispatchQueue.concurrentPerform(iterations: (groupCount + yearChunkSize - 1) / yearChunkSize) { chunkIndex in
                    let start = chunkIndex * yearChunkSize
                    let end = Swift.min(start + yearChunkSize, groupCount)
                    for i in start..<end {
                        yearsArray[i] = groups[i].primaryItem.releaseYear ?? 0
                    }
                }

                for i in 0..<groupCount {
                    releaseYears[groups[i].id] = yearsArray[i]
                }

                let groupingTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 5 - Grouping \(movies.count) movies into \(groups.count) groups: \(String(format: "%.2f", groupingTime))s")

                // Step 6: Update app state (keep loading screen visible)
                stepStart = Date()
                await MainActor.run {
                    appState.playlist = playlist
                    appState.cachedMovieGroups = groups
                    appState.movieGroupLookup = lookup
                    appState.cachedReleaseYears = releaseYears
                    appState.isAuthenticated = true
                    // Keep isInitialLoading = true until Step 7 completes
                }
                let uiUpdateTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 6 - Updating app state: \(String(format: "%.2f", uiUpdateTime))s")

                // Step 7: Load recent releases (still showing loading screen)
                await MainActor.run {
                    loadingMessage = "Loading recent releases..."
                }

                stepStart = Date()
                await appState.loadRecentReleases(forceRefresh: true)
                let recentReleasesTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 7 - Loading recent releases: \(String(format: "%.2f", recentReleasesTime))s")

                // Step 8: Load TV show data (TMDB trending + air dates)
                await MainActor.run {
                    loadingMessage = "Loading TV show data..."
                }

                stepStart = Date()
                await appState.loadTVShowData()
                let tvShowTime = Date().timeIntervalSince(stepStart)
                print("⏱️ Step 8 - Loading TV show data: \(String(format: "%.2f", tvShowTime))s")

                // Step 9: Hide loading screen - UI is now fully ready
                await MainActor.run {
                    isInitialLoading = false
                }

                let totalTime = Date().timeIntervalSince(totalStart)
                print("⏱️ === TOTAL LOADING TIME: \(String(format: "%.2f", totalTime))s ===")
                print("✅ Loaded sample playlist: \(vodItems.count) items, \(categories.count) categories, \(groups.count) movie groups")

            } catch {
                await MainActor.run {
                    print("ERROR loading sample playlist: \(error)")
                    isInitialLoading = false
                }
            }
        }
    }
}

// MARK: - Initial Loading View
struct InitialLoadingView: View {
    let message: String
    @State private var rotation: Double = 0

    var body: some View {
        ZStack {
            Color.black.ignoresSafeArea()

            VStack(spacing: 60) {
                // App icon or logo placeholder
                ZStack {
                    Circle()
                        .stroke(
                            AngularGradient(
                                gradient: Gradient(colors: [.blue, .purple, .pink, .blue]),
                                center: .center
                            ),
                            lineWidth: 8
                        )
                        .frame(width: 150, height: 150)
                        .rotationEffect(.degrees(rotation))

                    Image(systemName: "play.tv.fill")
                        .font(.system(size: 60))
                        .foregroundStyle(
                            LinearGradient(
                                colors: [.blue, .purple],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                        )
                }

                VStack(spacing: 20) {
                    Text("SimVision")
                        .font(.system(size: 50, weight: .bold))
                        .foregroundColor(.white)

                    Text(message)
                        .font(.title2)
                        .foregroundColor(.gray)
                        .contentTransition(.identity)
                        .id(message)
                }

                ProgressView()
                    .scaleEffect(2.0)
                    .tint(.white)
            }
        }
        .onAppear {
            withAnimation(.linear(duration: 2).repeatForever(autoreverses: false)) {
                rotation = 360
            }
        }
    }
}
