import UIKit

// MARK: - GalleryDismissController

/// Manages interactive vertical drag-to-dismiss with velocity-based decision.
/// Uses UIPanGestureRecognizer attached to the gallery VC's view.
/// Only activates when current page is NOT zoomed (Telegram parity).
final class GalleryDismissController: NSObject, UIGestureRecognizerDelegate {

    var onDragChanged: ((CGFloat) -> Void)?
    var onDismiss: ((CGFloat) -> Void)?
    var onCancel: (() -> Void)?

    /// Set by GalleryViewController — returns true when current page is zoomed.
    var isZoomedCheck: (() -> Bool)?

    private(set) var panGesture: UIPanGestureRecognizer!

    private let dismissThreshold: CGFloat = 100
    private let velocityThreshold: CGFloat = 1000

    // MARK: - Init

    override init() {
        super.init()
        panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        panGesture.minimumNumberOfTouches = 1
        panGesture.maximumNumberOfTouches = 1
        panGesture.delegate = self
    }

    // MARK: - Pan Handler

    @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
        let translation = gesture.translation(in: gesture.view)

        switch gesture.state {
        case .changed:
            onDragChanged?(translation.y)

        case .ended, .cancelled:
            let velocity = gesture.velocity(in: gesture.view).y
            let shouldDismiss = abs(translation.y) > dismissThreshold || abs(velocity) > velocityThreshold
            if shouldDismiss {
                onDismiss?(velocity)
            } else {
                onCancel?()
            }

        default:
            break
        }
    }

    // MARK: - UIGestureRecognizerDelegate

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard let pan = gestureRecognizer as? UIPanGestureRecognizer else { return false }
        // Only begin if vertical velocity dominates and page is not zoomed
        let velocity = pan.velocity(in: pan.view)
        let isVertical = abs(velocity.y) > abs(velocity.x)
        let isNotZoomed = !(isZoomedCheck?() ?? false)
        return isVertical && isNotZoomed
    }

    func gestureRecognizer(
        _ gestureRecognizer: UIGestureRecognizer,
        shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
    ) -> Bool {
        // Don't conflict with paging scroll view's pan
        !(otherGestureRecognizer is UIPanGestureRecognizer)
    }
}
