import Combine
import MusicKit
import SwiftUI

struct SessionDetailView: View {
    let sessionId: UUID
    @EnvironmentObject var dataManager: ClimbingDataManager
    @EnvironmentObject var themeManager: ThemeManager
    @EnvironmentObject var musicService: MusicService
    @Environment(\.dismiss) private var dismiss
    @State private var showingDeleteAlert = false
    @State private var showingAddAttempt = false
    @State private var editingAttempt: Attempt?
    @State private var attemptToDelete: Attempt?

    private var session: ClimbSession? {
        dataManager.session(withId: sessionId)
    }

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

    private var attempts: [Attempt] {
        dataManager.attempts(forSession: sessionId)
    }

    private var attemptsWithProblems: [(Attempt, Problem)] {
        attempts.compactMap { attempt in
            guard let problem = dataManager.problem(withId: attempt.problemId) else { return nil }
            return (attempt, problem)
        }.sorted { $0.0.timestamp < $1.0.timestamp }
    }

    private var sessionStats: SessionStats {
        calculateSessionStats()
    }

    var body: some View {
        List {
            if let session = session, let gym = gym {
                Section {
                    SessionHeaderCard(
                        session: session, gym: gym, stats: sessionStats)
                    .listRowInsets(EdgeInsets(top: 6, leading: 16, bottom: 6, trailing: 16))
                    .listRowBackground(Color.clear)
                    .listRowSeparator(.hidden)

                    if session.status == .active && musicService.isMusicEnabled && musicService.isAuthorized {
                        MusicControlCard()
                            .listRowInsets(EdgeInsets(top: 6, leading: 16, bottom: 6, trailing: 16))
                            .listRowBackground(Color.clear)
                            .listRowSeparator(.hidden)
                    }

                    SessionStatsCard(stats: sessionStats)
                    .listRowInsets(EdgeInsets(top: 6, leading: 16, bottom: 6, trailing: 16))
                    .listRowBackground(Color.clear)
                    .listRowSeparator(.hidden)
                }

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

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

                            Text("Start attempting problems to see your progress!")
                                .font(.subheadline)
                                .foregroundColor(.secondary)
                                .multilineTextAlignment(.center)
                        }
                        .frame(maxWidth: .infinity)
                        .padding()
                        .background(
                            RoundedRectangle(cornerRadius: 16)
                                .fill(.regularMaterial)
                        )
                        .listRowBackground(Color.clear)
                        .listRowSeparator(.hidden)
                        .listRowInsets(EdgeInsets(top: 6, leading: 16, bottom: 6, trailing: 16))
                    } else {
                        ForEach(attemptsWithProblems.indices, id: \.self) { index in
                            let (attempt, problem) = attemptsWithProblems[index]
                            AttemptCard(attempt: attempt, problem: problem)
                                .listRowBackground(Color.clear)
                                .listRowSeparator(.hidden)
                                .listRowInsets(EdgeInsets(top: 6, leading: 16, bottom: 6, trailing: 16))
                                .swipeActions(edge: .trailing, allowsFullSwipe: true) {
                                    Button(role: .destructive) {
                                        let impactFeedback = UIImpactFeedbackGenerator(style: .medium)
                                        impactFeedback.impactOccurred()
                                        attemptToDelete = attempt
                                    } label: {
                                        Label("Delete", systemImage: "trash")
                                    }
                                    .tint(.red)
                                    .accessibilityLabel("Delete attempt")

                                    Button {
                                        editingAttempt = attempt
                                    } label: {
                                        Label("Edit", systemImage: "pencil")
                                    }
                                    .tint(.indigo)
                                    .accessibilityLabel("Edit attempt")
                                }
                                .onTapGesture {
                                    editingAttempt = attempt
                                }
                        }
                    }
                } header: {
                    Text("Attempts (\(attemptsWithProblems.count))")
                        .font(.title2)
                        .fontWeight(.bold)
                        .foregroundColor(.primary)
                        .textCase(nil)
                        .padding(.bottom, 8)
                        .padding(.top, 16)
                }
            } else {
                Text("Session not found")
                    .foregroundColor(.secondary)
            }
        }
        .listStyle(.plain)
        .navigationTitle("Session Details")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                if let session = session {
                    if session.status == .active {
                        Button("End Session") {
                            dataManager.endSession(session.id)
                            dismiss()
                        }
                        .foregroundColor(.orange)
                    } else {
                        Button {
                            showingDeleteAlert = true
                        } label: {
                            Image(systemName: "trash")
                        }
                        .tint(.red)
                    }
                }
            }
        }
        .alert(
            "Delete Attempt",
            isPresented: Binding<Bool>(
                get: { attemptToDelete != nil },
                set: { if !$0 { attemptToDelete = nil } }
            )
        ) {
            Button("Cancel", role: .cancel) {
                attemptToDelete = nil
            }
            Button("Delete", role: .destructive) {
                if let attempt = attemptToDelete {
                    dataManager.deleteAttempt(attempt)
                    attemptToDelete = nil
                }
            }
        } message: {
            if let attempt = attemptToDelete,
                let problem = dataManager.problem(withId: attempt.problemId)
            {
                Text(
                    "Are you sure you want to delete this attempt on \"\(problem.name ?? "Unknown Problem")\"? This action cannot be undone."
                )
            } else {
                Text("Are you sure you want to delete this attempt? This action cannot be undone.")
            }
        }
        .overlay(alignment: .bottomTrailing) {
            if session?.status == .active {
                Button(action: { showingAddAttempt = true }) {
                    Image(systemName: "plus")
                        .font(.title2)
                        .foregroundColor(.white)
                        .frame(width: 56, height: 56)
                        .background(Circle().fill(themeManager.accentColor))
                        .shadow(radius: 4)
                }
                .padding()
            }
        }
        .confirmationDialog(
            "Delete Session",
            isPresented: $showingDeleteAlert,
            titleVisibility: .visible
        ) {
            Button("Delete", role: .destructive) {
                if let session = session {
                    dataManager.deleteSession(session)
                    dismiss()
                }
            }
            Button("Cancel", role: .cancel) {}
        } message: {
            Text(
                "Are you sure you want to delete this session? This will also delete all attempts associated with this session."
            )
        }
        .sheet(isPresented: $showingAddAttempt) {
            if let session = session, let gym = gym {
                AddAttemptView(session: session, gym: gym)
            }
        }
        .sheet(item: $editingAttempt) { attempt in
            EditAttemptView(attempt: attempt)
        }
    }

    private func calculateSessionStats() -> SessionStats {
        let successfulAttempts = attempts.filter { $0.result.isSuccessful }
        let uniqueProblems = Set(attempts.map { $0.problemId })
        let completedProblems = Set(successfulAttempts.map { $0.problemId })

        return SessionStats(
            totalAttempts: attempts.count,
            successfulAttempts: successfulAttempts.count,
            uniqueProblemsAttempted: uniqueProblems.count,
            uniqueProblemsCompleted: completedProblems.count
        )
    }
}

struct SessionHeaderCard: View {
    let session: ClimbSession
    let gym: Gym
    let stats: SessionStats
    @EnvironmentObject var themeManager: ThemeManager

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

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            VStack(alignment: .leading, spacing: 8) {
                Text(gym.name)
                    .font(.title)
                    .fontWeight(.bold)

                Text(Self.dateFormatter.string(from: session.date))
                    .font(.title2)
                    .foregroundColor(themeManager.accentColor)

                if session.status == .active {
                    if let startTime = session.startTime {
                        Text("Duration: ")
                            .font(.subheadline)
                            .foregroundColor(.secondary)
                            + Text(timerInterval: startTime...Date.distantFuture, countsDown: false)
                            .font(.subheadline)
                            .foregroundColor(.secondary)
                            .monospacedDigit()
                    }
                } else if let duration = session.duration {
                    Text("Duration: \(duration) minutes")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }

                if let notes = session.notes, !notes.isEmpty {
                    Text(notes)
                        .font(.body)
                        .padding(.top, 4)
                }
            }

            HStack {
                Image(systemName: session.status == .active ? "play.fill" : "checkmark.circle.fill")
                    .foregroundColor(session.status == .active ? .green : themeManager.accentColor)

                Text(session.status == .active ? "In Progress" : "Completed")
                    .font(.subheadline)
                    .fontWeight(.medium)
                    .foregroundColor(session.status == .active ? .green : themeManager.accentColor)

                Spacer()
            }
            .padding(.horizontal, 12)
            .padding(.vertical, 6)
            .background(
                RoundedRectangle(cornerRadius: 8)
                    .fill((session.status == .active ? Color.green : themeManager.accentColor).opacity(0.1))
            )
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(.regularMaterial)
        )
    }
}

struct SessionStatsCard: View {
    let stats: SessionStats

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

            if stats.totalAttempts == 0 {
                Text("No attempts recorded yet")
                    .foregroundColor(.secondary)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding()
            } else {
                LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 2), spacing: 16) {
                    StatItem(label: "Total Attempts", value: "\(stats.totalAttempts)")
                    StatItem(label: "Problems", value: "\(stats.uniqueProblemsAttempted)")
                    StatItem(label: "Completed", value: "\(stats.uniqueProblemsCompleted)")
                }
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(.regularMaterial)
        )
    }
}

struct StatItem: View {
    let label: String
    let value: String
    @EnvironmentObject var themeManager: ThemeManager

    var body: some View {
        VStack(spacing: 4) {
            Text(value)
                .font(.title2)
                .fontWeight(.bold)
                .foregroundColor(themeManager.accentColor)

            Text(label)
                .font(.caption)
                .foregroundColor(.secondary)
        }
        .frame(maxWidth: .infinity)
    }
}

struct AttemptCard: View {
    let attempt: Attempt
    let problem: Problem
    @EnvironmentObject var themeManager: ThemeManager

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack {
                VStack(alignment: .leading, spacing: 4) {
                    Text(problem.name ?? "Unknown Problem")
                        .font(.headline)
                        .fontWeight(.semibold)

                    Text("\(problem.difficulty.system.displayName): \(problem.difficulty.grade)")
                        .font(.subheadline)
                        .foregroundColor(themeManager.accentColor)

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

                Spacer()

                VStack(alignment: .trailing, spacing: 8) {
                    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 AttemptResultBadge: View {
    let result: AttemptResult

    private var badgeColor: Color {
        switch result {
        case .success, .flash:
            return .green
        case .fall:
            return .orange
        case .noProgress:
            return .red
        }
    }

    var body: some View {
        Text(result.displayName)
            .font(.caption)
            .fontWeight(.medium)
            .padding(.horizontal, 8)
            .padding(.vertical, 4)
            .background(
                RoundedRectangle(cornerRadius: 6)
                    .fill(badgeColor.opacity(0.1))
            )
            .foregroundColor(badgeColor)
            .overlay(
                RoundedRectangle(cornerRadius: 6)
                    .stroke(badgeColor.opacity(0.3), lineWidth: 1)
            )
    }
}

struct SessionStats {
    let totalAttempts: Int
    let successfulAttempts: Int
    let uniqueProblemsAttempted: Int
    let uniqueProblemsCompleted: Int
}

struct MusicControlCard: View {
    @EnvironmentObject var musicService: MusicService

    var body: some View {
        HStack {
            Image(systemName: "music.note")
                .font(.title2)
                .foregroundColor(.pink)
                .frame(width: 40, height: 40)
                .background(Color.pink.opacity(0.1))
                .clipShape(Circle())

            VStack(alignment: .leading, spacing: 2) {
                Text("Music")
                    .font(.headline)

                if let playlistId = musicService.selectedPlaylistId,
                   let playlist = musicService.playlists.first(where: { $0.id.rawValue == playlistId }) {
                    Text(playlist.name)
                        .font(.caption)
                        .foregroundColor(.secondary)
                } else {
                    Text("No playlist selected")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }

            Spacer()

            Button(action: {
                musicService.togglePlayback()
            }) {
                Image(systemName: musicService.isPlaying ? "pause.circle.fill" : "play.circle.fill")
                    .font(.system(size: 32))
                    .foregroundColor(.pink)
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(Color(.secondarySystemGroupedBackground))
                .shadow(color: .black.opacity(0.05), radius: 5, x: 0, y: 2)
        )
    }
}

#Preview {
    NavigationView {
        SessionDetailView(sessionId: UUID())
            .environmentObject(ClimbingDataManager.preview)
    }
}
