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

import Foundation
import NotificationCenter

enum TimerRouterError: Error {
    case notificationAuthorizationMissing
    case unmanagedTimer(_ timer: AbstractTimer)
}

class TimerRouter {
    
    static func performAction(timer: AbstractTimer) async throws -> Bool {
        
        return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Bool, Error>) in
            self.performAction(timer: timer) { result in
                switch result {
                case .success:
                    continuation.resume(returning: true)
                case .failure(let failure):
                    continuation.resume(throwing: failure)
                }
            }
        }
        
    }
    
    static func performAction(timer: AbstractTimer, handler: @escaping (Result<Void, Error>) -> Void) {
        switch timer {
        case let countdown as Countdown:
            self._launchCountdown(countdown, handler: handler)
        case let stopwatch as Stopwatch:
            self._startStopwatch(stopwatch, handler: handler)
        case let alarm as Alarm:
            self._scheduleAlarm(alarm, handler: handler)
        default:
            handler(Result.failure(TimerRouterError.unmanagedTimer(timer)))
            print("missing launcher for \(self)")
        }
        
    }
    
    static func stopTimer(timer: AbstractTimer) {
        switch timer {
        case let countdown as Countdown:
            Conductor.maestro.cancelCountdown(id: countdown.stringId)
        case let stopwatch as Stopwatch:
            self._stopStopwatch(stopwatch)
        default:
            print("missing launcher for \(self)")
        }
    }
    
    fileprivate static func _launchCountdown(_ countdown: Countdown, handler: @escaping (Result<Void, Error>) -> Void) {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            
            switch settings.authorizationStatus {
            case .notDetermined, .denied:
                handler(.failure(TimerRouterError.notificationAuthorizationMissing))
            default:
                CountdownScheduler.master.scheduleIfPossible(countdown: countdown) { result in
                    switch result {
                    case .success:
                        handler(.success(Void()))
                    case .failure(let failure):
                        handler(.failure(failure))
                    }
                }
            }
        }

    }
    
    fileprivate static func _scheduleAlarm(_ alarm: Alarm, handler: @escaping (Result<Void, Error>) -> Void) {
        
    }
    
    fileprivate static func _startStopwatch(_ stopwatch: Stopwatch, handler: @escaping (Result<Void, Error>) -> Void) {
        Conductor.maestro.startStopwatch(stopwatch)
        handler(.success(Void()))
    }
    
    fileprivate static func _stopStopwatch(_ stopwatch: Stopwatch, end: Date? = nil) {
        Conductor.maestro.stopStopwatch(stopwatch)
    }
    
}
