//
//  MainView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 29/02/2024.
//

import SwiftUI
import LeStorage
import StoreKit

struct MainView: View {
    @EnvironmentObject var dataStore: DataStore
    //TODO: IOS BUG
    //@Environment(\.requestReview) var requestReview

    @Environment(NavigationViewModel.self) private var navigation: NavigationViewModel
    @Environment(ImportObserver.self) private var importObserver: ImportObserver

    @State private var mainViewId: UUID = UUID()
    
    var lastDataSource: String? {
        dataStore.appSettings.lastDataSource
    }
    
    var selectedTabHandler: Binding<TabDestination?> { Binding(
        get: { navigation.selectedTab },
        set: {
            if $0 == navigation.selectedTab {
//                switch navigation.selectedTab {
//                case .activity:
//                    navigation.path.removeLast()
//                case .toolbox:
//                    navigation.toolboxPath = NavigationPath()
//                case .umpire:
//                    navigation.umpirePath = NavigationPath()
//                case .ongoing:
//                    navigation.ongoingPath = NavigationPath()
//                case .tournamentOrganizer:
//                    break
//                case .none:
//                    break
//                }
            } else {
                navigation.selectedTab = $0
            }
        }
    )}
    
    var badgeText: Text? {
        return (dataStore.appSettings.didCreateAccount && StoreCenter.main.isAuthenticated == false) ? Text("!").font(.headline) : nil
    }

    var body: some View {
        TabView(selection: selectedTabHandler) {
            ActivityView()
                .tabItem(for: .activity)
                .onAppear {
                    print("on appear main view")
                    if importObserver.willCheckDataIntegrity == false {
                        importObserver.willCheckDataIntegrity = true
                        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                            _checkingDataIntegrity()
                            importObserver.willCheckDataIntegrity = false
                        }
                    }
                    
                    #if DEBUG
                    #else
                    //_requestReviewIfAppropriated()
                    #endif

                }
                .toolbarBackground(.visible, for: .tabBar)
            TournamentOrganizerView()
                .tabItem(for: .tournamentOrganizer)
                .toolbarBackground(.visible, for: .tabBar)
            OngoingContainerView()
                .tabItem(for: .ongoing)
                .badge(self.dataStore.runningMatches().count)
                .toolbarBackground(.visible, for: .tabBar)
            ToolboxView()
                .tabItem(for: .toolbox)
                .toolbarBackground(.visible, for: .tabBar)
            UmpireView()
                .tabItem(for: .umpire)
                .badge(badgeText)
                .toolbarBackground(.visible, for: .tabBar)
//            PadelClubView()
//                .tabItem(for: .padelClub)
        }
        .id(mainViewId)
        .onChange(of: dataStore.user.id) {
            print("dataStore.user.id = ", dataStore.user.id)
            print("StoreCenter.main.userId = ", StoreCenter.main.userId ?? "")
            if StoreCenter.main.userId == nil { // user disconnected
                navigation.path.removeLast(navigation.path.count)
                mainViewId = UUID()
            }
        }
        .environmentObject(dataStore)
        .task {
            //await self._checkSourceFileAvailability()
            if StoreCenter.main.isAuthenticated {
                do {
                    try await dataStore.clubs.loadDataFromServerIfAllowed()
                } catch {
                    Logger.error(error)
                }
                
                
                let ids = dataStore.user.clubs
                var save = false
                ids.forEach { clubId in
                    if dataStore.clubs.findById(clubId) == nil {
                        dataStore.user.clubs.removeAll(where: { $0 == clubId })
                        save = true
                    }
                }
                
                if save {
                    dataStore.saveUser()
                }
            }
        }
//        .refreshable {
//            Task {
//                await self._checkSourceFileAvailability()
//            }
//        }
        .overlay(alignment: .bottom) {
            if importObserver.isImportingFile() {
                _activityStatusBoxView()
            } else {
                _activityStatusBoxView()
                    .deferredRendering(for: .seconds(3))
            }
        }
    }
    
    @MainActor
    private func _requestReviewIfAppropriated() {
        let isConnected = StoreCenter.main.userId != nil
        let numberOfSignificantTournaments = dataStore.tournaments.filter({ $0.isDeleted == false && $0.endDate != nil }).count
        if isConnected || numberOfSignificantTournaments > 0 {
            //requestReview()
        }
    }

    func _activityStatusBoxView() -> some View {
        return _activityStatus()
            .toastFormatted()
    }
    
    @ViewBuilder
    func _activityStatus() -> some View {
        if importObserver.isImportingFile() {
            HStack(spacing: 20) {
                ProgressView()
                    .progressViewStyle(CircularProgressViewStyle(tint: Color.black))
                Text(importObserver.currentlyImportingLabel())
            }
        } else if let mostRecentDateAvailable = SourceFileManager.shared.mostRecentDateAvailable, let lastDataSourceDate = SourceFileManager.shared.lastDataSourceDate() {
            if mostRecentDateAvailable > lastDataSourceDate {
                Label(mostRecentDateAvailable.monthYearFormatted + " disponible", systemImage: "exclamationmark.triangle")
                    .labelStyle(.titleAndIcon)
            } else {
                Label(mostRecentDateAvailable.monthYearFormatted, systemImage: "checkmark")
                    .labelStyle(.titleAndIcon)
            }
        }
    }
    
    private func _checkSourceFileAvailability() async {
        print("dataStore.appSettings.lastDataSource :", dataStore.appSettings.lastDataSource ?? "none")
        print("check internet")
        print("check files on internet")
        print("check if any files on internet are more recent than here")
        importObserver.checkingFiles = true
        await SourceFileManager.shared.fetchData()
        importObserver.checkingFilesAttempt += 1
        importObserver.checkingFiles = false
        
        if let mostRecentDateAvailable = SourceFileManager.shared.mostRecentDateAvailable, mostRecentDateAvailable > SourceFileManager.shared.lastDataSourceDate() ?? .distantPast {

            print("importing \(mostRecentDateAvailable)")
            await _startImporting(importingDate: mostRecentDateAvailable)
        }
    }

    private func _startImporting(importingDate: Date) async {
        await MainActor.run {
            importObserver.currentImportDate = importingDate
        }
        let lastDataSource = await FileImportManager.shared.importDataFromFFT(importingDate: importingDate)
        dataStore.appSettings.lastDataSource = lastDataSource
        dataStore.appSettingsStorage.write()
        await _calculateMonthData(dataSource: lastDataSource)
        await MainActor.run {
            importObserver.currentImportDate = nil

        }
        await _downloadPreviousDate()
    }
    
    private func _calculateMonthData(dataSource: String?) async {
        if let dataSource, let mostRecentDate = URL.importDateFormatter.date(from: dataSource) {
            await MonthData.calculateCurrentUnrankedValues(fromDate: mostRecentDate)
        }
    }
        
    private func _downloadPreviousDate() async {
        await SourceFileManager.shared.getAllFiles(initialDate: "05-2024")
    }
    
    private func _checkingDataIntegrity() {
        guard importObserver.checkingFiles == false, importObserver.isImportingFile() == false else {
            return
        }
        if lastDataSource == nil {
            Task {
                await self._checkSourceFileAvailability()
            }
        } else if let lastDataSource, lastDataSource != URL.importDateFormatter.string(from: Date()) {
            Task {
                await self._checkSourceFileAvailability()
            }
        } else if let lastDataSource, let mostRecentDateImported = URL.importDateFormatter.date(from: lastDataSource) {
            
            let monthData = dataStore.monthData.sorted(by: \.creationDate)
            
            if let current = monthData.last {
                Task {
                    let updated = await SourceFileManager.shared.fetchData(fromDate: mostRecentDateImported)
                    let fileURL = SourceFileManager.shared.allFiles(true).first(where: { $0.dateFromPath == mostRecentDateImported && $0.index == 0 })
                    print("file updated", updated)
                    if let updated, updated == 1 {
                        await _startImporting(importingDate: mostRecentDateImported)
                    } else if current.dataModelIdentifier != PersistenceController.getModelVersion() && current.fileModelIdentifier != fileURL?.fileModelIdentifier() {
                        await _startImporting(importingDate: mostRecentDateImported)
                    } else if updated == 0 {
                        await _calculateMonthData(dataSource: current.monthKey)
                    }
                }
            }
        }
    }
}

//#Preview {
//    MainView()
//}
