import AVFoundation
import Foundation
import MediaPlayer
import SwiftUI

public struct PlayPauseButtonV1: View {
    var timeControlStatus: AVPlayer.TimeControlStatus
    var play: () -> Void
    var pause: () -> Void
    var playFromCommandCenter: () -> Void
    var pauseFromCommandCenter: () -> Void
    var nextFromCommandCenter: () -> Void
    var prevFromCommandCenter: () -> Void
    var likeFromCommandCenter: () -> Void
    var unlikeFromCommandCenter: () -> Void

    static var commandCenter: MPRemoteCommandCenter?
    static var commandCenterSetup: Bool = false

    public init(
        timeControlStatus: AVPlayer.TimeControlStatus,
        isLiked: Bool,
        hasNextTrack: Bool,
        hasPrevTrack: Bool,
        play: @escaping () -> Void,
        pause: @escaping () -> Void,
        playFromCommandCenter: @escaping () -> Void,
        pauseFromCommandCenter: @escaping () -> Void,
        nextFromCommandCenter: @escaping () -> Void,
        prevFromCommandCenter: @escaping () -> Void,
        likeFromCommandCenter: @escaping () -> Void,
        unlikeFromCommandCenter: @escaping () -> Void
    ) {
        self.timeControlStatus = timeControlStatus
        self.play = play
        self.pause = pause
        self.playFromCommandCenter = playFromCommandCenter
        self.pauseFromCommandCenter = pauseFromCommandCenter
        self.nextFromCommandCenter = nextFromCommandCenter
        self.prevFromCommandCenter = prevFromCommandCenter
        self.likeFromCommandCenter = likeFromCommandCenter
        self.unlikeFromCommandCenter = unlikeFromCommandCenter

        PlayPauseButtonV1.setupCommandCenter(self)
        PlayPauseButtonV1.commandCenter?.likeCommand.isActive = isLiked
        PlayPauseButtonV1.commandCenter?.nextTrackCommand.isEnabled = hasNextTrack
        PlayPauseButtonV1.commandCenter?.previousTrackCommand.isEnabled = hasPrevTrack
    }

    private static func setupCommandCenter(_ instance: Self) {
        guard !commandCenterSetup else { return }
        commandCenterSetup = true
        let commandCenter = MPRemoteCommandCenter.shared()

        commandCenter.playCommand.addTarget { _ in
            instance.playFromCommandCenter()
            return .success
        }

        commandCenter.pauseCommand.addTarget { _ in
            instance.pauseFromCommandCenter()
            return .success
        }

        commandCenter.nextTrackCommand.addTarget { _ in
            instance.nextFromCommandCenter()
            return .success
        }

        commandCenter.previousTrackCommand.addTarget { _ in
            instance.prevFromCommandCenter()
            return .success
        }

        commandCenter.likeCommand.addTarget { _ in
            instance.likeFromCommandCenter()
            commandCenter.likeCommand.isActive = true
            return .success
        }

        commandCenter.dislikeCommand.addTarget { _ in
            instance.unlikeFromCommandCenter()
            commandCenter.likeCommand.isActive = false
            return .success
        }

        PlayPauseButtonV1.commandCenter = commandCenter
    }

    @State var transparency = 0.0

    public var body: some View {
        let isPlaying = timeControlStatus == .playing
        Button {
            switch timeControlStatus {
            case .paused:
                play()
            case .waitingToPlayAtSpecifiedRate:
                break
            case .playing:
                pause()
            @unknown default:
                break
            }
            transparency = 0.4
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                transparency = 0.0
            }
            UIImpactFeedbackGenerator(style: .light).impactOccurred()
        } label: {
            ZStack {
                Circle()
                    .fill(.ultraThinMaterial)
                    .frame(width: 44, height: 44)
                    .opacity(transparency)
                    .environment(\.colorScheme, .light)
                    .animation(.easeInOut(duration: 0.2), value: transparency)

                if timeControlStatus != .waitingToPlayAtSpecifiedRate {
                    Image(systemName: "play.fill") // TODO: Update to proper asset
                        .foregroundColor(.SemanticV1.iconPrimary)
                        .scaleEffect(isPlaying ? 0 : 1)
                        .opacity(isPlaying ? 0 : 1)
                        .animation(.bouncy(extraBounce: 0.3), value: isPlaying)

                    Image.Icon.pause
                        .foregroundColor(.SemanticV1.iconPrimary)
                        .scaleEffect(isPlaying ? 1 : 0)
                        .opacity(isPlaying ? 1 : 0)
                        .animation(.bouncy(extraBounce: 0.3), value: isPlaying)
                }
            }
            .frame(width: 40, height: 40)
        }
        .foregroundColor(.primary)
        .disabled(timeControlStatus == .waitingToPlayAtSpecifiedRate)
        .overlay {
            ProgressView()
                .progressViewStyle(.circular)
                .opacity(timeControlStatus == .waitingToPlayAtSpecifiedRate ? 1 : 0)
        }
    }
}
