//
//  PollDetailView.swift
//  SportsTime
//
//  View for displaying poll details and results
//

import SwiftUI

struct PollDetailView: View {
    @Environment(\.dismiss) private var dismiss
    @Environment(\.colorScheme) private var colorScheme
    @State private var viewModel = PollDetailViewModel()
    @State private var showShareSheet = false
    @State private var showDeleteConfirmation = false
    @State private var showVotingSheet = false
    @State private var selectedTrip: Trip?
    @State private var isOwner = false

    let pollId: UUID?
    let shareCode: String?
    let initialPoll: TripPoll?

    init(pollId: UUID) {
        self.pollId = pollId
        self.shareCode = nil
        self.initialPoll = nil
    }

    init(shareCode: String) {
        self.pollId = nil
        self.shareCode = shareCode
        self.initialPoll = nil
    }

    /// Initialize with a poll object directly (avoids fetch delay)
    init(poll: TripPoll) {
        self.pollId = poll.id
        self.shareCode = nil
        self.initialPoll = poll
    }

    var body: some View {
        Group {
            if viewModel.isLoading && viewModel.poll == nil {
                ProgressView("Loading poll...")
            } else if let poll = viewModel.poll {
                pollContent(poll)
            } else if let error = viewModel.error {
                ContentUnavailableView(
                    "Poll Not Found",
                    systemImage: "exclamationmark.triangle",
                    description: Text(error.localizedDescription)
                )
            }
        }
        .navigationTitle(viewModel.poll?.title ?? "Poll")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            if viewModel.poll != nil {
                ToolbarItem(placement: .primaryAction) {
                    Menu {
                        Button {
                            showShareSheet = true
                        } label: {
                            Label("Share Poll", systemImage: "square.and.arrow.up")
                        }

                        if isOwner {
                            Divider()

                            Button(role: .destructive) {
                                showDeleteConfirmation = true
                            } label: {
                                Label("Delete Poll", systemImage: "trash")
                            }
                        }
                    } label: {
                        Image(systemName: "ellipsis.circle")
                            .minimumHitTarget()
                            .accessibilityLabel("More options")
                    }
                }
            }
        }
        .refreshable {
            await viewModel.refresh()
        }
        .task {
            await loadPoll()
            isOwner = await viewModel.isOwner
        }
        .task(id: viewModel.poll?.id) {
            if viewModel.poll != nil {
                isOwner = await viewModel.isOwner
            }
        }
        .onDisappear {
            Task {
                await viewModel.cleanup()
            }
        }
        .sheet(isPresented: $showShareSheet) {
            if let url = viewModel.shareURL {
                ShareSheet(items: [url])
            }
        }
        .sheet(isPresented: $showVotingSheet) {
            if let poll = viewModel.poll {
                PollVotingView(poll: poll, existingVote: viewModel.myVote) {
                    Task {
                        await viewModel.refresh()
                    }
                }
            }
        }
        .confirmationDialog("Delete Poll", isPresented: $showDeleteConfirmation, titleVisibility: .visible) {
            Button("Delete", role: .destructive) {
                Task {
                    if await viewModel.deletePoll() {
                        dismiss()
                    }
                }
            }
            Button("Cancel", role: .cancel) {}
        } message: {
            Text("This will permanently delete the poll and all votes. This action cannot be undone.")
        }
        .sheet(item: $selectedTrip) { trip in
            NavigationStack {
                TripDetailView(trip: trip, allowCustomItems: true)
                    .navigationBarTitleDisplayMode(.inline)
                    .toolbar {
                        ToolbarItem(placement: .cancellationAction) {
                            Button("Done") {
                                selectedTrip = nil
                            }
                        }
                    }
            }
        }
    }

    @ViewBuilder
    private func pollContent(_ poll: TripPoll) -> some View {
        ScrollView {
            VStack(spacing: Theme.Spacing.lg) {
                // Share Code Card
                shareCodeCard(poll)

                // Voting Status
                votingStatusCard

                // Results
                if let results = viewModel.results {
                    resultsSection(results)
                }

                // Trip Previews
                tripPreviewsSection(poll)
            }
            .padding(.horizontal, Theme.Spacing.md)
            .padding(.vertical, Theme.Spacing.lg)
        }
        .background(Theme.backgroundGradient(colorScheme))
    }

    @ViewBuilder
    private func shareCodeCard(_ poll: TripPoll) -> some View {
        VStack(spacing: Theme.Spacing.md) {
            // Icon
            ZStack {
                Circle()
                    .fill(Theme.warmOrange.opacity(0.15))
                    .frame(width: 56, height: 56)
                Image(systemName: "link.circle.fill")
                    .font(.title2)
                    .foregroundStyle(Theme.warmOrange)
            }

            VStack(spacing: Theme.Spacing.xs) {
                Text("Share Code")
                    .font(.subheadline)
                    .foregroundStyle(Theme.textSecondary(colorScheme))

                Text(poll.shareCode)
                    .font(.system(.largeTitle, design: .monospaced).weight(.bold))
                    .foregroundStyle(Theme.warmOrange)
                    .tracking(4)
                    .lineLimit(1)
                    .minimumScaleFactor(0.7)
            }

            // Copy button
            Button {
                UIPasteboard.general.string = poll.shareCode
            } label: {
                Label("Copy Code", systemImage: "doc.on.doc")
                    .font(.subheadline.weight(.medium))
                    .foregroundStyle(Theme.warmOrange)
                    .padding(.horizontal, Theme.Spacing.md)
                    .padding(.vertical, Theme.Spacing.sm)
                    .background(Theme.warmOrange.opacity(0.1))
                    .clipShape(Capsule())
            }
        }
        .frame(maxWidth: .infinity)
        .padding(Theme.Spacing.lg)
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.large))
        .overlay(
            RoundedRectangle(cornerRadius: Theme.CornerRadius.large)
                .strokeBorder(Theme.warmOrange.opacity(0.2), lineWidth: 1)
        )
    }

    @ViewBuilder
    private var votingStatusCard: some View {
        HStack(spacing: Theme.Spacing.md) {
            // Status icon
            ZStack {
                Circle()
                    .fill(viewModel.hasVoted ? Theme.mlsGreen.opacity(0.15) : Theme.warmOrange.opacity(0.15))
                    .frame(width: 44, height: 44)
                Image(systemName: viewModel.hasVoted ? "checkmark.circle.fill" : "hand.raised.fill")
                    .font(.title3)
                    .foregroundStyle(viewModel.hasVoted ? Theme.mlsGreen : Theme.warmOrange)
                    .accessibilityLabel(viewModel.hasVoted ? "You have voted" : "You have not voted")
            }

            VStack(alignment: .leading, spacing: 2) {
                Text(viewModel.hasVoted ? "You voted" : "Cast your vote")
                    .font(.headline)
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                HStack(spacing: Theme.Spacing.xs) {
                    Image(systemName: "person.2.fill")
                        .font(.caption2)
                        .accessibilityHidden(true)
                    Text("\(viewModel.votes.count) vote\(viewModel.votes.count == 1 ? "" : "s")")
                        .font(.subheadline)
                }
                .foregroundStyle(Theme.textSecondary(colorScheme))
            }

            Spacer()

            Button {
                showVotingSheet = true
            } label: {
                Text(viewModel.hasVoted ? "Change" : "Vote")
                    .font(.subheadline.weight(.semibold))
                    .foregroundStyle(.white)
                    .padding(.horizontal, Theme.Spacing.md)
                    .padding(.vertical, Theme.Spacing.sm)
                    .background(Theme.warmOrange)
                    .clipShape(Capsule())
            }
        }
        .padding(Theme.Spacing.md)
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
    }

    @ViewBuilder
    private func resultsSection(_ results: PollResults) -> some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.md) {
            // Section header
            HStack(spacing: Theme.Spacing.sm) {
                Image(systemName: "chart.bar.fill")
                    .foregroundStyle(Theme.warmOrange)
                    .accessibilityHidden(true)
                Text("Results")
                    .font(.headline)
                    .foregroundStyle(Theme.textPrimary(colorScheme))
            }

            VStack(spacing: Theme.Spacing.sm) {
                ForEach(results.tripScores, id: \.tripIndex) { item in
                    let trip = results.poll.tripSnapshots[item.tripIndex]
                    let rank = results.tripScores.firstIndex { $0.tripIndex == item.tripIndex }! + 1
                    ResultRow(
                        rank: rank,
                        tripName: trip.displayName,
                        score: item.score,
                        percentage: results.scorePercentage(for: item.tripIndex),
                        isLeader: rank == 1 && item.score > 0
                    )
                }
            }
        }
        .padding(Theme.Spacing.md)
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
    }

    @ViewBuilder
    private func tripPreviewsSection(_ poll: TripPoll) -> some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.md) {
            // Section header
            HStack(spacing: Theme.Spacing.sm) {
                Image(systemName: "map.fill")
                    .foregroundStyle(Theme.warmOrange)
                    .accessibilityHidden(true)
                Text("Trip Options")
                    .font(.headline)
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                Spacer()

                Text("\(poll.tripSnapshots.count) trips")
                    .font(.caption)
                    .foregroundStyle(Theme.textMuted(colorScheme))
            }

            ForEach(Array(poll.tripSnapshots.enumerated()), id: \.element.id) { index, trip in
                Button {
                    selectedTrip = trip
                } label: {
                    TripPreviewCard(trip: trip, index: index + 1)
                }
                .buttonStyle(.plain)
            }
        }
    }

    private func loadPoll() async {
        // If we have an initial poll object, use it directly to avoid CloudKit fetch delay
        if let initialPoll {
            await viewModel.loadPoll(from: initialPoll)
        } else if let pollId {
            await viewModel.loadPoll(byId: pollId)
        } else if let shareCode {
            await viewModel.loadPoll(byShareCode: shareCode)
        }
    }
}

// MARK: - Result Row

private struct ResultRow: View {
    @Environment(\.colorScheme) private var colorScheme
    let rank: Int
    let tripName: String
    let score: Int
    let percentage: Double
    var isLeader: Bool = false

    private var rankIcon: String {
        switch rank {
        case 1: return "trophy.fill"
        case 2: return "medal.fill"
        case 3: return "medal.fill"
        default: return "\(rank).circle.fill"
        }
    }

    private var rankAccessibilityLabel: String {
        switch rank {
        case 1: return "First place"
        case 2: return "Second place"
        case 3: return "Third place"
        default: return "\(rank)\(rankSuffix) place"
        }
    }

    private var rankSuffix: String {
        let ones = rank % 10
        let tens = rank % 100
        if tens >= 11 && tens <= 13 { return "th" }
        switch ones {
        case 1: return "st"
        case 2: return "nd"
        case 3: return "rd"
        default: return "th"
        }
    }

    private var rankColor: Color {
        switch rank {
        case 1: return Theme.warmOrange
        case 2: return .gray
        case 3: return .brown
        default: return .secondary
        }
    }

    var body: some View {
        HStack(spacing: Theme.Spacing.sm) {
            // Rank badge
            ZStack {
                Circle()
                    .fill(rankColor.opacity(0.15))
                    .frame(width: 36, height: 36)
                Image(systemName: rankIcon)
                    .font(.subheadline)
                    .foregroundStyle(rankColor)
                    .accessibilityLabel(rankAccessibilityLabel)
            }

            VStack(alignment: .leading, spacing: 4) {
                Text(tripName)
                    .font(.subheadline.weight(isLeader ? .semibold : .regular))
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                GeometryReader { geometry in
                    ZStack(alignment: .leading) {
                        RoundedRectangle(cornerRadius: 4)
                            .fill(Theme.cardBackgroundElevated(colorScheme))
                            .frame(height: 6)

                        RoundedRectangle(cornerRadius: 4)
                            .fill(rankColor)
                            .frame(width: max(geometry.size.width * percentage, percentage > 0 ? 6 : 0), height: 6)
                    }
                }
                .frame(height: 6)
            }

            // Score badge
            Text("\(score)")
                .font(.subheadline.weight(.medium).monospacedDigit())
                .foregroundStyle(rankColor)
                .padding(.horizontal, 10)
                .padding(.vertical, 4)
                .background(rankColor.opacity(0.1))
                .clipShape(Capsule())
        }
        .padding(.vertical, Theme.Spacing.xs)
    }
}

// MARK: - Trip Preview Card

private struct TripPreviewCard: View {
    @Environment(\.colorScheme) private var colorScheme
    let trip: Trip
    let index: Int

    var body: some View {
        HStack(spacing: 12) {
            VStack(alignment: .leading, spacing: 8) {
                HStack {
                    Text("Option \(index)")
                        .font(.caption)
                        .fontWeight(.semibold)
                        .foregroundStyle(.white)
                        .padding(.horizontal, 8)
                        .padding(.vertical, 4)
                        .background(Theme.warmOrange)
                        .clipShape(Capsule())

                    Text(trip.displayName)
                        .font(.headline)
                        .foregroundStyle(.primary)
                }

                // Date range and duration
                HStack {
                    Label(trip.formattedDateRange, systemImage: "calendar")
                    Spacer()
                    Label("\(trip.tripDuration) days", systemImage: "clock")
                }
                .font(.caption)
                .foregroundStyle(.secondary)

                HStack {
                    Label("\(trip.stops.count) stops", systemImage: "mappin.and.ellipse")
                    Spacer()
                    Label("\(trip.stops.flatMap { $0.games }.count) games", systemImage: "sportscourt")
                }
                .font(.caption)
                .foregroundStyle(.secondary)
            }

            Image(systemName: "chevron.right")
                .font(.caption)
                .fontWeight(.semibold)
                .foregroundStyle(.tertiary)
                .accessibilityHidden(true)
        }
        .padding()
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: 12))
        .overlay(
            RoundedRectangle(cornerRadius: 12)
                .strokeBorder(Color.secondary.opacity(0.1), lineWidth: 1)
        )
    }
}

#Preview {
    NavigationStack {
        PollDetailView(shareCode: "ABC123")
    }
}
