//
//  CourtAvailabilitySettingsView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 19/04/2024.
//

import SwiftUI
import LeStorage

struct CourtAvailabilitySettingsView: View {
    @Environment(Tournament.self) var tournament: Tournament
    @EnvironmentObject var dataStore: DataStore
    
    let event: Event
    
    @State private var showingPopover: Bool = false
    @State private var courtIndex: Int = 0
    @State private var startDate: Date = Date()
    @State private var endDate: Date = Date()
    @State private var editingSlot: DateInterval?
    
    var courtsUnavailability: [Int: [DateInterval]] {
        let groupedBy = Dictionary(grouping: event.courtsUnavailability, by: { dateInterval in
            return dateInterval.courtIndex
        })
        return groupedBy
    }
    
    var body: some View {
        List {
            let keys = courtsUnavailability.keys.sorted()
            ForEach(keys, id: \.self) { key in
                if let dates = courtsUnavailability[key] {
                    Section {
                        ForEach(dates) { dateInterval in
                            Menu {
                                Button("dupliquer") {
                                    let duplicatedDateInterval = DateInterval(event: event.id, courtIndex: (courtIndex+1)%tournament.courtCount, startDate: dateInterval.startDate, endDate: dateInterval.endDate)
                                    do {
                                        try dataStore.dateIntervals.addOrUpdate(instance: duplicatedDateInterval)
                                    } catch {
                                        Logger.error(error)
                                    }
                                }
                                Button("éditer") {
                                    editingSlot = dateInterval
                                    courtIndex = dateInterval.courtIndex
                                    startDate = dateInterval.startDate
                                    endDate = dateInterval.endDate
                                    showingPopover = true
                                }
                                Button("effacer", role: .destructive) {
                                    do {
                                        try dataStore.dateIntervals.delete(instance: dateInterval)
                                    } catch {
                                        Logger.error(error)
                                    }
                                }
                            } label: {
                                HStack {
                                    VStack(alignment: .leading, spacing: 0) {
                                        Text(dateInterval.startDate.localizedTime()).font(.largeTitle)
                                        Text(dateInterval.startDate.localizedDay()).font(.caption)
                                    }
                                    Spacer()
                                    VStack {
                                        Image(systemName: "arrowshape.forward.fill")
                                            .tint(.master)
                                        Text("indisponible").foregroundStyle(.red).font(.caption)
                                    }
                                    Spacer()
                                    VStack(alignment: .trailing, spacing: 0) {
                                        Text(dateInterval.endDate.localizedTime()).font(.largeTitle)
                                        Text(dateInterval.endDate.localizedDay()).font(.caption)
                                    }
                                }
                            }
                            .swipeActions {
                                Button(role: .destructive) {
                                    do {
                                        try dataStore.dateIntervals.delete(instance: dateInterval)
                                    } catch {
                                        Logger.error(error)
                                    }
                                } label: {
                                    LabelDelete()
                                }
                            }
                        }
                    } header: {
                        HStack {
                            Text(Court.courtIndexedTitle(atIndex: key))
                            Spacer()
                            if let courtName = tournament.courtNameIfAvailable(atIndex: key) {
                                Text(courtName)
                            }
                        }
                    }
                    .headerProminence(.increased)
                }
            }
        }
        .overlay {
            if courtsUnavailability.isEmpty {
                ContentUnavailableView {
                    Label("Tous les terrains sont disponibles", systemImage: "checkmark.circle.fill").tint(.green)
                } description: {
                    Text("Vous pouvez précisez l'indisponibilité d'une ou plusieurs terrains, que ce soit pour une journée entière ou un créneau précis.")
                } actions: {
                    RowButtonView("Ajouter une indisponibilité", systemImage: "plus.circle.fill") {
                        startDate = tournament.startDate
                        endDate = tournament.startDate.addingTimeInterval(5400)
                        showingPopover = true
                    }
                }
            }
        }
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                BarButtonView("Ajouter une indisponibilité", icon: "plus.circle.fill") {
                    startDate = tournament.startDate
                    endDate = tournament.startDate.addingTimeInterval(5400)
                    showingPopover = true
                }
            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationTitle("Créneau indisponible")
        .popover(isPresented: $showingPopover) {
            NavigationStack {
                Form {
                    Section {
                        CourtPicker(title: "Terrain", selection: $courtIndex, maxCourt: tournament.courtCount)
                    }
                    
                    Section {
                        DatePicker("Début", selection: $startDate)
                        DatePicker("Fin", selection: $endDate)
                    } footer: {
                        FooterButtonView("jour entier") {
                            startDate = startDate.startOfDay
                            endDate = startDate.endOfDay()
                        }
                    }
                }
                .toolbar {
                    ButtonValidateView {
                        if editingSlot == nil {
                            let dateInterval = DateInterval(event: event.id, courtIndex: courtIndex, startDate: startDate, endDate: endDate)
                            do {
                                try dataStore.dateIntervals.addOrUpdate(instance: dateInterval)
                            } catch {
                                Logger.error(error)
                            }
                        } else {
                            editingSlot?.courtIndex = courtIndex
                            editingSlot?.endDate = endDate
                            editingSlot?.startDate = startDate
                            do {
                                try dataStore.dateIntervals.addOrUpdate(instance: editingSlot!)
                            } catch {
                                Logger.error(error)
                            }
                        }
                        showingPopover = false
                    }
                }
                .navigationBarTitleDisplayMode(.inline)
                .toolbarBackground(.visible, for: .navigationBar)
                .navigationTitle("Nouveau créneau")
                .tint(.master)
            }
            .onAppear {
                UIDatePicker.appearance().minuteInterval = 5
            }
            .onDisappear {
                UIDatePicker.appearance().minuteInterval = 1
            }
        }
    }
}

struct CourtPicker: View {
    @Environment(Tournament.self) var tournament: Tournament

    let title: String
    @Binding var selection: Int
    let maxCourt: Int

    var body: some View {
        Picker(title, selection: $selection) {
            ForEach(0..<maxCourt, id: \.self) {
                Text(tournament.courtName(atIndex: $0))
            }
        }
    }
}

//#Preview {
//    CourtAvailabilitySettingsView(event: Event.mock())
//}
