//
//  MacVideoPlayerView.swift
//  Pods
//
//  Created by kintan on 2018/10/31.
//
#if !canImport(UIKit)

import AppKit
import AVFoundation

public extension NSPasteboard.PasteboardType {
    static let nsURL = NSPasteboard.PasteboardType("NSURL")
    static let nsFilenames = NSPasteboard.PasteboardType("NSFilenamesPboardType")
}

public extension NSDraggingInfo {
    @MainActor
    func getUrl() -> URL? {
        guard let types = draggingPasteboard.types else { return nil }

        if types.contains(.nsFilenames) {
            guard let paths = draggingPasteboard.propertyList(forType: .nsFilenames) as? [String] else { return nil }
            let urls = paths.map { URL(fileURLWithPath: $0) }
            return urls.first
        }
        return nil
    }
}

open class MacVideoPlayerView: VideoPlayerView {
    override open func customizeUIComponents() {
        super.customizeUIComponents()
        registerForDraggedTypes([.nsFilenames, .nsURL, .string])
    }

    override open func player(layer: KSPlayerLayer, state: KSPlayerState) {
        super.player(layer: layer, state: state)
        if state == .readyToPlay {
            let naturalSize = layer.player.naturalSize
            window?.aspectRatio = naturalSize
        }
    }
}

extension MacVideoPlayerView {
    override open func updateTrackingAreas() {
        for trackingArea in trackingAreas {
            removeTrackingArea(trackingArea)
        }
        let trackingArea = NSTrackingArea(rect: bounds, options: [.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow], owner: self, userInfo: nil)
        addTrackingArea(trackingArea)
    }

    override open func mouseEntered(with _: NSEvent) {
        isMaskShow = true
    }

    override open func mouseMoved(with _: NSEvent) {
        isMaskShow = true
    }

    override open func mouseExited(with _: NSEvent) {
        isMaskShow = false
    }

    override open func scrollWheel(with event: NSEvent) {
        if event.phase.contains(.began) {
            if event.scrollingDeltaX != 0 {
                scrollDirection = .horizontal
                tmpPanValue = toolBar.timeSlider.value
            } else if event.scrollingDeltaY != 0 {
                scrollDirection = .vertical
                tmpPanValue = 1
            }
        } else if event.phase.contains(.changed) {
            let delta = scrollDirection == .horizontal ? event.scrollingDeltaX : event.scrollingDeltaY
            if scrollDirection == .horizontal {
                tmpPanValue += Float(delta / 10000) * Float(totalTime)
                showSeekToView(second: Double(tmpPanValue), isAdd: delta > 0)
            } else {
                if KSOptions.enableVolumeGestures {
                    tmpPanValue -= Float(delta / 1000)
                    tmpPanValue = max(min(tmpPanValue, 1), 0)
                }
            }
        } else if event.phase.contains(.ended) {
            if scrollDirection == .horizontal {
                slider(value: Double(tmpPanValue), event: .touchUpInside)
                hideSeekToView()
            } else {
                if KSOptions.enableVolumeGestures {
                    playerLayer?.player.playbackVolume = tmpPanValue
                }
            }
        }
    }

    override open var acceptsFirstResponder: Bool {
        true
    }

    override open func keyDown(with event: NSEvent) {
        if let specialKey = event.specialKey {
            if specialKey == .rightArrow {
                slider(value: Double(toolBar.timeSlider.value) + 0.01 * totalTime, event: .touchUpInside)
            } else if specialKey == .leftArrow {
                slider(value: Double(toolBar.timeSlider.value) - 0.01 * totalTime, event: .touchUpInside)
            }
        } else if let character = event.characters?.first {
            if character == " " {
                onButtonPressed(toolBar.playButton)
            }
        }
    }

    override open func draggingEntered(_: NSDraggingInfo) -> NSDragOperation {
        .copy
    }

    override open func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        if let url = sender.getUrl() {
            if url.isMovie || url.isAudio {
                set(resource: KSPlayerResource(url: url, options: KSOptions()))
                return true
            } else {
                srtControl.selectedSubtitleInfo = URLSubtitleInfo(url: url)
                return true
            }
        }
        return false
    }
}

class UIActivityIndicatorView: UIView {
    private let loadingView = NSView()
    private let progressLabel = UILabel()
    public var progress: Double = 0 {
        didSet {
            print("new progress: \(progress)")
            progressLabel.stringValue = "\(Int(progress * 100))%"
        }
    }

    override init(frame frameRect: CGRect) {
        super.init(frame: frameRect)
        wantsLayer = true
        backingLayer?.backgroundColor = UIColor(white: 0, alpha: 0.2).cgColor
        setupLoadingView()
    }

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

    private func setupLoadingView() {
        loadingView.wantsLayer = true
        addSubview(loadingView)
        let imageView = NSImageView()
        imageView.image = KSOptions.image(named: "loading")
        loadingView.addSubview(imageView)
        imageView.imageScaling = .scaleAxesIndependently
        imageView.translatesAutoresizingMaskIntoConstraints = false
        loadingView.translatesAutoresizingMaskIntoConstraints = false
        translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            widthAnchor.constraint(equalToConstant: 110),
            heightAnchor.constraint(equalToConstant: 110),
            loadingView.centerXAnchor.constraint(equalTo: centerXAnchor),
            loadingView.centerYAnchor.constraint(equalTo: centerYAnchor),
            loadingView.widthAnchor.constraint(equalTo: widthAnchor),
            loadingView.heightAnchor.constraint(equalTo: heightAnchor),
            imageView.bottomAnchor.constraint(equalTo: loadingView.bottomAnchor),
            imageView.leadingAnchor.constraint(equalTo: loadingView.leadingAnchor),
            imageView.heightAnchor.constraint(equalTo: widthAnchor),
            imageView.widthAnchor.constraint(equalTo: heightAnchor),
        ])
        progressLabel.alignment = .center
        progressLabel.font = NSFont.systemFont(ofSize: 18, weight: .medium)
        addSubview(progressLabel)
        progressLabel.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            progressLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
            progressLabel.topAnchor.constraint(equalTo: loadingView.bottomAnchor, constant: 20),
            progressLabel.widthAnchor.constraint(equalToConstant: 100),
            progressLabel.heightAnchor.constraint(equalToConstant: 22),
        ])
        startAnimating()
    }
}

extension UIActivityIndicatorView: LoadingIndector {
    func startAnimating() {
        loadingView.backingLayer?.position = CGPoint(x: loadingView.layer!.frame.midX, y: loadingView.layer!.frame.midY)
        loadingView.backingLayer?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
        rotationAnimation.duration = 1.0
        rotationAnimation.repeatCount = MAXFLOAT
        rotationAnimation.fromValue = 0.0
        rotationAnimation.toValue = Float.pi * -2
        loadingView.backingLayer?.add(rotationAnimation, forKey: "loading")
    }

    func stopAnimating() {
        loadingView.backingLayer?.removeAnimation(forKey: "loading")
    }
}
#endif
