//
//  QualitySelectorView+Sections.swift
//  Yattee
//
//  Section content views for QualitySelectorView.
//

import SwiftUI

extension QualitySelectorView {
    // MARK: - Main Content Views

    @ViewBuilder
    var loadingContent: some View {
        VStack(spacing: 16) {
            Spacer()
            ProgressView()
                .controlSize(.large)
            Text(String(localized: "player.quality.loading"))
                .font(.subheadline)
                .foregroundStyle(.secondary)
            Spacer()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    @ViewBuilder
    var emptyContent: some View {
        ContentUnavailableView(
            String(localized: "player.quality.unavailable"),
            systemImage: "film.stack",
            description: Text(String(localized: "player.quality.unavailable.description"))
        )
    }

    @ViewBuilder
    var downloadedContent: some View {
        ScrollView {
            VStack(spacing: 16) {
                if !hasOnlineStreams {
                    downloadInfoSection
                    loadOnlineStreamsButton
                } else {
                    onlineStreamsAfterDownload
                }

                if showTabPicker {
                    generalSectionContent
                }
            }
            .padding()
        }
    }

    @ViewBuilder
    var streamsContent: some View {
        ScrollView {
            VStack(spacing: 16) {
                if showTabPicker && availableTabs.count > 1 {
                    mediaSelectionRows
                } else {
                    tabContent
                }

                if showTabPicker {
                    generalSectionContent
                }
            }
            .padding()
        }
        .onAppear {
            selectedTab = initialTab
        }
    }

    // MARK: - Tab Content

    @ViewBuilder
    private var mediaSelectionRows: some View {
        VStack(spacing: 0) {
            NavigationLink(value: QualitySelectorDestination.video) {
                HStack {
                    Label(String(localized: "player.quality.video"), systemImage: "film")
                        .font(.headline)
                    Spacer()
                    Text(currentVideoDisplayValue)
                        .foregroundStyle(.secondary)
                    Image(systemName: "chevron.right")
                        .font(.caption.weight(.semibold))
                        .foregroundStyle(.tertiary)
                }
                .padding(.vertical, 12)
                .padding(.horizontal, 12)
                .contentShape(Rectangle())
            }
            .buttonStyle(.plain)

            if availableTabs.contains(.audio) {
                Divider()
                NavigationLink(value: QualitySelectorDestination.audio) {
                    HStack {
                        Label(String(localized: "stream.audio"), systemImage: "speaker.wave.2")
                            .font(.headline)
                        Spacer()
                        Text(currentAudioDisplayValue)
                            .foregroundStyle(.secondary)
                        Image(systemName: "chevron.right")
                            .font(.caption.weight(.semibold))
                            .foregroundStyle(.tertiary)
                    }
                    .padding(.vertical, 12)
                    .padding(.horizontal, 12)
                    .contentShape(Rectangle())
                }
                .buttonStyle(.plain)
            }

            if availableTabs.contains(.subtitles) {
                Divider()
                NavigationLink(value: QualitySelectorDestination.subtitles) {
                    HStack {
                        Label(String(localized: "stream.subtitles"), systemImage: "captions.bubble")
                            .font(.headline)
                        Spacer()
                        Text(currentSubtitlesDisplayValue)
                            .foregroundStyle(.secondary)
                        Image(systemName: "chevron.right")
                            .font(.caption.weight(.semibold))
                            .foregroundStyle(.tertiary)
                    }
                    .padding(.vertical, 12)
                    .padding(.horizontal, 12)
                    .contentShape(Rectangle())
                }
                .buttonStyle(.plain)
            }
        }
        .cardBackground()
    }

    // MARK: - Display Value Computed Properties

    private var currentVideoDisplayValue: String {
        guard let stream = currentStream else {
            return String(localized: "stream.subtitles.none")
        }
        let format = StreamFormat.detect(from: stream)
        if format == .hls || format == .dash {
            return format == .hls ? "HLS" : "DASH"
        }
        return stream.qualityLabel
    }

    private var currentAudioDisplayValue: String {
        if isCurrentStreamMuxed {
            return String(localized: "player.quality.audioFromVideo.short")
        }
        if let audio = selectedAudioStream ?? currentAudioStream {
            return parseAudioTrackName(audio).language
        }
        return String(localized: "stream.audio.default")
    }

    private var currentSubtitlesDisplayValue: String {
        currentCaption?.displayName ?? String(localized: "stream.subtitles.off")
    }

    // MARK: - Detail Content Views

    @ViewBuilder
    var videoDetailContent: some View {
        ScrollView {
            VStack(spacing: 16) {
                if !adaptiveStreams.isEmpty {
                    adaptiveSectionContent
                }
                if !videoStreams.isEmpty {
                    videoSectionContent
                }
            }
            .padding()
        }
        .background(ListBackgroundStyle.grouped.color)
        .navigationTitle(String(localized: "player.quality.video"))
        #if os(iOS)
        .navigationBarTitleDisplayMode(.inline)
        #endif
    }

    @ViewBuilder
    var audioDetailContent: some View {
        ScrollView {
            VStack(spacing: 16) {
                audioSectionContent
            }
            .padding()
        }
        .background(ListBackgroundStyle.grouped.color)
        .navigationTitle(String(localized: "stream.audio"))
        #if os(iOS)
        .navigationBarTitleDisplayMode(.inline)
        #endif
    }

    @ViewBuilder
    var subtitlesDetailContent: some View {
        ScrollView {
            VStack(spacing: 16) {
                subtitlesSectionContent
            }
            .padding()
        }
        .background(ListBackgroundStyle.grouped.color)
        .navigationTitle(String(localized: "stream.subtitles"))
        #if os(iOS)
        .navigationBarTitleDisplayMode(.inline)
        #endif
    }

    @ViewBuilder
    private var tabContent: some View {
        if selectedTab == .video && !adaptiveStreams.isEmpty {
            adaptiveSectionContent
        }

        switch selectedTab {
        case .video:
            if !videoStreams.isEmpty {
                videoSectionContent
            }
        case .audio:
            audioSectionContent
        case .subtitles:
            subtitlesSectionContent
        }
    }

    @ViewBuilder
    private var onlineStreamsAfterDownload: some View {
        if availableTabs.count > 1 {
            mediaSelectionRows
        } else {
            if selectedTab == .video && !adaptiveStreams.isEmpty {
                adaptiveSectionContent
            }

            switch selectedTab {
            case .video:
                if !videoStreams.isEmpty {
                    videoSectionContent
                }
            case .audio:
                audioSectionContent
            case .subtitles:
                subtitlesSectionContent
            }
        }
    }

    // MARK: - General Section

    @ViewBuilder
    var generalSectionContent: some View {
        VStack(spacing: 0) {
            playbackSpeedRow

            Divider()

            #if !os(tvOS)
            lockControlsRow
            #endif
        }
        .cardBackground()
    }

    @ViewBuilder
    private var playbackSpeedRow: some View {
        HStack {
            Label(String(localized: "player.quality.playbackSpeed"), systemImage: "gauge.with.needle")
                .font(.headline)

            Spacer()

            HStack(spacing: 8) {
                Button {
                    if let newRate = previousRate() {
                        onRateChanged?(newRate)
                    }
                } label: {
                    Image(systemName: "minus")
                        .font(.body.weight(.medium))
                        .frame(minWidth: 18, minHeight: 18)
                        .contentShape(Rectangle())
                }
                .buttonStyle(.bordered)
                .disabled(previousRate() == nil)

                Menu {
                    ForEach(PlaybackRate.allCases) { rate in
                        Button {
                            onRateChanged?(rate)
                        } label: {
                            if currentRate == rate {
                                Label(rate.displayText, systemImage: "checkmark")
                            } else {
                                Text(rate.displayText)
                            }
                        }
                    }
                } label: {
                    Text(currentRate.displayText)
                        .font(.body.weight(.medium))
                        .frame(minWidth: 60)
                }
                .menuStyle(.borderlessButton)

                Button {
                    if let newRate = nextRate() {
                        onRateChanged?(newRate)
                    }
                } label: {
                    Image(systemName: "plus")
                        .font(.body.weight(.medium))
                        .frame(minWidth: 18, minHeight: 18)
                        .contentShape(Rectangle())
                }
                .buttonStyle(.bordered)
                .disabled(nextRate() == nil)
            }
        }
        .padding(.vertical, 12)
        .padding(.horizontal, 12)
    }

    #if !os(tvOS)
    @ViewBuilder
    private var lockControlsRow: some View {
        HStack {
            Label(String(localized: "player.quality.lockControls"), systemImage: "lock")
                .font(.headline)

            Spacer()

            Toggle("", isOn: Binding(
                get: { isControlsLocked },
                set: { onLockToggled?($0) }
            ))
            .labelsHidden()
        }
        .padding(.vertical, 12)
        .padding(.horizontal, 12)
    }
    #endif

    // MARK: - Download Info Section

    @ViewBuilder
    var downloadInfoSection: some View {
        if let download = currentDownload {
            // Video section
            VStack(alignment: .leading, spacing: 8) {
                Label(String(localized: "player.quality.video"), systemImage: "film")
                    .font(.subheadline.weight(.semibold))
                    .foregroundStyle(.secondary)

                VStack(spacing: 0) {
                    DownloadedVideoRowView(download: download, showAdvancedDetails: showAdvancedStreamDetails)
                        .padding(.vertical, 8)
                        .padding(.horizontal, 12)
                }
                .cardBackground()
            }

            // Audio section (if separate audio track)
            if download.localAudioPath != nil {
                VStack(alignment: .leading, spacing: 8) {
                    Label(String(localized: "stream.audio"), systemImage: "speaker.wave.2")
                        .font(.subheadline.weight(.semibold))
                        .foregroundStyle(.secondary)

                    VStack(spacing: 0) {
                        DownloadedAudioRowView(download: download, showAdvancedDetails: showAdvancedStreamDetails)
                            .padding(.vertical, 8)
                            .padding(.horizontal, 12)
                    }
                    .cardBackground()
                }
            }

            // Subtitles section (if downloaded)
            if download.localCaptionPath != nil {
                VStack(alignment: .leading, spacing: 8) {
                    Label(String(localized: "stream.subtitles"), systemImage: "captions.bubble")
                        .font(.subheadline.weight(.semibold))
                        .foregroundStyle(.secondary)

                    VStack(spacing: 0) {
                        CaptionRowView(
                            caption: nil,
                            isSelected: currentCaption == nil,
                            isPreferred: false,
                            onTap: {
                                onCaptionSelected(nil)
                                dismiss()
                            }
                        )
                        .padding(.vertical, 8)
                        .padding(.horizontal, 12)

                        Divider()

                        DownloadedCaptionRowView(
                            download: download,
                            localCaptionURL: localCaptionURL,
                            currentCaption: currentCaption,
                            onCaptionSelected: onCaptionSelected,
                            onDismiss: { dismiss() }
                        )
                        .padding(.vertical, 8)
                        .padding(.horizontal, 12)
                    }
                    .cardBackground()
                }
            }
        }
    }

    @ViewBuilder
    var loadOnlineStreamsButton: some View {
        Button {
            onLoadOnlineStreams()
        } label: {
            HStack {
                if isLoadingOnlineStreams {
                    ProgressView()
                        .controlSize(.small)
                } else {
                    Image(systemName: "arrow.clockwise")
                }
                Text(String(localized: "player.quality.loadOnline"))
            }
            .frame(maxWidth: .infinity)
            .padding(.vertical, 12)
        }
        .buttonStyle(.bordered)
        .disabled(isLoadingOnlineStreams)
    }

    // MARK: - Adaptive Section

    @ViewBuilder
    var adaptiveSectionContent: some View {
        VStack(alignment: .leading, spacing: 8) {
            Label(String(localized: "stream.adaptive"), systemImage: "antenna.radiowaves.left.and.right")
                .font(.subheadline.weight(.semibold))
                .foregroundStyle(.secondary)

            VStack(spacing: 0) {
                ForEach(Array(adaptiveStreams.enumerated()), id: \.element.url) { index, stream in
                    if index > 0 {
                        Divider()
                    }
                    AdaptiveStreamRowView(
                        stream: stream,
                        isSelected: stream.url == currentStream?.url,
                        onTap: {
                            handleAdaptiveStreamTap(stream)
                        }
                    )
                    .padding(.vertical, 10)
                    .padding(.horizontal, 12)
                }
            }
            .cardBackground()
        }
    }

    private func handleAdaptiveStreamTap(_ stream: Stream) {
        if isPlayingDownloadedContent {
            onSwitchToOnlineStream(stream, nil)
        } else {
            onStreamSelected(stream, nil)
        }
        dismiss()
    }

    // MARK: - Video Section

    @ViewBuilder
    var videoSectionContent: some View {
        VStack(spacing: 16) {
            // Recommended section
            if !recommendedVideoStreams.isEmpty {
                VStack(alignment: .leading, spacing: 8) {
                    Label(String(localized: "player.quality.recommended"), systemImage: "bolt.fill")
                        .font(.subheadline.weight(.semibold))
                        .foregroundStyle(.secondary)

                    VStack(spacing: 0) {
                        ForEach(Array(recommendedVideoStreams.enumerated()), id: \.element.url) { index, stream in
                            if index > 0 {
                                Divider()
                            }
                            videoStreamRow(stream)
                                .padding(.vertical, 8)
                                .padding(.horizontal, 12)
                        }
                    }
                    .cardBackground()
                }
            }

            // Other section (software decode)
            if showAdvancedStreamDetails && !otherVideoStreams.isEmpty {
                VStack(alignment: .leading, spacing: 8) {
                    Label(String(localized: "player.quality.other"), systemImage: "cpu")
                        .font(.subheadline.weight(.semibold))
                        .foregroundStyle(.secondary)

                    VStack(spacing: 0) {
                        ForEach(Array(otherVideoStreams.enumerated()), id: \.element.url) { index, stream in
                            if index > 0 {
                                Divider()
                            }
                            videoStreamRow(stream)
                                .padding(.vertical, 8)
                                .padding(.horizontal, 12)
                        }
                    }
                    .cardBackground()
                }
            }
        }
    }

    @ViewBuilder
    private func videoStreamRow(_ stream: Stream) -> some View {
        let isDownloadedStream: Bool = stream.url.isFileURL
        let isSelected: Bool = stream.isMuxed
            ? stream.url == currentStream?.url
            : stream.url == selectedVideoStream?.url
        let isPreferredQuality: Bool = stream.resolution == preferredQuality.maxResolution

        VideoStreamRowView(
            stream: stream,
            isSelected: isSelected,
            isPreferredQuality: isPreferredQuality,
            isDownloaded: isDownloadedStream,
            showAdvancedDetails: showAdvancedStreamDetails,
            requiresSoftwareDecode: !stream.isMuxed && requiresSoftwareDecode(stream.videoCodec),
            onTap: {
                handleVideoStreamTap(stream, isDownloaded: isDownloadedStream)
            }
        )
    }

    private func handleVideoStreamTap(_ stream: Stream, isDownloaded: Bool) {
        if isDownloaded {
            if stream.isMuxed {
                onStreamSelected(stream, nil)
                dismiss()
            } else {
                selectedVideoStream = stream
                if let audio = selectedAudioStream {
                    onStreamSelected(stream, audio)
                    dismiss()
                }
            }
        } else if isPlayingDownloadedContent {
            let audioStream: Stream? = stream.isVideoOnly ? (selectedAudioStream ?? defaultAudioStream) : nil
            onSwitchToOnlineStream(stream, audioStream)
            dismiss()
        } else {
            if stream.isMuxed {
                onStreamSelected(stream, nil)
                dismiss()
            } else {
                selectedVideoStream = stream
                if let audio = selectedAudioStream {
                    onStreamSelected(stream, audio)
                    dismiss()
                }
            }
        }
    }

    // MARK: - Audio Section

    @ViewBuilder
    var audioSectionContent: some View {
        if isCurrentStreamMuxed {
            VStack(spacing: 0) {
                HStack {
                    Image(systemName: "info.circle")
                        .foregroundStyle(.secondary)
                    Text(String(localized: "player.quality.audioFromVideo"))
                        .font(.subheadline)
                        .foregroundStyle(.secondary)
                    Spacer()
                }
                .padding(.vertical, 12)
                .padding(.horizontal, 12)
            }
            .cardBackground()
        } else {
            VStack(spacing: 0) {
                ForEach(Array(audioStreams.enumerated()), id: \.element.url) { index, stream in
                    if index > 0 {
                        Divider()
                    }
                    audioStreamRow(stream)
                        .padding(.vertical, 8)
                        .padding(.horizontal, 12)
                }
            }
            .cardBackground()
        }
    }

    @ViewBuilder
    private func audioStreamRow(_ stream: Stream) -> some View {
        let isSelected: Bool = stream.url == selectedAudioStream?.url
        let isPreferred: Bool = preferredAudioLanguage.map { (stream.audioLanguage ?? "").hasPrefix($0) } ?? false
        let trackInfo: AudioTrackInfo = parseAudioTrackName(stream)

        AudioStreamRowView(
            stream: stream,
            isSelected: isSelected,
            isPreferred: isPreferred,
            showAdvancedDetails: showAdvancedStreamDetails,
            trackInfo: trackInfo,
            onTap: {
                handleAudioStreamTap(stream)
            }
        )
    }

    private func handleAudioStreamTap(_ stream: Stream) {
        selectedAudioStream = stream
        if let video = selectedVideoStream, video.isVideoOnly {
            onStreamSelected(video, stream)
            dismiss()
        }
    }

    // MARK: - Subtitles Section

    @ViewBuilder
    var subtitlesSectionContent: some View {
        VStack(spacing: 0) {
            CaptionRowView(
                caption: nil,
                isSelected: currentCaption == nil,
                isPreferred: false,
                onTap: {
                    handleCaptionTap(nil)
                }
            )
            .padding(.vertical, 8)
            .padding(.horizontal, 12)

            ForEach(sortedCaptions) { caption in
                Divider()

                CaptionRowView(
                    caption: caption,
                    isSelected: caption.id == currentCaption?.id,
                    isPreferred: isCaptionPreferred(caption),
                    onTap: {
                        handleCaptionTap(caption)
                    }
                )
                .padding(.vertical, 8)
                .padding(.horizontal, 12)
            }
        }
        .cardBackground()
    }

    private func isCaptionPreferred(_ caption: Caption) -> Bool {
        guard let preferred = preferredSubtitlesLanguage else { return false }
        return caption.baseLanguageCode == preferred || caption.languageCode.hasPrefix(preferred)
    }

    private func handleCaptionTap(_ caption: Caption?) {
        if caption?.id == currentCaption?.id && caption != nil {
            onCaptionSelected(nil)
        } else {
            onCaptionSelected(caption)
        }
        dismiss()
    }
}
