import SwiftUI
import SwiftData
import AVKit
import SharedModels

/// Three-button row for a curated YouTube video (Issue #21):
/// - **Stream** — opens in the YouTube app (falls back to Safari).
/// - **Download** — pulls the MP4 via YouTubeKit, shows progress, then enables Play.
/// - **Play** — enabled only when the video exists on disk; plays via AVPlayer.
///
/// Used by both `GuideDetailView` and `GrammarNoteDetailView` to keep the
/// video affordances consistent.
struct VideoActionsButtonRow: View {
    let video: YouTubeVideoStore.VideoEntry

    @Environment(\.openURL) private var openURL
    @Environment(\.modelContext) private var modelContext
    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    private var cloudModelContext: ModelContext { cloudModelContextProvider() }

    @State private var downloadService = VideoDownloadService.shared
    @State private var isDownloaded: Bool
    @State private var playerVideoId: String?
    @State private var downloadError: String?
    @State private var confirmDelete: Bool = false

    init(video: YouTubeVideoStore.VideoEntry) {
        self.video = video
        self._isDownloaded = State(initialValue: VideoDownloadService.isDownloaded(videoId: video.videoId))
    }

    private var activeStatus: VideoDownloadService.DownloadStatus? {
        downloadService.activeDownloads[video.videoId]
    }

    private var isDownloading: Bool {
        activeStatus != nil
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text(video.title)
                .font(.caption)
                .foregroundStyle(.secondary)
                .lineLimit(2)

            HStack(spacing: 10) {
                streamButton
                downloadButton
                playButton
            }
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 12))
        .fullScreenCover(item: Binding(
            get: { playerVideoId.map { LocalVideoID(videoId: $0) } },
            set: { playerVideoId = $0?.videoId }
        )) { id in
            LocalVideoPlayerSheet(videoId: id.videoId, title: video.title)
        }
        .alert("Download failed", isPresented: .init(
            get: { downloadError != nil },
            set: { if !$0 { downloadError = nil } }
        )) {
            Button("OK") { downloadError = nil }
        } message: {
            Text(downloadError ?? "")
        }
        .confirmationDialog(
            "Delete this downloaded video?",
            isPresented: $confirmDelete,
            titleVisibility: .visible
        ) {
            Button("Delete", role: .destructive) {
                downloadService.delete(videoId: video.videoId, modelContext: modelContext)
                isDownloaded = false
            }
            Button("Cancel", role: .cancel) {}
        } message: {
            Text("You can re-download it at any time.")
        }
        .onAppear {
            // Refresh on appear in case the user deleted the file via Settings.
            isDownloaded = VideoDownloadService.isDownloaded(videoId: video.videoId)
        }
    }

    // MARK: - Buttons

    private var streamButton: some View {
        Button {
            if let url = URL(string: "https://www.youtube.com/watch?v=\(video.videoId)") {
                ReviewStore.recordActivity(context: cloudModelContext)
                openURL(url)
            }
        } label: {
            Label("Stream", systemImage: "play.rectangle.fill")
                .labelStyle(VideoActionLabelStyle())
                .frame(maxWidth: .infinity)
        }
        .buttonStyle(.borderedProminent)
        .tint(.red)
        .controlSize(.large)
    }

    @ViewBuilder
    private var downloadButton: some View {
        // Single slot whose role flips through the download lifecycle:
        // Download → progress/label (disabled) → Delete.
        if let status = activeStatus {
            Button {} label: {
                VStack(spacing: 4) {
                    if let progress = status.progress {
                        ProgressView(value: progress).frame(width: 56)
                    } else {
                        ProgressView().controlSize(.small)
                    }
                    Text(status.label)
                        .font(.caption2.monospacedDigit().weight(.semibold))
                        .lineLimit(1)
                        .minimumScaleFactor(0.7)
                }
                .frame(maxWidth: .infinity)
            }
            .buttonStyle(.bordered)
            .tint(.blue)
            .controlSize(.large)
            .disabled(true)
        } else if isDownloaded {
            Button(role: .destructive) {
                confirmDelete = true
            } label: {
                Label("Delete", systemImage: "trash")
                    .labelStyle(VideoActionLabelStyle())
                    .frame(maxWidth: .infinity)
            }
            .buttonStyle(.bordered)
            .tint(.red)
            .controlSize(.large)
        } else {
            Button {
                Task { await startDownload() }
            } label: {
                Label("Download", systemImage: "arrow.down.to.line")
                    .labelStyle(VideoActionLabelStyle())
                    .frame(maxWidth: .infinity)
            }
            .buttonStyle(.bordered)
            .tint(.blue)
            .controlSize(.large)
        }
    }

    private var playButton: some View {
        Button {
            ReviewStore.recordActivity(context: cloudModelContext)
            playerVideoId = video.videoId
        } label: {
            Label("Play", systemImage: "play.fill")
                .labelStyle(VideoActionLabelStyle())
                .frame(maxWidth: .infinity)
        }
        .buttonStyle(.bordered)
        .tint(.green)
        .controlSize(.large)
        .disabled(!isDownloaded)
    }

    // MARK: - Actions

    private func startDownload() async {
        do {
            try await downloadService.download(
                videoId: video.videoId,
                title: video.title,
                into: modelContext
            )
            isDownloaded = true
            ReviewStore.recordActivity(context: cloudModelContext)
        } catch {
            downloadError = error.localizedDescription
        }
    }
}

// MARK: - Helper identifiable wrapper so .sheet(item:) can use a plain String

private struct LocalVideoID: Identifiable {
    let videoId: String
    var id: String { videoId }
}

// Stacks the icon above the title so three equal-width buttons fit an iPhone
// row without wrapping mid-word.
private struct VideoActionLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        VStack(spacing: 4) {
            configuration.icon
                .imageScale(.large)
            configuration.title
                .font(.caption2.weight(.semibold))
                .lineLimit(1)
                .minimumScaleFactor(0.8)
        }
    }
}

// MARK: - Local playback sheet

struct LocalVideoPlayerSheet: View {
    let videoId: String
    let title: String

    @Environment(\.dismiss) private var dismiss
    @State private var player: AVPlayer

    init(videoId: String, title: String) {
        self.videoId = videoId
        self.title = title
        self._player = State(initialValue: AVPlayer(url: VideoDownloadService.fileURL(for: videoId)))
    }

    var body: some View {
        NavigationStack {
            ZStack {
                Color.black.ignoresSafeArea()
                VideoPlayer(player: player)
                    .ignoresSafeArea()
                    .onAppear { player.play() }
                    .onDisappear { player.pause() }
            }
            .navigationTitle(title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbarBackground(.black, for: .navigationBar)
            .toolbarBackground(.visible, for: .navigationBar)
            .toolbarColorScheme(.dark, for: .navigationBar)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Done") { dismiss() }
                }
            }
        }
    }
}
