//
//  BrightnessVolume.swift
//  KSPlayer
//
//  Created by kintan on 2017/11/3.
//
#if canImport(UIKit)
import UIKit

@MainActor
open class BrightnessVolume {
    private var brightnessObservation: NSKeyValueObservation?
    public static let shared = BrightnessVolume()
    public var progressView: BrightnessVolumeViewProtocol & UIView = ProgressView()
    init() {
        #if !os(tvOS) && !os(xrOS)
        brightnessObservation = UIScreen.main.observe(\.brightness, options: .new) { [weak self] _, change in
            guard KSOptions.enableBrightnessGestures else { return }
            if let self, let value = change.newValue {
                self.appearView()
                self.progressView.setProgress(Float(value), type: 0)
            }
        }
        #endif
        let name = NSNotification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification")
        NotificationCenter.default.addObserver(self, selector: #selector(volumeIsChanged(notification:)), name: name, object: nil)
        progressView.alpha = 0.0
    }

    public func move(to view: UIView) {
        progressView.move(to: view)
    }

    @objc private func volumeIsChanged(notification: NSNotification) {
        guard KSOptions.enableVolumeGestures else { return }
        if let changeReason = notification.userInfo?["AVSystemController_AudioVolumeChangeReasonNotificationParameter"] as? String, changeReason == "ExplicitVolumeChange" {
            if let volume = notification.userInfo?["AVSystemController_AudioVolumeNotificationParameter"] as? CGFloat {
                appearView()
                progressView.setProgress(Float(volume), type: 1)
            }
        }
    }

    private func appearView() {
        if progressView.alpha == 0.0 {
            progressView.alpha = 1.0
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) { [weak self] () in
                self?.disAppearView()
            }
        }
    }

    private func disAppearView() {
        if progressView.alpha == 1.0 {
            UIView.animate(withDuration: 0.8) { [weak self] () in
                self?.progressView.alpha = 0.0
            }
        }
    }

    deinit {
        brightnessObservation?.invalidate()
    }
}

public protocol BrightnessVolumeViewProtocol {
    // type: 0 brightness type: 1 volume
    func setProgress(_ progress: Float, type: UInt)
    func move(to view: UIView)
}

private final class SystemView: UIVisualEffectView {
    private let stackView = UIStackView()
    private let imageView = UIImageView()
    private let titleLabel = UILabel()
    private lazy var brightnessImage = UIImage(systemName: "sun.max")
    private lazy var volumeImage = UIImage(systemName: "speaker.wave.3.fill")
    private convenience init() {
        self.init(effect: UIBlurEffect(style: .extraLight))
        clipsToBounds = true
        cornerRadius = 10
        imageView.image = brightnessImage
        contentView.addSubview(imageView)
        titleLabel.font = .systemFont(ofSize: 16)
        titleLabel.textColor = UIColor(red: 0.25, green: 0.22, blue: 0.21, alpha: 1)
        titleLabel.textAlignment = .center
        titleLabel.text = "亮度"
        contentView.addSubview(titleLabel)
        let longView = UIView()
        longView.backgroundColor = titleLabel.textColor
        contentView.addSubview(longView)
        stackView.alignment = .center
        stackView.distribution = .fillEqually
        stackView.axis = .horizontal
        stackView.spacing = 1
        longView.addSubview(stackView)
        for _ in 0 ..< 16 {
            let tipView = UIView()
            tipView.backgroundColor = .white
            stackView.addArrangedSubview(tipView)
            tipView.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                tipView.heightAnchor.constraint(equalTo: stackView.heightAnchor),
            ])
        }
        translatesAutoresizingMaskIntoConstraints = false
        imageView.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        longView.translatesAutoresizingMaskIntoConstraints = false
        stackView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            imageView.widthAnchor.constraint(equalToConstant: 79),
            imageView.heightAnchor.constraint(equalToConstant: 76),
            imageView.centerYAnchor.constraint(equalTo: centerYAnchor),
            imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
            titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 5),
            titleLabel.widthAnchor.constraint(equalTo: widthAnchor),
            titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
            titleLabel.heightAnchor.constraint(equalToConstant: 30),
            longView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 13),
            longView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -13),
            longView.heightAnchor.constraint(equalToConstant: 7),
            longView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            stackView.leadingAnchor.constraint(equalTo: longView.leadingAnchor, constant: 1),
            stackView.trailingAnchor.constraint(equalTo: longView.trailingAnchor, constant: -1),
            stackView.topAnchor.constraint(equalTo: longView.topAnchor, constant: 1),
            stackView.bottomAnchor.constraint(equalTo: longView.bottomAnchor, constant: -1),
        ])
    }
}

extension SystemView: BrightnessVolumeViewProtocol {
    public func setProgress(_ progress: Float, type: UInt) {
        if type == 0 {
            imageView.image = brightnessImage
            titleLabel.text = NSLocalizedString("brightness", comment: "")
        } else {
            imageView.image = volumeImage
            titleLabel.text = NSLocalizedString("volume", comment: "")
        }
        let level = Int(progress * Float(stackView.arrangedSubviews.count))
        for i in 0 ..< stackView.arrangedSubviews.count {
            let view = stackView.arrangedSubviews[i]
            if i <= level, level > 0 {
                view.alpha = 1
            } else {
                view.alpha = 0
            }
        }
    }

    public func move(to view: UIView) {
        if superview != view {
            removeFromSuperview()
            view.addSubview(self)
            translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                centerXAnchor.constraint(equalTo: view.centerXAnchor),
                centerYAnchor.constraint(equalTo: view.centerYAnchor),
                heightAnchor.constraint(equalToConstant: 155),
                widthAnchor.constraint(equalToConstant: 155),
            ])
        }
    }
}

private final class ProgressView: UIView {
    private lazy var brightnessImage = UIImage(systemName: "sun.max")
    private lazy var volumeImage = UIImage(systemName: "speaker.fill")
    private lazy var brightnessOffImage = UIImage(systemName: "sun.min")
    private lazy var volumeOffImage = UIImage(systemName: "speaker.slash.fill")
    private let progressView = UIProgressView()
    private let imageView = UIImageView()

    override init(frame _: CGRect) {
        super.init(frame: .zero)
        addSubview(progressView)
        addSubview(imageView)
        progressView.progressTintColor = UIColor.white
        progressView.trackTintColor = UIColor.white.withAlphaComponent(0.5)
        progressView.translatesAutoresizingMaskIntoConstraints = false
        progressView.centerRotate(byDegrees: -90)
        imageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            progressView.widthAnchor.constraint(equalToConstant: 115),
            progressView.heightAnchor.constraint(equalToConstant: 2),
            progressView.centerXAnchor.constraint(equalTo: centerXAnchor),
            progressView.topAnchor.constraint(equalTo: topAnchor, constant: 57),
            imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: trailingAnchor),
            imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
        ])
    }

    @available(*, unavailable)
    required init?(coder _: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension ProgressView: BrightnessVolumeViewProtocol {
    func setProgress(_ progress: Float, type: UInt) {
        progressView.setProgress(progress, animated: false)
        if progress == 0 {
            imageView.image = type == 0 ? brightnessOffImage : volumeOffImage
        } else {
            imageView.image = type == 0 ? brightnessImage : volumeImage
        }
    }

    func move(to view: UIView) {
        if superview != view {
            removeFromSuperview()
            view.addSubview(self)
            translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                trailingAnchor.constraint(equalTo: view.safeTrailingAnchor, constant: -10),
                centerYAnchor.constraint(equalTo: view.centerYAnchor),
                heightAnchor.constraint(equalToConstant: 150),
                widthAnchor.constraint(equalToConstant: 24),
            ])
        }
    }
}
#endif
