//
//  ContentView.swift
//  LeCountdown
//
//  Created by Laurent Morvillier on 20/01/2023.
//

import SwiftUI
import CoreData
import Combine

class BoringContext : ObservableObject {
    
    @Published var isShowingNewData = false
    @Published var error: Error?
    @Published var showDefaultAlert: Bool = false
    @Published var showPermissionAlert: Bool = false
    @Published var siriTimer: AbstractTimer? = nil
}

class TimerSpot : Identifiable, Equatable {
    
    var id: Int16 { return self.order }
    
    var order: Int16
    var timer: AbstractTimer?
    
    init(order: Int16, timer: AbstractTimer? = nil) {
        self.order = order
        self.timer = timer
    }
    
    func setOrder(order: Int16) {
        self.order = order
        self.timer?.order = order
    }
    
    static func == (lhs: TimerSpot, rhs: TimerSpot) -> Bool {
        return lhs.order == rhs.order && lhs.timer?.stringId == rhs.timer?.stringId
    }

}

struct ContentView<T : AbstractTimer>: View {

    @StateObject var boringContext: BoringContext = BoringContext()
    @EnvironmentObject var conductor: Conductor

    @Environment(\.managedObjectContext) private var viewContext
    
    @State private var isEditing: Bool = false
    
    @State private var tipsShown: Bool = false
    
    @State private var siriTipShown: Bool = false
    
    @State private var showSettingsSheet: Bool = false

    var body: some View {
        
        VStack {
            
            TimersView(isEditing: self.$isEditing)
                .environment(\.managedObjectContext, viewContext)
                .environmentObject(self.boringContext)
            
            //                if !self.tipsShown, let tip = Preferences.tipToShow {
            //                    TipView(tip: tip) {
            //                        self._hideTip(tip)
            //                    }.padding()
            //                }
            
            if !conductor.liveTimers.isEmpty {
                
                Spacer()
                
                SiriTimerView(timer: self.boringContext.siriTimer)
                
                HStack(alignment: .center) {
                    VolumeView().padding(12.0)
                }.frame(width: 300.0, height: 40.0)
                    .background(Color(white: 0.9))
                    .cornerRadius(16.0)
                
                LiveTimerListView()
                    .environment(\.managedObjectContext, viewContext)
                    .environmentObject(conductor)
                    .padding(.horizontal, 12.0)
                    .foregroundColor(.black)
                    .background(Color(white: 0.9))
                    .cornerRadius(32.0, corners: [.topRight, .topLeft])
            }
        }
        
        .navigationTitle("Home")
        .alert(boringContext.error?.localizedDescription ?? "missing error", isPresented: $boringContext.showDefaultAlert) {
            Button("OK", role: .cancel) { }
        }
        .alert("You need to accept notifications, please check your settings", isPresented: $boringContext.showPermissionAlert) {
            PermissionAlertView()
        }
        .sheet(isPresented: self.$boringContext.isShowingNewData, content: {
        })
        .sheet(isPresented: self.$showSettingsSheet, content: {
            SettingsView()
                .presentationDetents([.height(150.0)])
        })
        .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                Button {
                    withAnimation {
                        self.isEditing.toggle()
                    }
                } label: {
                    Text(self.isEditing ? "Done" : "Edit")
                }
            }
            ToolbarItem(placement: .navigationBarTrailing) {
                Button {
                    withAnimation {
                        self.showSettingsSheet.toggle()
                    }
                } label: {
                    Image(systemName: "gearshape.fill")
                }
            }
        }
        .onAppear {
            self._askPermissions()
        }
        .onOpenURL { url in
            self._performActionIfPossible(url: url)
        }
        
    }
    
    // MARK: - Business

    fileprivate func _hideTip(_ tip: Tip) {
        Preferences.lastShownTip = tip.rawValue
        self.tipsShown = true
    }
    
    fileprivate func _askPermissions() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { success, error in
            print("requestAuthorization > success = \(success), error = \(String(describing: error))")
        }
    }
    
    fileprivate func _performActionIfPossible(url: URL) {
        
        // hide new window if launching a timer
        self.boringContext.isShowingNewData = false
        
        print("_performActionIfPossible")
        
        let urlString = url.absoluteString
        if let timer = viewContext.object(stringId: urlString) as? AbstractTimer {
            
            if timer is T {
                print("performAction")

                TimerRouter.performAction(timer: timer) { result in
                    switch result {
                    case .success:
                        break
                    case .failure(let failure):
                        switch failure {
                        case TimerRouterError.notificationAuthorizationMissing:
                            self.boringContext.showPermissionAlert = true
                        default:
                            self.boringContext.error = failure
                            self.boringContext.showDefaultAlert = true
                        }
                    }
                }

            }
            
//            print("Start countdown: \(countdown.name ?? ""), \(countdown.duration)")
//            self._launchCountdown(countdown)
        } else {
            print("timer not found with id = \(urlString)")
        }
        
    }
    
}

struct MainToolbarView: View {
    
    var isShowingNewData: Binding<Bool>
    
    var body: some View {
        Button {
            self.isShowingNewData.wrappedValue = true
        } label: {
            HStack {
                Image(systemName: "timer")
                Text("countdown")
            }
        }
        Button {
            self.isShowingNewData.wrappedValue = true
        } label: {
            HStack {
                Image(systemName: "stopwatch")
                Text("stopwatch")
            }
        }
        Button {
            self.isShowingNewData.wrappedValue = true
        } label: {
            HStack {
                Image(systemName: "alarm")
                Text("alarm")
            }
        }

    }
}

fileprivate extension Countdown {
    
    var endDate: Date? {
        return Conductor.maestro.currentCountdowns[self.stringId]?.end
    }
    
    var isLive: Bool {
        return endDate != nil
    }
    
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView<Countdown>().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)                    .environmentObject(Conductor.maestro)

    }
}
