import SwiftUI
import EventKit
import EventKitUI

enum EventsError: Error {
    case invalidStartDate
    case invalidEndDate
    case unknownAccessState
}

class EventsService: ObservableObject {
    static let standard = EventsService()
    
    var eventStore = EKEventStore()
    
    func requestPermission() async throws {
        return try await withCheckedThrowingContinuation({ continuation in
            eventStore.requestAccess(to: .event) { granted, error in
                if granted {
                    continuation.resume()
                } else {
                    continuation.resume(throwing: error ?? EventsError.unknownAccessState)
                }
            }
        })
    }
    
    func createEKEvent(post: Post, postEvent: Post.Event) throws -> EKEvent {
        let event = EKEvent(eventStore: eventStore)
        event.calendar = eventStore.defaultCalendarForNewEvents
        event.title = post.title.rendered
        event.isAllDay = false
        
        event.startDate = postEvent.startDate
        
        if let endDate = postEvent.endDate {
            event.endDate = endDate
        } else {
            guard let endDate = Calendar.current.date(byAdding: .hour, value: 1, to: event.startDate) else {
                throw(EventsError.invalidStartDate)
            }
            
            event.endDate = endDate
        }
        
        if let location = postEvent.location {
            event.location = location
        }
        
        return event
    }
}

struct AddEventView: UIViewControllerRepresentable {
    @EnvironmentObject private var eventsService: EventsService
    @Environment(\.presentationMode) var presentationMode
    
    var event: EKEvent?
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> EKEventEditViewController {
        let viewController = EKEventEditViewController()
        viewController.editViewDelegate = context.coordinator
        viewController.event = event
        viewController.eventStore = eventsService.eventStore
        return viewController
    }

    func updateUIViewController(_ uiViewController: EKEventEditViewController, context: Context) {

    }
    
    class Coordinator: NSObject, EKEventEditViewDelegate {
        private let parentView: AddEventView
        
        init(_ parentView: AddEventView) {
            self.parentView = parentView
        }
        
        func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
            parentView.presentationMode.wrappedValue.dismiss()
        }
        
    }
}
