import SwiftUI

struct ProblemsView: View {
    @EnvironmentObject var dataManager: ClimbingDataManager
    @EnvironmentObject var themeManager: ThemeManager
    @State private var showingAddProblem = false
    @State private var selectedClimbType: ClimbType?
    @State private var selectedGym: Gym?
    @State private var searchText = ""
    @State private var showingSearch = false
    @State private var showingFilters = false
    @FocusState private var isSearchFocused: Bool

    @State private var cachedFilteredProblems: [Problem] = []

    // State moved from ProblemsList
    @State private var problemToDelete: Problem?
    @State private var problemToEdit: Problem?
    @State private var animationKey = 0

    private func updateFilteredProblems() {
        Task {
            cachedFilteredProblems = await computeFilteredProblems()
        }
    }

    private func computeFilteredProblems() async -> [Problem] {
        // Capture dependencies for safe background processing
        let problems = dataManager.problems
        let searchText = self.searchText
        let selectedClimbType = self.selectedClimbType
        let selectedGym = self.selectedGym

        var filtered = problems

        // Apply search filter
        if !searchText.isEmpty {
            filtered = filtered.filter { problem in
                return problem.name?.localizedCaseInsensitiveContains(searchText) ?? false
                    || (problem.description?.localizedCaseInsensitiveContains(searchText) ?? false)
                    || (problem.location?.localizedCaseInsensitiveContains(searchText) ?? false)
                    || problem.tags.contains { $0.localizedCaseInsensitiveContains(searchText) }
            }
        }

        // Apply climb type filter
        if let climbType = selectedClimbType {
            filtered = filtered.filter { $0.climbType == climbType }
        }

        // Apply gym filter
        if let gym = selectedGym {
            filtered = filtered.filter { $0.gymId == gym.id }
        }

        // Separate active and inactive problems with stable sorting
        let active = filtered.filter { $0.isActive }.sorted {
            if $0.updatedAt == $1.updatedAt {
                return $0.id.uuidString < $1.id.uuidString  // Stable fallback
            }
            return $0.updatedAt > $1.updatedAt
        }
        let inactive = filtered.filter { !$0.isActive }.sorted {
            if $0.updatedAt == $1.updatedAt {
                return $0.id.uuidString < $1.id.uuidString  // Stable fallback
            }
            return $0.updatedAt > $1.updatedAt
        }

        return active + inactive
    }

    var body: some View {
        NavigationStack {
            Group {
                if cachedFilteredProblems.isEmpty {
                    VStack(spacing: 0) {
                        headerContent

                        EmptyProblemsView(
                            isEmpty: dataManager.problems.isEmpty,
                            isFiltered: !dataManager.problems.isEmpty
                        )
                    }
                } else {
                    List {
                        if showingSearch {
                            Section {
                                headerContent
                            }
                            .listRowInsets(EdgeInsets())
                            .listRowSeparator(.hidden)
                            .listRowBackground(Color.clear)
                        }

                        ForEach(cachedFilteredProblems) { problem in
                            NavigationLink(destination: ProblemDetailView(problemId: problem.id)) {
                                ProblemRow(problem: problem)
                            }
                            .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                                Button(role: .destructive) {
                                    problemToDelete = problem
                                } label: {
                                    Label("Delete", systemImage: "trash")
                                }
                                .tint(.red)

                                Button {
                                    withAnimation(.spring(response: 0.5, dampingFraction: 0.8, blendDuration: 0.1))
                                    {
                                        let updatedProblem = problem.updated(isActive: !problem.isActive)
                                        dataManager.updateProblem(updatedProblem)
                                    }
                                } label: {
                                    Label(
                                        problem.isActive ? "Mark as Reset" : "Mark as Active",
                                        systemImage: problem.isActive ? "xmark.circle" : "checkmark.circle")
                                }
                                .tint(.orange)

                                Button {
                                    problemToEdit = problem
                                } label: {
                                    HStack {
                                        Image(systemName: "pencil")
                                        Text("Edit")
                                    }
                                }
                                .tint(.indigo)
                            }
                        }
                    }
                    .listStyle(.plain)
                    .animation(
                        .spring(response: 0.5, dampingFraction: 0.8, blendDuration: 0.1),
                        value: animationKey
                    )
                }
            }
            .navigationTitle("Problems")
            .navigationBarTitleDisplayMode(.automatic)
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarTrailing) {
                    if dataManager.isSyncing {
                        HStack(spacing: 2) {
                            ProgressView()
                                .progressViewStyle(CircularProgressViewStyle(tint: themeManager.accentColor))
                                .scaleEffect(0.6)
                        }
                        .padding(.horizontal, 6)
                        .padding(.vertical, 3)
                        .background(
                            Circle()
                                .fill(.regularMaterial)
                        )
                        .transition(.scale.combined(with: .opacity))
                        .animation(
                            .easeInOut(duration: 0.2), value: dataManager.isSyncing
                        )
                    }

                    Button(action: {
                        withAnimation(.easeInOut(duration: 0.3)) {
                            showingSearch.toggle()
                            if showingSearch {
                                isSearchFocused = true
                            } else {
                                searchText = ""
                                isSearchFocused = false
                            }
                        }
                    }) {
                        Image(systemName: showingSearch ? "xmark.circle.fill" : "magnifyingglass")
                            .font(.system(size: 16, weight: .medium))
                            .foregroundColor(showingSearch ? .secondary : themeManager.accentColor)
                    }

                    Button(action: {
                        showingFilters = true
                    }) {
                        let hasFilters = selectedClimbType != nil || selectedGym != nil
                        Image(systemName: hasFilters ? "line.3.horizontal.decrease.circle.fill" : "line.3.horizontal.decrease.circle")
                            .font(.system(size: 16, weight: .medium))
                            .foregroundColor(themeManager.accentColor)
                    }

                    if !dataManager.gyms.isEmpty {
                        Button("Add") {
                            showingAddProblem = true
                        }
                    }
                }
            }
            .sheet(isPresented: $showingAddProblem) {
                AddEditProblemView()
            }
            .sheet(isPresented: $showingFilters) {
                FilterSheet(
                    selectedClimbType: $selectedClimbType,
                    selectedGym: $selectedGym,
                    filteredProblems: cachedFilteredProblems
                )
                .presentationDetents([.height(320)])
            }
            .sheet(item: $problemToEdit) { problem in
                AddEditProblemView(problemId: problem.id)
            }
            .confirmationDialog(
                "Delete Problem",
                isPresented: .init(
                    get: { problemToDelete != nil },
                    set: { if !$0 { problemToDelete = nil } }
                ),
                titleVisibility: .visible
            ) {
                Button("Delete", role: .destructive) {
                    if let problem = problemToDelete {
                        dataManager.deleteProblem(problem)
                        problemToDelete = nil
                    }
                }
                Button("Cancel", role: .cancel) {
                    problemToDelete = nil
                }
            } message: {
                Text(
                    "Are you sure you want to delete this problem? This will also delete all associated attempts."
                )
            }
        }
        .onAppear {
            updateFilteredProblems()
        }
        .onChange(of: dataManager.problems) {
            updateFilteredProblems()
        }
        .onChange(of: searchText) {
            updateFilteredProblems()
        }
        .onChange(of: selectedClimbType) {
            updateFilteredProblems()
        }
        .onChange(of: selectedGym) {
            updateFilteredProblems()
        }
        .onChange(of: cachedFilteredProblems) {
            animationKey += 1
        }
    }

    @ViewBuilder
    private var headerContent: some View {
        VStack(spacing: 0) {
            if showingSearch {
                HStack(spacing: 8) {
                    Image(systemName: "magnifyingglass")
                        .foregroundColor(.secondary)
                        .font(.system(size: 16, weight: .medium))

                    TextField("Search problems...", text: $searchText)
                        .textFieldStyle(.plain)
                        .font(.system(size: 16))
                        .focused($isSearchFocused)
                        .submitLabel(.search)
                }
                .padding(.horizontal, 12)
                .padding(.vertical, 10)
                .background {
                    if #available(iOS 18.0, *) {
                        RoundedRectangle(cornerRadius: 12)
                            .fill(.regularMaterial)
                            .overlay {
                                RoundedRectangle(cornerRadius: 12)
                                    .stroke(.quaternary, lineWidth: 0.5)
                            }
                    } else {
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color(.systemGray6))
                            .overlay {
                                RoundedRectangle(cornerRadius: 10)
                                    .stroke(Color(.systemGray4), lineWidth: 0.5)
                            }
                    }
                }
                .padding(.horizontal)
                .padding(.top, 8)
                .padding(.bottom, 8)
                .animation(.easeInOut(duration: 0.3), value: showingSearch)
            }
        }
    }
}

struct FilterSection: View {
    @EnvironmentObject var dataManager: ClimbingDataManager
    @EnvironmentObject var themeManager: ThemeManager
    @Binding var selectedClimbType: ClimbType?
    @Binding var selectedGym: Gym?
    let filteredProblems: [Problem]

    var body: some View {
        VStack(spacing: 12) {
            // Climb Type Filter
            VStack(alignment: .leading, spacing: 8) {
                Text("Climb Type")
                    .font(.subheadline)
                    .fontWeight(.medium)

                ScrollView(.horizontal, showsIndicators: false) {
                    HStack(spacing: 8) {
                        FilterChip(
                            title: "All Types",
                            isSelected: selectedClimbType == nil
                        ) {
                            selectedClimbType = nil
                        }

                        ForEach(ClimbType.allCases, id: \.self) { climbType in
                            FilterChip(
                                title: climbType.displayName,
                                isSelected: selectedClimbType == climbType
                            ) {
                                selectedClimbType = climbType
                            }
                        }
                    }
                    .padding(.horizontal, 1)
                }
            }

            // Gym Filter
            VStack(alignment: .leading, spacing: 8) {
                Text("Gym")
                    .font(.subheadline)
                    .fontWeight(.medium)

                ScrollView(.horizontal, showsIndicators: false) {
                    HStack(spacing: 8) {
                        FilterChip(
                            title: "All Gyms",
                            isSelected: selectedGym == nil
                        ) {
                            selectedGym = nil
                        }

                        ForEach(dataManager.gyms, id: \.id) { gym in
                            FilterChip(
                                title: gym.name,
                                isSelected: selectedGym?.id == gym.id
                            ) {
                                selectedGym = gym
                            }
                        }
                    }
                    .padding(.horizontal, 1)
                }
            }

            // Results count
            if selectedClimbType != nil || selectedGym != nil {
                HStack {
                    Text(
                        "Showing \(filteredProblems.count) of \(dataManager.problems.count) problems"
                    )
                    .font(.caption)
                    .foregroundColor(.secondary)
                    Spacer()
                }
            }
        }
    }
}

struct FilterChip: View {
    let title: String
    let isSelected: Bool
    let action: () -> Void
    @EnvironmentObject var themeManager: ThemeManager

    var body: some View {
        Button(action: action) {
            Text(title)
                .font(.caption)
                .fontWeight(.medium)
                .padding(.horizontal, 12)
                .padding(.vertical, 6)
                .background(
                    RoundedRectangle(cornerRadius: 16)
                        .fill(isSelected ? themeManager.accentColor : .clear)
                        .stroke(themeManager.accentColor, lineWidth: 1)
                )
                .foregroundColor(isSelected ? themeManager.contrastingTextColor : themeManager.accentColor)
        }
        .buttonStyle(.plain)
    }
}

struct ProblemRow: View {
    let problem: Problem
    @EnvironmentObject var dataManager: ClimbingDataManager
    @EnvironmentObject var themeManager: ThemeManager

    private var gym: Gym? {
        dataManager.gym(withId: problem.gymId)
    }

    private var isCompleted: Bool {
        dataManager.attempts.contains { attempt in
            attempt.problemId == problem.id && attempt.result.isSuccessful
        }
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                VStack(alignment: .leading, spacing: 4) {
                    Text(problem.name ?? "Unnamed Problem")
                        .font(.headline)
                        .fontWeight(.semibold)
                        .foregroundColor(problem.isActive ? .primary : .secondary)

                    Text(gym?.name ?? "Unknown Gym")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }

                Spacer()

                VStack(alignment: .trailing, spacing: 4) {
                    HStack(spacing: 8) {
                        if !problem.imagePaths.isEmpty {
                            Image(systemName: "photo")
                                .font(.system(size: 14, weight: .medium))
                                .foregroundColor(themeManager.accentColor)
                        }

                        if isCompleted {
                            Image(systemName: "checkmark.circle.fill")
                                .font(.system(size: 14, weight: .medium))
                                .foregroundColor(.green)
                        }

                        Text(problem.difficulty.grade)
                            .font(.title2)
                            .fontWeight(.bold)
                            .foregroundColor(themeManager.accentColor)
                    }

                    Text(problem.climbType.displayName)
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }

            if let location = problem.location {
                Text("Location: \(location)")
                    .font(.caption)
                    .foregroundColor(.secondary)
            }

            if !problem.tags.isEmpty {
                ScrollView(.horizontal, showsIndicators: false) {
                    HStack(spacing: 6) {
                        ForEach(problem.tags.prefix(3), id: \.self) { tag in
                            Text(tag)
                                .font(.caption2)
                                .padding(.horizontal, 6)
                                .padding(.vertical, 2)
                                .background(
                                    RoundedRectangle(cornerRadius: 4)
                                        .fill(themeManager.accentColor.opacity(0.1))
                                )
                                .foregroundColor(themeManager.accentColor)
                        }
                    }
                }
            }

            if !problem.isActive {
                Text("Reset / No Longer Set")
                    .font(.caption)
                    .foregroundColor(.orange)
                    .fontWeight(.medium)
            }
        }
        .padding(.vertical, 8)
    }
}

struct EmptyProblemsView: View {
    let isEmpty: Bool
    let isFiltered: Bool
    @EnvironmentObject var dataManager: ClimbingDataManager
    @State private var showingAddProblem = false

    var body: some View {
        VStack(spacing: 20) {
            Spacer()

            Image(systemName: "star.fill")
                .font(.system(size: 60))
                .foregroundColor(.secondary)

            VStack(spacing: 8) {
                Text(title)
                    .font(.title2)
                    .fontWeight(.bold)

                Text(subtitle)
                    .font(.body)
                    .foregroundColor(.secondary)
                    .multilineTextAlignment(.center)
                    .padding(.horizontal)
            }

            if isEmpty && !dataManager.gyms.isEmpty {
                Button("Add Problem") {
                    showingAddProblem = true
                }
                .buttonStyle(.borderedProminent)
                .controlSize(.large)
            }

            Spacer()
        }
        .sheet(isPresented: $showingAddProblem) {
            AddEditProblemView()
        }
    }

    private var title: String {
        if isEmpty {
            return dataManager.gyms.isEmpty ? "No Gyms Available" : "No Problems Yet"
        } else {
            return "No Problems Match Filters"
        }
    }

    private var subtitle: String {
        if isEmpty {
            return dataManager.gyms.isEmpty
                ? "Add a gym first to start tracking problems and routes!"
                : "Start tracking your favorite problems and routes!"
        } else {
            return "Try adjusting your filters to see more problems."
        }
    }
}

struct FilterSheet: View {
    @Binding var selectedClimbType: ClimbType?
    @Binding var selectedGym: Gym?
    let filteredProblems: [Problem]
    @Environment(\.dismiss) var dismiss
    @EnvironmentObject var themeManager: ThemeManager

    var body: some View {
        NavigationStack {
            ScrollView {
                FilterSection(
                    selectedClimbType: $selectedClimbType,
                    selectedGym: $selectedGym,
                    filteredProblems: filteredProblems
                )
                .padding()
            }
            .navigationTitle("Filters")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        dismiss()
                    }) {
                        Text("Done")
                            .font(.subheadline)
                            .fontWeight(.semibold)
                            .padding(.horizontal, 16)
                            .padding(.vertical, 6)
                            .background(.ultraThinMaterial)
                            .clipShape(Capsule())
                            .overlay(
                                Capsule()
                                    .stroke(Color.secondary.opacity(0.2), lineWidth: 0.5)
                            )
                            .foregroundColor(themeManager.accentColor)
                    }
                }

                ToolbarItem(placement: .navigationBarLeading) {
                    if selectedClimbType != nil || selectedGym != nil {
                        Button(action: {
                            selectedClimbType = nil
                            selectedGym = nil
                        }) {
                            Text("Reset")
                                .font(.subheadline)
                                .fontWeight(.medium)
                                .padding(.horizontal, 16)
                                .padding(.vertical, 6)
                                .background(.ultraThinMaterial)
                                .clipShape(Capsule())
                                .overlay(
                                    Capsule()
                                        .stroke(Color.secondary.opacity(0.2), lineWidth: 0.5)
                                )
                                .foregroundColor(.red)
                        }
                    }
                }
            }
        }
    }
}

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