//
//  DialView.swift
//  LeCountdown
//
//  Created by Laurent Morvillier on 02/02/2023.
//

import SwiftUI

struct DialView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    
    @EnvironmentObject var boringContext: BoringContext
    @EnvironmentObject var conductor: Conductor

    @State var timer: AbstractTimer
    
    var frameSize: CGFloat
    
    var body: some View {
        ZStack(alignment: .topLeading) {
            
            Image(timer.imageName).resizable()
            
            Button {
                self._launchTimer(timer)
            } label: {
                self._dialView(timer: timer).padding()
            }
            
            HStack {
                Spacer()
                NavigationLink {
                    self._editView(timer: timer, isPresented: $boringContext.isShowingNewData)
                } label: {
                    Image(systemName: "gearshape.fill")
                        .font(.system(size: 24, weight: .light))
                        .padding()
                        .foregroundColor(Color.white)
                }
            }
        }
        .frame(width: frameSize, height: frameSize)
        .cornerRadius(40.0)
    }
    
    @ViewBuilder
    fileprivate func _dialView(timer: AbstractTimer) -> some View {
        Group {
            switch timer {
            case let countdown as Countdown:
                CountdownDialView(countdown: countdown)
                    .environmentObject(Conductor.maestro)
            case let alarm as Alarm:
                AlarmDialView(alarm: alarm)
                    .environmentObject(Conductor.maestro)
            case let stopwatch as Stopwatch:
                StopwatchDialView(stopwatch: stopwatch)
                    .environmentObject(Conductor.maestro)
            default:
                Text("missing dial view")
            }
        }
        .monospaced()
        .font(Font.system(size: 16.0, weight: .semibold))
        .foregroundColor(Color.white)
    }
    
    @ViewBuilder
    fileprivate func _editView(timer: AbstractTimer, isPresented: Binding<Bool>) -> some View {
        switch timer {
        case let countdown as Countdown:
            CountdownEditView(countdown: countdown, isPresented: isPresented)
        case let alarm as Alarm:
            AlarmEditView(alarm: alarm, isPresented: isPresented)
        case let stopwatch as Stopwatch:
            StopwatchEditView(stopwatch: stopwatch, isPresented: isPresented)
        default:
            Text("missing edit view")
        }
    }
    
    fileprivate func _launchTimer(_ timer: AbstractTimer) {
        
        TimerRouter.performAction(timer: timer) { result in
            switch result {
            case .success:
                break
            case .failure(let failure):
                switch failure {
                case TimerError.notificationAuthorizationMissing:
                    self.boringContext.showPermissionAlert = true
                default:
                    self.boringContext.error = failure
                    self.boringContext.showDefaultAlert = true
                }
            }
        }
        
    }
    
}

struct DialView_Previews: PreviewProvider {
    static var previews: some View {
        
        DialView(
            timer: Countdown.fake(context: PersistenceController.preview.container.viewContext),
                 frameSize: 150.0)
            .environmentObject(Conductor.maestro)
            .environmentObject(BoringContext())


    }
}
