import SwiftUI

struct AddEditGymView: View {
    let gymId: UUID?
    @EnvironmentObject var dataManager: ClimbingDataManager
    @EnvironmentObject var themeManager: ThemeManager
    @Environment(\.dismiss) private var dismiss

    @State private var name = ""
    @State private var location = ""
    @State private var notes = ""
    @State private var selectedClimbTypes = Set<ClimbType>()
    @State private var selectedDifficultySystems = Set<DifficultySystem>()
    @State private var customDifficultyGrades: [String] = []
    @State private var isEditing = false

    private var existingGym: Gym? {
        guard let gymId = gymId else { return nil }
        return dataManager.gym(withId: gymId)
    }

    private var availableDifficultySystems: [DifficultySystem] {
        if selectedClimbTypes.isEmpty {
            return []
        } else {
            return selectedClimbTypes.flatMap { climbType in
                DifficultySystem.systemsForClimbType(climbType)
            }.removingDuplicates()
        }
    }

    init(gymId: UUID? = nil) {
        self.gymId = gymId
    }

    var body: some View {
        NavigationStack {
            Form {
                BasicInfoSection()
                ClimbTypesSection()
                DifficultySystemsSection()
                NotesSection()
            }
            .navigationTitle(isEditing ? "Edit Gym" : "Add Gym")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") {
                        dismiss()
                    }
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Save") {
                        saveGym()
                    }
                    .disabled(!canSave)
                }
            }
        }
        .onAppear {
            loadExistingGym()
        }
        .onChange(of: selectedClimbTypes) {
            updateAvailableDifficultySystems()
        }
    }

    @ViewBuilder
    private func BasicInfoSection() -> some View {
        Section("Basic Information") {
            TextField("Gym Name", text: $name)

            TextField("Location (Optional)", text: $location)
        }
    }

    @ViewBuilder
    private func ClimbTypesSection() -> some View {
        Section("Supported Climb Types") {
            ForEach(ClimbType.allCases, id: \.self) { climbType in
                HStack {
                    Text(climbType.displayName)
                    Spacer()
                    if selectedClimbTypes.contains(climbType) {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundColor(themeManager.accentColor)
                    } else {
                        Image(systemName: "circle")
                            .foregroundColor(.gray)
                    }
                }
                .contentShape(Rectangle())
                .onTapGesture {
                    if selectedClimbTypes.contains(climbType) {
                        selectedClimbTypes.remove(climbType)
                    } else {
                        selectedClimbTypes.insert(climbType)
                    }
                }
            }
        }
    }

    @ViewBuilder
    private func DifficultySystemsSection() -> some View {
        Section("Difficulty Systems") {
            if selectedClimbTypes.isEmpty {
                Text("Select climb types first to see available difficulty systems")
                    .foregroundColor(.secondary)
                    .font(.caption)
            } else {
                ForEach(availableDifficultySystems, id: \.self) { system in
                    HStack {
                        Text(system.displayName)
                        Spacer()
                        if selectedDifficultySystems.contains(system) {
                            Image(systemName: "checkmark.circle.fill")
                                .foregroundColor(themeManager.accentColor)
                        } else {
                            Image(systemName: "circle")
                                .foregroundColor(.gray)
                        }
                    }
                    .contentShape(Rectangle())
                    .onTapGesture {
                        if selectedDifficultySystems.contains(system) {
                            selectedDifficultySystems.remove(system)
                        } else {
                            selectedDifficultySystems.insert(system)
                        }
                    }
                }
            }
        }
    }

    @ViewBuilder
    private func NotesSection() -> some View {
        Section("Notes (Optional)") {
            TextEditor(text: $notes)
                .frame(minHeight: 100)
        }
    }

    private var canSave: Bool {
        !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !selectedClimbTypes.isEmpty
            && !selectedDifficultySystems.isEmpty
    }

    private func loadExistingGym() {
        if let gym = existingGym {
            isEditing = true
            name = gym.name
            location = gym.location ?? ""
            notes = gym.notes ?? ""
            selectedClimbTypes = Set(gym.supportedClimbTypes)
            selectedDifficultySystems = Set(gym.difficultySystems)
            customDifficultyGrades = gym.customDifficultyGrades
        }
    }

    private func updateAvailableDifficultySystems() {
        // Remove selected systems that are no longer available
        let availableSet = Set(availableDifficultySystems)
        selectedDifficultySystems = selectedDifficultySystems.intersection(availableSet)
    }

    private func saveGym() {
        let trimmedName = name.trimmingCharacters(in: .whitespacesAndNewlines)
        let trimmedLocation = location.trimmingCharacters(in: .whitespacesAndNewlines)
        let trimmedNotes = notes.trimmingCharacters(in: .whitespacesAndNewlines)

        if isEditing, let gym = existingGym {
            let updatedGym = gym.updated(
                name: trimmedName,
                location: trimmedLocation.isEmpty ? nil : trimmedLocation,
                supportedClimbTypes: Array(selectedClimbTypes),
                difficultySystems: Array(selectedDifficultySystems),
                customDifficultyGrades: customDifficultyGrades,
                notes: trimmedNotes.isEmpty ? nil : trimmedNotes
            )
            dataManager.updateGym(updatedGym)
        } else {
            let newGym = Gym(
                name: trimmedName,
                location: trimmedLocation.isEmpty ? nil : trimmedLocation,
                supportedClimbTypes: Array(selectedClimbTypes),
                difficultySystems: Array(selectedDifficultySystems),
                customDifficultyGrades: customDifficultyGrades,
                notes: trimmedNotes.isEmpty ? nil : trimmedNotes
            )
            dataManager.addGym(newGym)
        }

        dismiss()
    }
}

extension Array where Element: Hashable {
    func removingDuplicates() -> [Element] {
        var seen = Set<Element>()
        return filter { seen.insert($0).inserted }
    }
}

#Preview {
    AddEditGymView()
        .environmentObject(ClimbingDataManager.preview)
}
