//
//  YFLDragCardContainer.swift
//  Crush
//
//  Created by AI Assistant on 2024/12/19.
//  Copyright © 2024年 Crush. All rights reserved.
//

import UIKit
import SnapKit

// MARK: - 数据源协议
protocol YFLDragCardContainerDataSource: AnyObject {
    /// 数据源个数
    func numberOfRowsInYFLDragCardContainer(_ container: YFLDragCardContainer) -> Int
    
    /// 显示数据源
    func container(_ container: YFLDragCardContainer, viewForRowsAt index: Int) -> YFLDragCardView
}

// MARK: - 代理协议
protocol YFLDragCardContainerDelegate: AnyObject {
    /// 点击卡片回调
    func container(_ container: YFLDragCardContainer, didSelectRowAt index: Int)
    
    /// 拖到最后一张卡片 YES，空，可继续调用reloadData分页数据
    func container(_ container: YFLDragCardContainer, dataSourceIsEmpty isEmpty: Bool)
    
    /// 当前cardview 是否可以拖拽，默认YES
    func container(_ container: YFLDragCardContainer, canDragForCardView cardView: YFLDragCardView) -> Bool
    
    /// 卡片处于拖拽中回调
    func container(_ container: YFLDragCardContainer, dargingForCardView cardView: YFLDragCardView, direction: ContainerDragDirection, widthRate: Float, heightRate: Float)
    
    /// 询问这次滑动的方向是否生效，控制 v2.6 ld add
    func container(_ container: YFLDragCardContainer, canDragFinishForDirection direction: ContainerDragDirection, forCardView cardView: YFLDragCardView) -> Bool
    
    /// 卡片拖拽结束回调（卡片消失）
    func container(_ container: YFLDragCardContainer, dragDidFinshForDirection direction: ContainerDragDirection, forCardView cardView: YFLDragCardView)
    
    /// 卡片回看 v2.6 添加
    func container(_ container: YFLDragCardContainer, lookingBack direction: ContainerDragDirection, forCardView cardView: YFLDragCardView)
    
    func container(_ container: YFLDragCardContainer, enterSmallCardMode smallCardMode: Bool, forCardView cardView: YFLDragCardView)
}

// MARK: - 主容器类
class YFLDragCardContainer: UIView {
    
    // MARK: - 公开属性
    private(set) var tmpStoreNopeCardView: YFLDragCardView?
    private(set) var smallCardMode: Bool = false
    private(set) var isMoveIng: Bool = false
    
    weak var dataSource: YFLDragCardContainerDataSource?
    weak var delegate: YFLDragCardContainerDelegate?
    
    // MARK: - 私有属性
    private var cards: [YFLDragCardView] = []
    private var direction: ContainerDragDirection = .default
    private var loadedIndex: Int = 0
    private var firstCardFrame: CGRect = .zero
    private var lastCardFrame: CGRect = .zero
    private var cardCenter: CGPoint = .zero
    private var lastCardTransform: CGAffineTransform = .identity
    private var configure: YFLDragConfigure!
    
    // 🔥 根据上下文推测：动画相关视图
    private var likeOrDislikeShowLogoView: UIView!
    private var likeOrDislikeShowImageView: UIImageView!
    private var likeLottieView: UIView! // 🔥 推测为Lottie动画视图
    private var dislikeLottieView: UIView! // �� 推测为Lottie动画视图
    private var superlikeLottieView: UIView! // 🔥 推测为Lottie动画视图
    private var superlikeWordsShowBg: UIImageView!
    private var superlikeWordsLabel: UILabel!
    private var superLikeCountLeft: UILabel!
    
    // v2.8
    private var currentIntialGestureDirection: ContainerDragDirection = .default
    private var canMoveView: Bool = true
    
    // MARK: - 初始化方法
    convenience init(frame: CGRect) {
        self.init(frame: frame, configure: YFLDragCardContainer.setDefaultsConfigures())
    }
    
    init(frame: CGRect, configure: YFLDragConfigure) {
        super.init(frame: frame)
        initDataConfigure(configure)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        initDataConfigure(YFLDragCardContainer.setDefaultsConfigures())
    }
    
    // MARK: - 私有方法
    private static func setDefaultsConfigures() -> YFLDragConfigure {
        let configure = YFLDragConfigure()
        configure.visableCount = 3
        configure.containerEdge = 16.0
        configure.cardEdge = 0.01
        configure.cardCornerRadius = 8.0
        configure.cardCornerBorderWidth = 0.0
        configure.cardBordColor = UIColor.clear
        configure.cardVTopEdage = 0
        configure.cardVBottomEdage = 12
        return configure
    }
    
    private func initDataConfigure(_ configure: YFLDragConfigure) {
        resetInitData()
        initialLikeDislikesShowViews()
        cards = []
        backgroundColor = UIColor.white
        self.configure = configure
    }
    
    private func initialLikeDislikesShowViews() {
        likeOrDislikeShowLogoView = UIView()
        likeOrDislikeShowLogoView.backgroundColor = UIColor.clear
        likeOrDislikeShowLogoView.isUserInteractionEnabled = false
        likeOrDislikeShowLogoView.alpha = 0
        likeOrDislikeShowLogoView.layer.zPosition = 10
        insertSubview(likeOrDislikeShowLogoView, at: 0)
        
        likeOrDislikeShowLogoView.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        // 🔥 根据上下文推测：创建Lottie动画视图
        likeLottieView = createLottieView(animationName: "LottieResources/kuolie_swipe_like")
        dislikeLottieView = createLottieView(animationName: "LottieResources/kuolie_swipe_dislike")
        superlikeLottieView = createLottieView(animationName: "LottieResources/kuolie_superlike")
        
        // 🔥 根据上下文推测：创建超级喜欢文字背景
        superlikeWordsShowBg = UIImageView()
        superlikeWordsShowBg.image = UIImage(named: "kuolie_superlike_words_bg")
        superlikeLottieView.addSubview(superlikeWordsShowBg)
        superlikeWordsShowBg.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.bottom.equalToSuperview().offset(8)
            make.size.equalTo(CGSize(width: 186, height: 32))
        }
        
        // 🔥 根据上下文推测：创建超级喜欢文字标签
        superlikeWordsLabel = UILabel()
        superlikeWordsLabel.textColor = UIColor.white
        superlikeWordsLabel.font = UIFont.systemFont(ofSize: 16) // 🔥 推测字体
        superlikeWordsLabel.text = "SUPER LIKE" // 🔥 推测文字
        superlikeLottieView.addSubview(superlikeWordsLabel)
        superlikeWordsLabel.snp.makeConstraints { make in
            make.center.equalTo(superlikeWordsShowBg)
        }
    }
    
    private func createLottieView(animationName: String) -> UIView {
        // 🔥 根据上下文推测：创建Lottie动画视图
        let view = UIView()
        view.contentMode = .scaleAspectFill
        likeOrDislikeShowLogoView.addSubview(view)
        view.isHidden = true
        view.snp.makeConstraints { make in
            make.center.equalTo(likeOrDislikeShowLogoView)
            make.size.equalTo(CGSize(width: 120, height: 120))
        }
        return view
    }
    
    /// 重置数据(为了二次调用reload)
    private func resetInitData() {
        loadedIndex = 0
        resetCards()
        direction = .default
        isMoveIng = false
    }
    
    /// 清掉所有card view
    private func resetCards() {
        for view in cards {
            view.removeFromSuperview()
        }
        cards.removeAll()
    }
    
    /// 添加子视图
    private func addSubViews() {
        guard let dataSource = dataSource else { return }
        
        let sum = dataSource.numberOfRowsInYFLDragCardContainer(self)
        let preLoadViewCount = min(sum, configure.visableCount)
        
        // 预防越界
        if loadedIndex < sum {
            // 当手势滑动，加载第四个，最多创建4个。不存在内存warning。(手势停止，滑动的view没消失，需要干掉多创建的+1)
            let targetCount = isMoveIng ? preLoadViewCount + 1 : preLoadViewCount
            for i in cards.count..<targetCount {
                let cardView = dataSource.container(self, viewForRowsAt: loadedIndex)
                addAdaptForDragCardView(cardView)
                cards.append(cardView)
                loadedIndex += 1
            }
        }
    }
    
    /// 布局子视图
    private func resetLayoutSubviews() {
        // 动画时允许用户交流，比如触摸 | 时间曲线函数，缓入缓出，中间快
        UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.6, options: [.allowUserInteraction, .curveEaseInOut]) {
            
            if let delegate = self.delegate, let firstCard = self.cards.first {
                delegate.container(self, dargingForCardView: firstCard, direction: self.direction, widthRate: 0, heightRate: 0)
            }
            
            for (i, cardView) in self.cards.enumerated() {
                cardView.transform = .identity
                var frame = self.firstCardFrame
                
                switch i {
                case 0:
                    cardView.frame = frame
                case 1:
                    cardView.transform = CGAffineTransform(scaleX: secondCardScale, y: 1)
                case 2:
                    cardView.transform = CGAffineTransform(scaleX: thirdCardScale, y: 1)
                    if self.lastCardFrame.isEmpty {
                        self.lastCardFrame = frame
                        self.lastCardTransform = cardView.transform
                    }
                default:
                    break
                }
                
                cardView.originTransForm = cardView.transform
            }
        } completion: { finished in
            let isEmpty = self.cards.isEmpty
            self.delegate?.container(self, dataSourceIsEmpty: isEmpty)
        }
    }
    
    private func recordFrame(_ cardView: YFLDragCardView) {
        if loadedIndex >= 3 {
            cardView.frame = lastCardFrame
        } else {
            let frame = cardView.frame
            if firstCardFrame.isEmpty {
                firstCardFrame = frame
                cardCenter = cardView.center
            }
        }
    }
    
    /// 移动卡片
    private func moveIngStatusChange(_ scale: Float) {
        // 如果正在移动，添加第四个
        if !isMoveIng {
            isMoveIng = true
            addSubViews()
        } else {
            // 第四个加载完，立马改变没作用在手势上其他cardview的scale
            let absScale = min(abs(scale), boundaryRation)
            let transFormtxPoor = (secondCardScale - thirdCardScale) / (boundaryRation / absScale)
            let frameYPoor: CGFloat = 0
            
            for (index, cardView) in cards.enumerated() {
                guard index > 0 else { continue }
                
                switch index {
                case 1:
                    let scaleTransform = CGAffineTransform(scaleX: transFormtxPoor + secondCardScale, y: 1)
                    let translateTransform = CGAffineTransform(translationX: 0, y: -frameYPoor)
                    cardView.transform = scaleTransform.concatenating(translateTransform)
                case 2:
                    let scaleTransform = CGAffineTransform(scaleX: transFormtxPoor + thirdCardScale, y: 1)
                    let translateTransform = CGAffineTransform(translationX: 0, y: -frameYPoor)
                    cardView.transform = scaleTransform.concatenating(translateTransform)
                case 3:
                    cardView.transform = lastCardTransform
                default:
                    break
                }
            }
        }
    }
    
    // 手势结束
    private func panGesturemMoveFinishOrCancle(_ cardView: YFLDragCardView, direction: ContainerDragDirection, scale: Float, isDisappear: Bool) {
        if !isDisappear { // 没有消失，恢复原样
            if currentIntialGestureDirection == .left || currentIntialGestureDirection == .right || currentIntialGestureDirection == .default {
                UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.6, options: [.allowUserInteraction, .curveEaseInOut]) {
                    self.subRestoreCardState()
                } completion: { finished in
                }
            } else { // 其他情况下没有动画
                subRestoreCardState()
            }
        } else {
            // v2.6
            if let delegate = delegate {
                if !delegate.container(self, canDragFinishForDirection: direction, forCardView: cardView) {
                    subRestoreCardState()
                    return
                }
            }
            
            delegate?.container(self, dragDidFinshForDirection: self.direction, forCardView: cardView)
            
            if direction == .left {
                tmpStoreNopeCardView = cardView
            }
            
            let flag = direction == .left ? -1 : 2
            let screenWidth = UIScreen.main.bounds.width
            
            UIView.animate(withDuration: 0.5, delay: 0.0, options: [.curveLinear, .allowUserInteraction]) {
                self.isMoveIng = true
                cardView.center = CGPoint(x: CGFloat(flag) * screenWidth, y: CGFloat(flag) * screenWidth / CGFloat(scale) + self.cardCenter.y)
            } completion: { finished in
                self.isMoveIng = false
                cardView.removeFromSuperview()
            }
            
            if let index = cards.firstIndex(of: cardView) {
                cards.remove(at: index)
            }
            isMoveIng = false
            resetLayoutSubviews()
        }
    }
    
    private func subRestoreCardState() {
        // 干掉多创建的第四个.重置标量
        if isMoveIng && cards.count > configure.visableCount {
            if let lastView = cards.last {
                lastView.removeFromSuperview()
                cards.removeLast()
                loadedIndex = lastView.tag
            }
        }
        isMoveIng = false
        resetLayoutSubviews()
    }
    
    // MARK: - 公开方法
    func reloadData() {
        guard let dataSource = dataSource else {
            assertionFailure("check dataSource and dataSource Methods!")
            return
        }
        
        resetInitData()
        addSubViews()
        resetLayoutSubviews()
    }
    
    func getCurrentShowCardView() -> YFLDragCardView? {
        return cards.first
    }
    
    func getCurrentShowCardViewIndex() -> Int {
        return cards.first?.tag ?? 0
    }
    
    /// 手动控制滑动，且不回调代理方法
    func removeCardViewForDirection(_ direction: ContainerDragDirection) {
        guard !isMoveIng else { return }
        
        let screenWidth = UIScreen.main.bounds.width
        var cardCenter = CGPoint.zero
        var flag = 0
        
        guard let currentShowCardView = cards.first else { return }
        
        switch direction {
        case .left:
            cardCenter = CGPoint(x: -screenWidth / 2.0, y: self.cardCenter.y)
            flag = -1
            tmpStoreNopeCardView = currentShowCardView
        case .right:
            cardCenter = CGPoint(x: screenWidth * 1.5, y: self.cardCenter.y)
            flag = 1
        default:
            break
        }
        
        UIView.animate(withDuration: 0.35) {
            self.isMoveIng = true
            let translate = CGAffineTransform(translationX: CGFloat(flag) * 20, y: 0)
            currentShowCardView.transform = translate.rotated(by: CGFloat(flag) * .pi / 4 / 4)
            currentShowCardView.center = cardCenter
        } completion: { finished in
            self.isMoveIng = false
            currentShowCardView.removeFromSuperview()
            if let index = self.cards.firstIndex(of: currentShowCardView) {
                self.cards.remove(at: index)
            }
            self.addSubViews()
            self.resetLayoutSubviews()
        }
    }
    
    /// app控制滑动，且回调滑动Finish代理
    func removeCardViewWithCallDelegateForDirection(_ direction: ContainerDragDirection) {
        guard !isMoveIng else { return }
        
        let screenWidth = UIScreen.main.bounds.width
        var cardCenter = CGPoint.zero
        var flag = 0
        
        guard let currentShowCardView = cards.first else { return }
        
        switch direction {
        case .left:
            cardCenter = CGPoint(x: -screenWidth / 2.0, y: self.cardCenter.y)
            flag = -1
            tmpStoreNopeCardView = currentShowCardView
        case .right:
            cardCenter = CGPoint(x: screenWidth * 1.5, y: self.cardCenter.y)
            flag = 1
        default:
            break
        }
        
        UIView.animate(withDuration: 0.35) {
            let translate = CGAffineTransform(translationX: CGFloat(flag) * 20, y: 0)
            currentShowCardView.transform = translate.rotated(by: CGFloat(flag) * .pi / 4 / 4)
            currentShowCardView.center = cardCenter
        } completion: { finished in
            currentShowCardView.removeFromSuperview()
            if let index = self.cards.firstIndex(of: currentShowCardView) {
                self.cards.remove(at: index)
            }
            self.addSubViews()
            self.resetLayoutSubviews()
        }
        
        delegate?.container(self, dragDidFinshForDirection: direction, forCardView: currentShowCardView)
    }
    
    /// 手动回看 Meet 卡片，将之前存的临时CardView 回看回来
    func addCardView(_ cardView: YFLDragCardView?, fromDirection direction: ContainerDragDirection) {
        guard !isMoveIng else { return }
        
        let targetCardView = cardView ?? tmpStoreNopeCardView
        guard let cardView = targetCardView else { return }
        
        let screenWidth = UIScreen.main.bounds.width
        var cardCenter = CGPoint.zero
        var flag = 0
        
        switch direction {
        case .left:
            cardCenter = CGPoint(x: -screenWidth / 2.0, y: self.cardCenter.y)
            flag = -1
            tmpStoreNopeCardView = cardView
        case .right:
            cardCenter = CGPoint(x: screenWidth * 1.5, y: self.cardCenter.y)
            flag = 1
        default:
            break
        }
        
        cards.insert(cardView, at: 0)
        addSubview(cardView)
        
        cardView.center = cardCenter
        let translate = CGAffineTransform(translationX: CGFloat(flag) * 20, y: 0)
        cardView.transform = translate.rotated(by: CGFloat(flag) * .pi / 4 / 4)
        
        cardCenter = CGPoint(x: self.cardCenter.x, y: self.cardCenter.y)
        
        UIView.animate(withDuration: 0.35) {
            cardView.transform = .identity
            cardView.center = cardCenter
            self.isMoveIng = true
        } completion: { finished in
            self.isMoveIng = false
            self.tmpStoreNopeCardView = nil
        }
        
        delegate?.container(self, lookingBack: direction, forCardView: cardView)
    }
    
    func showNopeLogo(_ show: Bool, widthRate: CGFloat) {
        if widthRate == 0 {
            if !isLottieAnimationPlaying(dislikeLottieView) { // 🔥 推测方法
                UIView.animate(withDuration: 0.25) {
                    self.likeOrDislikeShowLogoView.alpha = 0
                }
            }
            return
        }
        
        if show {
            likeLottieView.isHidden = true
            superlikeLottieView.isHidden = true
            dislikeLottieView.isHidden = false
            likeOrDislikeShowLogoView.isHidden = false
            likeOrDislikeShowLogoView.alpha = widthRate > 0.2 ? 1 : (widthRate / 0.2)
            superLikeCountLeft.isHidden = true
        } else {
            UIView.animate(withDuration: 0.45) {
                self.likeOrDislikeShowLogoView.alpha = 0
            }
        }
    }
    
    func showLikeLogo(_ show: Bool, widthRate: CGFloat) {
        if widthRate == 0 {
            if !isLottieAnimationPlaying(likeLottieView) { // 🔥 推测方法
                UIView.animate(withDuration: 0.25) {
                    self.likeOrDislikeShowLogoView.alpha = 0
                }
            }
            return
        }
        
        if show {
            likeLottieView.isHidden = false
            dislikeLottieView.isHidden = true
            superlikeLottieView.isHidden = true
            likeOrDislikeShowLogoView.alpha = widthRate > 0.2 ? 1 : (widthRate / 0.2)
            superLikeCountLeft.isHidden = true
        } else {
            UIView.animate(withDuration: 0.45) {
                self.likeOrDislikeShowLogoView.alpha = 0
            }
        }
    }
    
    func showNopeLottie() {
        likeLottieView.isHidden = true
        superlikeLottieView.isHidden = true
        dislikeLottieView.isHidden = false
        stopLottieAnimation(dislikeLottieView) // 🔥 推测方法
        likeOrDislikeShowLogoView.alpha = 1
        
        playLottieAnimation(dislikeLottieView) { [weak self] finish in
            if finish {
                self?.likeOrDislikeShowLogoView.alpha = 0
            }
        }
    }
    
    func showLikeLottie() {
        dislikeLottieView.isHidden = true
        superlikeLottieView.isHidden = true
        likeLottieView.isHidden = false
        stopLottieAnimation(likeLottieView) // 🔥 推测方法
        likeOrDislikeShowLogoView.alpha = 1
        
        playLottieAnimation(likeLottieView) { [weak self] finish in
            if finish {
                self?.likeOrDislikeShowLogoView.alpha = 0
            }
        }
    }
    
    func showSuperLikeLottie(complete: @escaping (Bool) -> Void) {
        dislikeLottieView.isHidden = true
        likeLottieView.isHidden = true
        superlikeLottieView.isHidden = false
        stopLottieAnimation(superlikeLottieView) // 🔥 推测方法
        likeOrDislikeShowLogoView.alpha = 1
        
        playLottieAnimation(superlikeLottieView) { [weak self] finish in
            self?.likeOrDislikeShowLogoView.alpha = 0
            complete(finish)
        }
    }
    
    func addAdaptForDragCardView(_ cardView: YFLDragCardView) {
        let y = configure.containerEdge + configure.cardVTopEdage
        let width = frame.size.width - 2 * configure.containerEdge
        let height = frame.size.height - 2 * configure.containerEdge - configure.cardVTopEdage - configure.cardVBottomEdage
        
        cardView.frame = CGRect(x: configure.containerEdge, y: y, width: width, height: height)
        cardView.setConfigure(configure)
        cardView.YFLDragCardViewLayoutSubviews()
        
        recordFrame(cardView)
        cardView.tag = loadedIndex
        
        // 添加拖拽手势
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
        cardView.addGestureRecognizer(panGesture)
        addSubview(cardView)
        sendSubviewToBack(cardView)
    }
    
    func clearTmpStoreNopeCardView() {
        tmpStoreNopeCardView?.removeFromSuperview()
        tmpStoreNopeCardView = nil
    }
    
    func switchAllCardsToSmallCardMode(_ smallMode: Bool) {
        guard smallCardMode != smallMode else { return }
        
        smallCardMode = smallMode
        delegate?.container(self, enterSmallCardMode: smallCardMode, forCardView: getCurrentShowCardView() ?? YFLDragCardView())
    }
    
    // MARK: - 手势处理
    @objc private func handleTapGesture(_ tap: UITapGestureRecognizer) {
        delegate?.container(self, didSelectRowAt: tap.view?.tag ?? 0)
    }
    
    @objc private func handlePanGesture(_ pan: UIPanGestureRecognizer) {
        guard let cardView = pan.view as? YFLDragCardView else { return }
        
        let canEdit = delegate?.container(self, canDragForCardView: cardView) ?? true
        
        if canEdit {
            switch pan.state {
            case .began:
                let point = pan.translation(in: self)
                doVDirectionLogicByPoint(point, forCardView: cardView)
                
            case .changed:
                guard currentIntialGestureDirection != .up && currentIntialGestureDirection != .down else { return }
                
                if let delegate = delegate {
                    // 计算横向滑动比例 >0 向右  <0 向左
                    let horizionSliderRate = Float((pan.view?.center.x ?? 0) - cardCenter.x) / Float(cardCenter.x)
                    let verticalSliderRate = Float((pan.view?.center.y ?? 0) - cardCenter.y) / Float(cardCenter.y)
                    
                    // 正在滑动，需要创建第四个。
                    moveIngStatusChange(horizionSliderRate)
                    
                    if currentIntialGestureDirection == .default {
                        // 再次决定方向
                        let point = pan.translation(in: self)
                        doVDirectionLogicByPoint(point, forCardView: cardView)
                    } else { // 已经确定了方向，且走到这儿，肯定是左右滑
                        // 以自身的左上角为原点；每次移动后，原点都置0；计算的是相对于上一个位置的偏移；
                        let point = pan.translation(in: self)
                        cardView.center = CGPoint(x: (pan.view?.center.x ?? 0) + point.x * 0.5, y: pan.view?.center.y ?? 0)
                        
                        // 当angle为正值时,逆时针旋转坐标系统,反之顺时针旋转坐标系统
                        let rotationAngle = ((pan.view?.center.x ?? 0) - cardCenter.x) / cardCenter.x * (.pi / 4 / 12)
                        cardView.transform = cardView.originTransForm.rotated(by: rotationAngle)
                        pan.setTranslation(.zero, in: self) // 设置坐标原点位上次的坐标
                    }
                    
                    if horizionSliderRate > 0 {
                        direction = .right
                    } else if horizionSliderRate < 0 {
                        direction = .left
                    } else {
                        direction = .default
                    }
                    
                    if currentIntialGestureDirection == .default {
                        currentIntialGestureDirection = direction
                    }
                    
                    delegate.container(self, dargingForCardView: cardView, direction: direction, widthRate: horizionSliderRate, heightRate: verticalSliderRate)
                }
                
            case .ended, .cancelled:
                // 还原card位置，或者消失card
                let horizionSliderRate = Float((pan.view?.center.x ?? 0) - cardCenter.x) / Float(cardCenter.x)
                let moveY = (pan.view?.center.y ?? 0) - cardCenter.y
                let moveX = (pan.view?.center.x ?? 0) - cardCenter.x
                
                panGesturemMoveFinishOrCancle(cardView, direction: direction, scale: Float(moveX / moveY), isDisappear: abs(horizionSliderRate) > boundaryRation)
                
                for per in cards { // 上下滑完后，不隐藏后面的cardView
                    per.isHidden = false
                }
                
                currentIntialGestureDirection = .default
                
            default:
                break
            }
        }
    }
    
    // MARK: - 辅助方法
    private func doVDirectionLogicByPoint(_ point: CGPoint, forCardView cardView: YFLDragCardView) {
        // option2: 不单独处理竖直方向手势
        if point.x == 0 {
            currentIntialGestureDirection = .default
        } else if point.x < 0 {
            currentIntialGestureDirection = .left
        } else {
            currentIntialGestureDirection = .right
        }
    }
    
    // 🔥 根据上下文推测的Lottie动画相关方法
    private func isLottieAnimationPlaying(_ view: UIView) -> Bool {
        // 🔥 推测：检查Lottie动画是否正在播放
        return false
    }
    
    private func stopLottieAnimation(_ view: UIView) {
        // 🔥 推测：停止Lottie动画
    }
    
    private func playLottieAnimation(_ view: UIView, completion: @escaping (Bool) -> Void) {
        // 🔥 推测：播放Lottie动画
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            completion(true)
        }
    }
}
