//
//  LNVideoPreviewCell.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/11.
//

import Foundation
import UIKit
import SnapKit


protocol LNVideoPreviewCellDelegate: AnyObject {
    func onVideoPreviewCellDragToDismiss(cell: LNVideoPreviewCell)
}


class LNVideoPreviewCell: UICollectionViewCell {
    private let videoPlayer = LNVideoPlayerView()
    private let indicator = UIActivityIndicatorView(style: .large)
    
    private var panGesture: UIPanGestureRecognizer?
    private var touchBeginPoint: CGPoint = .zero
    private var lastMove: CGPoint = .zero
    private let dragScaleMin = 0.4
    private let dragScaleOffsetY = UIScreen.main.bounds.height * 0.5
    private let dragAlphaOffsetY = 150.0
    
    private var curUrl: String?
    
    weak var delegate: LNVideoPreviewCellDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
        setupGesture()
    }
    
    func update(url: String, coverUrl: String?) {
        indicator.startAnimating()
        videoPlayer.loadVideo(url, coverUrl: coverUrl)
    }
    
    func stop() {
        videoPlayer.stop()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNVideoPreviewCell {
    @objc
    private func handlePan(_ gesture: UIPanGestureRecognizer) {
        let position = gesture.translation(in: self)
        
        switch gesture.state {
        case .began:
            touchBeginPoint = position
            break
        case .changed:
            lastMove = gesture.velocity(in: self)
            var frame = contentView.frame
            frame.origin.y = position.y - touchBeginPoint.y
            frame.origin.x = position.x - touchBeginPoint.x
            contentView.frame = frame
            
            let progress = (frame.origin.y / dragAlphaOffsetY).bounded(min: 0, max: 1.0)
            superview?.backgroundColor = .black.withAlphaComponent(1 - progress)
            
            let scale = 1 - (frame.origin.y / dragScaleOffsetY).bounded(min: 0, max: 1.0) * (1 - dragScaleMin)
            videoPlayer.transform = .init(scaleX: scale, y: scale)
            break
        default:
            if lastMove.y > 0 {
                var frame = contentView.frame
                frame.origin.y = bounds.height
                
                UIView.animate(withDuration: 0.25) { [weak self] in
                    guard let self else { return }
                    contentView.frame = frame
                    
                    superview?.backgroundColor = .clear
                } completion: { [weak self] _ in
                    guard let self else { return }
                    delegate?.onVideoPreviewCellDragToDismiss(cell: self)
                }
            } else {
                UIView.animate(withDuration: 0.25) { [weak self] in
                    guard let self else { return }
                    contentView.frame = bounds
                    
                    superview?.backgroundColor = .black
                    videoPlayer.transform = .identity
                }
            }
            break
        }
    }
}

extension LNVideoPreviewCell: LNVideoPlayerViewDelegate {
    func onVideoDidLoad(view: LNVideoPlayerView) {
        indicator.stopAnimating()
        videoPlayer.start()
    }
}

extension LNVideoPreviewCell: UIGestureRecognizerDelegate {
    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard let pan = gestureRecognizer as? UIPanGestureRecognizer else {
            return true
        }
        
        let velocity = pan.velocity(in: self)
        return abs(velocity.y) > abs(velocity.x)
    }
}

extension LNVideoPreviewCell {
    private func setupViews() {
        videoPlayer.showCover = false
        videoPlayer.loop = true
        videoPlayer.delegate = self
        videoPlayer.backgroundColor = .clear
        videoPlayer.playButtonSize = 56
        contentView.addSubview(videoPlayer)
        videoPlayer.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.verticalEdges.equalToSuperview()
        }
    }
    
    private func setupGesture() {
        let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        pan.delegate = self
        pan.isEnabled = true
        pan.maximumNumberOfTouches = 1
        contentView.addGestureRecognizer(pan)
        panGesture = pan
    }
}
