import SwiftUI

struct ProblemDetailView: View {
    let problemId: UUID
    @EnvironmentObject var dataManager: ClimbingDataManager
    @EnvironmentObject var themeManager: ThemeManager
    @Environment(\.dismiss) private var dismiss
    @State private var showingDeleteAlert = false
    @State private var showingImageViewer = false
    @State private var selectedImageIndex = 0
    @State private var showingEditProblem = false

    private var problem: Problem? {
        dataManager.problem(withId: problemId)
    }

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

    private var attempts: [Attempt] {
        dataManager.attempts(forProblem: problemId)
    }

    private var successfulAttempts: [Attempt] {
        attempts.filter { $0.result.isSuccessful }
    }

    private var attemptsWithSessions: [(Attempt, ClimbSession)] {
        attempts.compactMap { attempt in
            guard let session = dataManager.session(withId: attempt.sessionId) else { return nil }
            return (attempt, session)
        }.sorted { $0.1.date > $1.1.date }
    }

    var body: some View {
        ScrollView {
            LazyVStack(spacing: 20) {
                if let problem = problem, let gym = gym {
                    ProblemHeaderCard(problem: problem, gym: gym)

                    ProgressSummaryCard(
                        totalAttempts: attempts.count,
                        successfulAttempts: successfulAttempts.count,
                        firstSuccess: firstSuccessInfo
                    )

                    if !problem.imagePaths.isEmpty {
                        PhotosSection(imagePaths: problem.imagePaths)
                    }

                    AttemptHistorySection(attemptsWithSessions: attemptsWithSessions)
                } else {
                    Text("Problem not found")
                        .foregroundColor(.secondary)
                }
            }
            .padding()
        }
        .navigationTitle("Problem Details")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                if problem != nil {
                    Menu {
                        Button {
                            showingEditProblem = true
                        } label: {
                            Label("Edit Problem", systemImage: "pencil")
                        }

                        Button(role: .destructive) {
                            showingDeleteAlert = true
                        } label: {
                            Label("Delete Problem", systemImage: "trash")
                        }
                    } label: {
                        Image(systemName: "ellipsis.circle")
                    }
                }
            }
        }
        .confirmationDialog(
            "Delete Problem",
            isPresented: $showingDeleteAlert,
            titleVisibility: .visible
        ) {
            Button("Delete", role: .destructive) {
                if let problem = problem {
                    dataManager.deleteProblem(problem)
                    dismiss()
                }
            }
            Button("Cancel", role: .cancel) {}
        } message: {
            Text(
                "Are you sure you want to delete this problem? This will also delete all attempts associated with this problem."
            )
        }
        .sheet(isPresented: $showingEditProblem) {
            if let problem = problem {
                AddEditProblemView(problemId: problem.id)
            }
        }
        .sheet(isPresented: $showingImageViewer) {
            if let problem = problem, !problem.imagePaths.isEmpty {
                ImageViewerView(
                    imagePaths: problem.imagePaths,
                    initialIndex: selectedImageIndex
                )
            }
        }
    }

    private var firstSuccessInfo: (date: Date, result: AttemptResult)? {
        guard
            let firstSuccess = successfulAttempts.min(by: { attempt1, attempt2 in
                let session1 = dataManager.session(withId: attempt1.sessionId)
                let session2 = dataManager.session(withId: attempt2.sessionId)
                return session1?.date ?? Date() < session2?.date ?? Date()
            })
        else { return nil }

        let session = dataManager.session(withId: firstSuccess.sessionId)
        return (date: session?.date ?? Date(), result: firstSuccess.result)
    }
}

struct ProblemHeaderCard: View {
    let problem: Problem
    let gym: Gym
    @EnvironmentObject var themeManager: ThemeManager

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                VStack(alignment: .leading, spacing: 8) {
                    Text(problem.name ?? "Unnamed Problem")
                        .font(.title)
                        .fontWeight(.bold)

                    Text(gym.name)
                        .font(.title2)
                        .foregroundColor(.secondary)

                    if let location = problem.location {
                        Text(location)
                            .font(.subheadline)
                            .foregroundColor(.secondary)
                    }
                }

                Spacer()

                VStack(alignment: .trailing, spacing: 8) {
                    Text(problem.difficulty.grade)
                        .font(.title)
                        .fontWeight(.bold)
                        .foregroundColor(themeManager.accentColor)

                    Text(problem.climbType.displayName)
                        .font(.subheadline)
                        .foregroundColor(.secondary)

                    Text(problem.difficulty.system.displayName)
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }

            if let description = problem.description, !description.isEmpty {
                Text(description)
                    .font(.body)
            }

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

            if let notes = problem.notes, !notes.isEmpty {
                Text(notes)
                    .font(.caption)
                    .foregroundColor(.secondary)
                    .padding(.top, 4)
            }

            if !problem.isActive {
                HStack {
                    Image(systemName: "exclamationmark.triangle.fill")
                        .foregroundColor(.orange)
                    Text("Inactive Problem")
                        .font(.subheadline)
                        .fontWeight(.medium)
                        .foregroundColor(.orange)
                }
                .padding(.horizontal, 12)
                .padding(.vertical, 6)
                .background(
                    RoundedRectangle(cornerRadius: 8)
                        .fill(.orange.opacity(0.1))
                )
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(.regularMaterial)
        )
    }
}

struct ProgressSummaryCard: View {
    let totalAttempts: Int
    let successfulAttempts: Int
    let firstSuccess: (date: Date, result: AttemptResult)?
    @EnvironmentObject var themeManager: ThemeManager

    private static let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        return formatter
    }()

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Progress Summary")
                .font(.title2)
                .fontWeight(.bold)

            if totalAttempts == 0 {
                Text("No attempts recorded yet")
                    .foregroundColor(.secondary)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding()
            } else {
                HStack {
                    StatItem(label: "Total Attempts", value: "\(totalAttempts)")
                    StatItem(label: "Successful", value: "\(successfulAttempts)")
                }

                if let firstSuccess = firstSuccess {
                    VStack(alignment: .leading, spacing: 4) {
                        Text("First Success")
                            .font(.subheadline)
                            .fontWeight(.medium)

                        Text(
                            "\(Self.dateFormatter.string(from: firstSuccess.date)) (\(firstSuccess.result.displayName))"
                        )
                        .font(.subheadline)
                        .foregroundColor(themeManager.accentColor)
                    }
                    .padding(.top, 8)
                }
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(.regularMaterial)
        )
    }
}

struct PhotosSection: View {
    let imagePaths: [String]
    @State private var showingImageViewer = false
    @State private var selectedImageIndex = 0

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Photos")
                .font(.title2)
                .fontWeight(.bold)

            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 12) {
                    ForEach(imagePaths.indices, id: \.self) { index in
                        ProblemDetailImageView(imagePath: imagePaths[index])
                            .onTapGesture {
                                selectedImageIndex = index
                                showingImageViewer = true
                            }
                    }
                }
                .padding(.horizontal, 1)
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(.regularMaterial)
        )
        .sheet(isPresented: $showingImageViewer) {
            ImageViewerView(
                imagePaths: imagePaths,
                initialIndex: selectedImageIndex
            )
        }
    }
}

struct AttemptHistorySection: View {
    let attemptsWithSessions: [(Attempt, ClimbSession)]
    @EnvironmentObject var dataManager: ClimbingDataManager

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Attempt History (\(attemptsWithSessions.count))")
                .font(.title2)
                .fontWeight(.bold)

            if attemptsWithSessions.isEmpty {
                VStack(spacing: 12) {
                    Image(systemName: "hand.raised.slash")
                        .font(.title)
                        .foregroundColor(.secondary)

                    Text("No attempts yet")
                        .font(.headline)
                        .foregroundColor(.secondary)

                    Text("Start a session and track your attempts on this problem!")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .multilineTextAlignment(.center)
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(
                    RoundedRectangle(cornerRadius: 16)
                        .fill(.regularMaterial)
                )
            } else {
                LazyVStack(spacing: 12) {
                    ForEach(attemptsWithSessions.indices, id: \.self) { index in
                        let (attempt, session) = attemptsWithSessions[index]
                        AttemptHistoryCard(attempt: attempt, session: session)
                    }
                }
            }
        }
    }
}

struct AttemptHistoryCard: View {
    let attempt: Attempt
    let session: ClimbSession
    @EnvironmentObject var dataManager: ClimbingDataManager

    private static let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        return formatter
    }()

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

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack {
                VStack(alignment: .leading, spacing: 4) {
                    Text(Self.dateFormatter.string(from: session.date))
                        .font(.headline)
                        .fontWeight(.semibold)

                    if let gym = gym {
                        Text(gym.name)
                            .font(.subheadline)
                            .foregroundColor(.secondary)
                    }
                }

                Spacer()

                AttemptResultBadge(result: attempt.result)
            }

            if let notes = attempt.notes, !notes.isEmpty {
                Text(notes)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }

            if let highestHold = attempt.highestHold, !highestHold.isEmpty {
                Text("Highest hold: \(highestHold)")
                    .font(.caption)
                    .foregroundColor(.secondary)
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(Color(uiColor: .secondarySystemGroupedBackground))
                .shadow(color: .black.opacity(0.05), radius: 2, x: 0, y: 1)
        )
    }
}

struct ImageViewerView: View {
    let imagePaths: [String]
    let initialIndex: Int
    @Environment(\.dismiss) private var dismiss
    @State private var currentIndex: Int

    init(imagePaths: [String], initialIndex: Int) {
        self.imagePaths = imagePaths
        self.initialIndex = initialIndex
        self._currentIndex = State(initialValue: initialIndex)
    }

    var body: some View {
        NavigationStack {
            TabView(selection: $currentIndex) {
                ForEach(imagePaths.indices, id: \.self) { index in
                    ProblemDetailImageFullView(imagePath: imagePaths[index])
                        .tag(index)
                }
            }
            .tabViewStyle(.page(indexDisplayMode: .always))
            .navigationTitle("Photo \(currentIndex + 1) of \(imagePaths.count)")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Done") {
                        dismiss()
                    }
                }
            }
        }
    }
}

struct ProblemDetailImageView: View {
    let imagePath: String

    var body: some View {
        OrientationAwareImage.fill(imagePath: imagePath)
            .frame(width: 120, height: 120)
            .clipped()
            .cornerRadius(12)
    }
}

struct ProblemDetailImageFullView: View {
    let imagePath: String

    var body: some View {
        OrientationAwareImage.fit(imagePath: imagePath)
    }
}

#Preview {
    NavigationView {
        ProblemDetailView(problemId: UUID())
            .environmentObject(ClimbingDataManager.preview)
    }
}
