//
//  ClubDetailView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 20/03/2024.
//

import SwiftUI
import LeStorage

struct ClubDetailView: View {
    @EnvironmentObject var dataStore: DataStore
    @Environment(\.dismiss) var dismiss
    @FocusState var focusedField: Club.CodingKeys?
    @State private var acronymMode: Club.AcronymMode = .automatic
    @State private var city: String
    @State private var zipCode: String
    @State private var selectedCourt: Court?
    @Bindable var club: Club
    @State private var clubDeleted: Bool = false
    var displayContext: DisplayContext
    var selection: ((Club) -> ())? = nil

    init(club: Club, displayContext: DisplayContext, selection: ((Club) -> ())? = nil) {
        _club = Bindable(club)
        self.displayContext = displayContext
        self.selection = selection
        _acronymMode = State(wrappedValue: club.shortNameMode())
        _city = State(wrappedValue: club.city ?? "")
        _zipCode = State(wrappedValue: club.zipCode ?? "")
    }

    var body: some View {
        Form {
            if displayContext == .edition || displayContext == .lockedForEditing {
                let isFavorite = club.isFavorite()
                Section {
                    RowButtonView(isFavorite ? "Retirer des favoris" : "Mettre en favori", role: isFavorite ? .destructive : nil) {
                        if isFavorite {
                            dataStore.user.clubs.removeAll(where: { $0 == club.id })
                        } else {
                            dataStore.user.clubs.append(club.id)
                        }
                        self.dataStore.saveUser()
                    }
                } footer: {
                    if displayContext == .lockedForEditing {
                        Text("Édition impossible, vous n'êtes pas le créateur de ce club.").foregroundStyle(.logoRed)
                    }
                }
            }

            Section {
                TextField("Nom du club", text: $club.name)
                    .autocorrectionDisabled()
                    .keyboardType(.alphabet)
                    .frame(maxWidth: .infinity)
                    .focused($focusedField, equals: ._name)
                    .submitLabel( displayContext == .addition ? .next : .done)
                    .onSubmit(of: .text) {
                        if club.acronym.isEmpty {
                            club.acronym = club.name.canonicalVersion.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines).acronym()
                        }
                        
                        if displayContext == .edition && city.isEmpty == true {
                            focusedField = ._city
                        } else {
                            focusedField = nil
                        }

                    }
                LabeledContent {
                    if acronymMode == .automatic || displayContext == .lockedForEditing {
                        Text(club.acronym)
                    } else {
                        TextField("Nom court", text: $club.acronym)
                            .textInputAutocapitalization(.never)
                            .fixedSize()
                            .focused($focusedField, equals: ._acronym)
                            .submitLabel(.done)
                            .multilineTextAlignment(.trailing)
                            .onSubmit(of: .text) {
                                if club.acronym.count > 10 {
                                    club.acronym = String(club.acronym.prefix(10))
                                }
                            }
                    }
                } label: {
                    VStack(alignment: .leading, spacing: 0) {
                        Text("Nom court (10 caractères max.)").foregroundStyle(.secondary).font(.caption)
                        Menu {
                            Section {
                                ForEach(Club.AcronymMode.allCases, id: \.self) { option in
                                    Toggle(isOn: .init(get: {
                                        acronymMode == option
                                    }, set: { value in
                                        acronymMode = option
                                    })) {
                                        Text(option.rawValue)
                                    }
                                }
                            } header: {
                                Text("Nom court")
                            }
                        } label: {
                            Text(acronymMode.rawValue)
                        }
                        .disabled(displayContext == .lockedForEditing)
                    }
                }
                .onChange(of: acronymMode) {
                    focusedField = ._acronym
                    if acronymMode == .custom {
                        club.acronym = ""
                    }
                }
            } footer: {
                if displayContext != .lockedForEditing {
                    Text("Vous pouvez personaliser le nom court ou laisser celui généré par défaut.")
                }
            }
            
            if club.code == nil {
                Section {
                    LabeledContent {
                        TextField("Ville", text: $city)
                            .autocorrectionDisabled()
                            .keyboardType(.alphabet)
                            .multilineTextAlignment(.trailing)
                            .frame(maxWidth: .infinity)
                            .focused($focusedField, equals: ._city)
                            .submitLabel( displayContext == .addition ? .next : .done)
                            .onSubmit {
                                if displayContext == .addition {
                                    focusedField = ._zipCode
                                }
                                club.city = city
                            }
                    } label: {
                        Text("Ville")
                    }
                    .onTapGesture {
                        focusedField = ._city
                    }

                    LabeledContent {
                        TextField("Code Postal", text: $zipCode)
                            .autocorrectionDisabled()
                            .keyboardType(.alphabet)
                            .multilineTextAlignment(.trailing)
                            .frame(maxWidth: .infinity)
                            .focused($focusedField, equals: ._zipCode)
                            .submitLabel( displayContext == .addition ? .next : .done)
                            .onSubmit {
                                club.zipCode = zipCode
                            }
                    } label: {
                        Text("Code Postal")
                    }
                    .onTapGesture {
                        focusedField = ._zipCode
                    }
                }
                .disabled(displayContext == .lockedForEditing)
            }
            
            let federalLink = club.federalLink()
            let padelClubLink = club.shareURL()
            if federalLink != nil || padelClubLink != nil {
                Section {
                    if let federalLink {
                        LabeledContent("Code Club") {
                            Text(club.code ?? "")
                        }
                        LabeledContent("Ville") {
                            Text(club.city ?? "")
                        }
                        Link(destination: federalLink) {
                            Text("Accéder au club sur Tenup")
                        }
                    }
                    if let padelClubLink {
                        Link(destination: padelClubLink) {
                            Text("Accéder au club sur Padel Club")
                        }
                    }
                }
            }
            
            if displayContext == .addition {
                Section {
                } header: {
                    HStack {
                        VStack {
                            Divider()
                        }
                        Text("ou")
                        VStack {
                            Divider()
                        }
                    }
                }
                
                Section {
                    NavigationLink {
                        ClubSearchView(displayContext: .edition, club: club)
                    } label: {
                        Label("Chercher dans la base fédérale", systemImage: "magnifyingglass")
                    }
                } footer: {
                    Text("Vous pouvez chercher un club dans la base fédérale et importer les informations directement.")
                }
            }
            
            ClubCourtSetupView(club: club, displayContext: displayContext, selectedCourt: $selectedCourt, hideLockForEditingMessage: true)
            
            if displayContext == .edition {
                Section {
                    RowButtonView("Supprimer ce club", role: .destructive) {
                        do {
                            clubDeleted = true
                            dataStore.user.clubs.removeAll(where: { $0 == club.id })
                            self.dataStore.saveUser()
                            try dataStore.clubs.deleteById(club.id)
                            dismiss()
                        } catch {
                            Logger.error(error)
                        }
                    }
                }
            }
        }
        .keyboardType(.alphabet)
        .autocorrectionDisabled()
        .defaultFocus($focusedField, ._name, priority: .automatic)
        .navigationTitle(displayContext == .addition ? "Nouveau club" : "Détail du club")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar(.visible, for: .navigationBar)
        .headerProminence(.increased)
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationDestination(item: $selectedCourt) { court in
            CourtView(court: court)
        }
        .onDisappear {
            if displayContext == .edition && clubDeleted == false {
                do {
                    try dataStore.clubs.addOrUpdate(instance: club)
                } catch {
                    Logger.error(error)
                }
            }
        }
        .onAppear {
            if displayContext == .addition {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    focusedField = ._name
                }
            }
        }
    }
}

//#Preview {
//    ClubDetailView(club: Club.mock(), displayContext: .edition)
//}
