//
//  PlaybackCommands.swift
//  Yattee
//
//  Menu bar commands for playback control.
//

import SwiftUI

#if !os(tvOS)
/// Playback-related menu bar commands.
/// Works on both macOS and iPadOS 26+.
struct PlaybackCommands: Commands {
    let appEnvironment: AppEnvironment

    private var playerService: PlayerService {
        appEnvironment.playerService
    }

    private var navigationCoordinator: NavigationCoordinator {
        appEnvironment.navigationCoordinator
    }

    private var state: PlayerState {
        playerService.state
    }

    private var settingsManager: SettingsManager {
        appEnvironment.settingsManager
    }

    private var hasActiveVideo: Bool {
        state.currentVideo != nil
    }

    private var isPlayerExpanded: Bool {
        navigationCoordinator.isPlayerExpanded
    }

    var body: some Commands {
        CommandMenu(String(localized: "menu.playback")) {
            // Player visibility (existing)
            playerToggleButton

            Divider()

            // Core playback
            playPauseButton

            Divider()

            // Seeking
            seekBackwardButton
            seekForwardButton
            secondarySeekBackwardButton
            secondarySeekForwardButton

            Divider()

            // Navigation
            previousVideoButton
            nextVideoButton

            Divider()

            // Speed
            slowerButton
            fasterButton
            resetSpeedButton

            Divider()

            // Volume
            volumeUpButton
            volumeDownButton
            muteButton

            Divider()

            // Display modes
            pipButton
            
            Divider()
            closeVideoButton
        }
    }

    // MARK: - Player Visibility

    private var playerToggleButton: some View {
        Button {
            togglePlayerExpanded()
        } label: {
            Text(isPlayerExpanded
                ? String(localized: "menu.playback.hidePlayer")
                : String(localized: "menu.playback.showPlayer"))
        }
        .keyboardShortcut("p", modifiers: [.command, .shift])
        .disabled(!hasActiveVideo)
    }

    private func togglePlayerExpanded() {
        if isPlayerExpanded {
            navigationCoordinator.isPlayerExpanded = false
        } else {
            navigationCoordinator.expandPlayer()
        }
    }

    // MARK: - Core Playback

    private var playPauseButton: some View {
        Button {
            playerService.togglePlayPause()
        } label: {
            Text(String(localized: "menu.playback.playPause"))
        }
        .keyboardShortcut("k", modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    // MARK: - Seeking

    /// Seek durations follow the active player controls preset, matching the
    /// in-player arrow key shortcuts.
    private var seekBackwardSeconds: Int {
        appEnvironment.activeControlsCenterSettings.seekBackwardSeconds
    }

    private var seekForwardSeconds: Int {
        appEnvironment.activeControlsCenterSettings.seekForwardSeconds
    }

    private var seekBackwardButton: some View {
        Button {
            playerService.seekBackward(by: TimeInterval(seekBackwardSeconds))
        } label: {
            Text(String(localized: "menu.playback.seekBackward \(seekBackwardSeconds)"))
        }
        .keyboardShortcut(.leftArrow, modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private var seekForwardButton: some View {
        Button {
            playerService.seekForward(by: TimeInterval(seekForwardSeconds))
        } label: {
            Text(String(localized: "menu.playback.seekForward \(seekForwardSeconds)"))
        }
        .keyboardShortcut(.rightArrow, modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private var secondarySeekBackwardSeconds: Int {
        appEnvironment.activeControlsCenterSettings.secondarySeekBackwardSeconds
    }

    private var secondarySeekForwardSeconds: Int {
        appEnvironment.activeControlsCenterSettings.secondarySeekForwardSeconds
    }

    private var secondarySeekBackwardButton: some View {
        Button {
            playerService.seekBackward(by: TimeInterval(secondarySeekBackwardSeconds))
        } label: {
            Text(String(localized: "menu.playback.seekBackward \(secondarySeekBackwardSeconds)"))
        }
        .keyboardShortcut(.leftArrow, modifiers: [.command, .shift])
        .disabled(!hasActiveVideo)
    }

    private var secondarySeekForwardButton: some View {
        Button {
            playerService.seekForward(by: TimeInterval(secondarySeekForwardSeconds))
        } label: {
            Text(String(localized: "menu.playback.seekForward \(secondarySeekForwardSeconds)"))
        }
        .keyboardShortcut(.rightArrow, modifiers: [.command, .shift])
        .disabled(!hasActiveVideo)
    }

    // MARK: - Navigation

    private var previousVideoButton: some View {
        Button {
            Task {
                await playerService.playPrevious()
            }
        } label: {
            Text(String(localized: "menu.playback.previousVideo"))
        }
        .keyboardShortcut(.leftArrow, modifiers: [.command, .option])
        .disabled(!hasActiveVideo || !state.hasPrevious)
    }

    private var nextVideoButton: some View {
        Button {
            Task {
                await playerService.playNext()
            }
        } label: {
            Text(String(localized: "menu.playback.nextVideo"))
        }
        .keyboardShortcut(.rightArrow, modifiers: [.command, .option])
        .disabled(!hasActiveVideo || !state.hasNext)
    }

    // MARK: - Speed

    private var slowerButton: some View {
        Button {
            cycleSpeedDown()
        } label: {
            Text(String(localized: "menu.playback.slower"))
        }
        .keyboardShortcut("[", modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private var fasterButton: some View {
        Button {
            cycleSpeedUp()
        } label: {
            Text(String(localized: "menu.playback.faster"))
        }
        .keyboardShortcut("]", modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private var resetSpeedButton: some View {
        Button {
            state.rate = .x1
            playerService.currentBackend?.rate = 1.0
        } label: {
            Text(String(localized: "menu.playback.resetSpeed"))
        }
        .keyboardShortcut("0", modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private func cycleSpeedDown() {
        let rates = PlaybackRate.allCases
        guard let currentIndex = rates.firstIndex(of: state.rate) else { return }
        if currentIndex > 0 {
            let newRate = rates[currentIndex - 1]
            state.rate = newRate
            playerService.currentBackend?.rate = Float(newRate.rawValue)
        }
    }

    private func cycleSpeedUp() {
        let rates = PlaybackRate.allCases
        guard let currentIndex = rates.firstIndex(of: state.rate) else { return }
        if currentIndex < rates.count - 1 {
            let newRate = rates[currentIndex + 1]
            state.rate = newRate
            playerService.currentBackend?.rate = Float(newRate.rawValue)
        }
    }

    // MARK: - Volume

    private var volumeUpButton: some View {
        Button {
            let newVolume = min(1.0, state.volume + 0.1)
            state.volume = newVolume
            playerService.currentBackend?.volume = newVolume
        } label: {
            Text(String(localized: "menu.playback.volumeUp"))
        }
        .keyboardShortcut(.upArrow, modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private var volumeDownButton: some View {
        Button {
            let newVolume = max(0.0, state.volume - 0.1)
            state.volume = newVolume
            playerService.currentBackend?.volume = newVolume
        } label: {
            Text(String(localized: "menu.playback.volumeDown"))
        }
        .keyboardShortcut(.downArrow, modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private var muteButton: some View {
        Button {
            state.isMuted.toggle()
            playerService.currentBackend?.isMuted = state.isMuted
        } label: {
            Text(String(localized: "menu.playback.mute"))
        }
        .keyboardShortcut("m", modifiers: [.command, .shift])
        .disabled(!hasActiveVideo)
    }

    // MARK: - Display Modes

    private var pipButton: some View {
        Button {
            if let mpvBackend = playerService.currentBackend as? MPVBackend {
                mpvBackend.togglePiP()
            }
        } label: {
            Text(String(localized: "menu.playback.pip"))
        }
        .keyboardShortcut("i", modifiers: [.command, .shift])
        .disabled(!hasActiveVideo || !state.isPiPPossible || state.currentStream?.isAudioOnly == true)
    }
    
    // MARK: - Close video button
    
    private var closeVideoButton: some View {
        Button {
            closeVideo()
        } label: {
            Text(String(localized: "menu.playback.closeVideo"))
        }
        .keyboardShortcut(".", modifiers: [.command])
        .disabled(!hasActiveVideo)
    }

    private func closeVideo() {
        // Mark as closing to hide tab accessory before dismissal
        state.isClosingVideo = true

        // Clear the queue when closing video
        appEnvironment.queueManager.clearQueue()

        // Reset panel state when closing player
        settingsManager.landscapeDetailsPanelVisible = false
        settingsManager.landscapeDetailsPanelPinned = false

        // Stop player FIRST before dismissing window
        playerService.stop()

        // Then dismiss player window (after backend is stopped)
        navigationCoordinator.isPlayerExpanded = false
    }
}
#endif
