//
//  PQVideoCutingOprateView.swift
//  PQSpeed
//
//  Created by SanW on 2021/5/9.
//  Copyright © 2021 BytesFlow. All rights reserved.
//

import UIKit
import BFCommonKit

class PQVideoCutingOprateView: UIView {
    // 距离左边间隔
    var leftMargin: CGFloat = 0
    // 距离右边间隔
    var rightMargin: CGFloat = 0
    // 距离上边间隔
    var topMargin: CGFloat = 14
    // 距离下边间隔
    var bottomMargin: CGFloat = 20
    /// 上下线条的高度
    var lineHeight: CGFloat = 3.0
    /// 进度宽度
    var progressWidth: CGFloat = 12.0
    // 左右裁剪操作宽度
    var cutingOprateWidth: CGFloat = 15
    // 开始时间 默认 0
    private var cutStartTime: CGFloat = 0
    // 结束时间
    private var cutEndTime: CGFloat = 0
    // 视频总时长
    private var totalDuration: CGFloat = 0
    // 最小裁剪大小 默认 10s
    private var cutMinDuration: CGFloat = 10
    // 最大裁剪大小 默认 40s
    private var cutMaxDuration: CGFloat = 40
    /// 每秒宽度
    private var perSecondWidth: CGFloat = 0
    /// 裁剪总时长
    private var cutTotalTime: CGFloat = 0
    /// 当前滑动的位置
    private var preOriginX: CGFloat = 0
    /// 当前滑动的view
    private var currentPanView: UIView?
    private var progress: CGFloat {
        if progressView.frame.minX >= (rightOprateView.frame.minX - (((progressView.frame.width - 3) / 2) + 3)) {
            return 1
        } else {
            return ((progressView.frame.minX - (leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2))) / perSecondWidth) / (cutEndTime - cutStartTime)
        }
    }

    /// 拖缀结束的回调 type - 1-拖动左边裁剪结束 2--拖动右边裁剪结束 3-进度条拖动结束 4-滑动结束
    var didEndDragging: ((_ type: Int, _ startTime: CGFloat, _ endTime: CGFloat, _ progress: CGFloat) -> Void)?
    /// 裁剪实时回调
    var cutRangeDidChanged: ((_ startTime: CGFloat, _ endTime: CGFloat, _ cutTotalTime: CGFloat) -> Void)?
    /// 进度回调
    var progressDidChanged: ((_ progress: CGFloat) -> Void)?

    lazy var durationLabel: UILabel = {
        let durationLabel = UILabel()
        durationLabel.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        durationLabel.backgroundColor = PQBFConfig.shared.cutDurationColor
        durationLabel.textColor = UIColor.white
        durationLabel.textAlignment = .center
        durationLabel.addShadow()
        return durationLabel
    }()

    lazy var leftOprateView: UIImageView = {
        let leftOprateView = UIImageView(image:UIImage.moduleImage(named: "videomk_crop_left", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate))
        leftOprateView.tintColor = PQBFConfig.shared.cutViewTintColor
        leftOprateView.contentMode = .scaleAspectFill
        leftOprateView.isUserInteractionEnabled = true
        leftOprateView.backgroundColor = PQBFConfig.shared.cutViewStyleColor
        let panGes = UIPanGestureRecognizer(target: self, action: #selector(panGesture(gesture:)))
        panGes.maximumNumberOfTouches = 1
        panGes.minimumNumberOfTouches = 1
        leftOprateView.addGestureRecognizer(panGes)
        return leftOprateView
    }()

    lazy var rightOprateView: UIImageView = {
        let rightOprateView = UIImageView(image:UIImage.moduleImage(named: "videomk_crop_right", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate))
        rightOprateView.tintColor = PQBFConfig.shared.cutViewTintColor
        rightOprateView.contentMode = .scaleAspectFill
        rightOprateView.isUserInteractionEnabled = true
        rightOprateView.backgroundColor = PQBFConfig.shared.cutViewStyleColor
        let panGes = UIPanGestureRecognizer(target: self, action: #selector(panGesture(gesture:)))
        panGes.maximumNumberOfTouches = 1
        panGes.minimumNumberOfTouches = 1
        rightOprateView.addGestureRecognizer(panGes)
        return rightOprateView
    }()

    lazy var topLineView: UIImageView = {
        let topLineView = UIImageView()
        topLineView.backgroundColor = PQBFConfig.shared.cutViewStyleColor
        return topLineView
    }()

    lazy var bottomLineView: UIImageView = {
        let bottomLineView = UIImageView()
        bottomLineView.backgroundColor = PQBFConfig.shared.cutViewStyleColor
        return bottomLineView
    }()

    lazy var progressView: PQCuttingPointView = {
        let progressView = PQCuttingPointView(frame: CGRect(x: 0, y: 0, width: progressWidth, height: frame.height))
        let panGes = UIPanGestureRecognizer(target: self, action: #selector(panGesture(gesture:)))
        panGes.maximumNumberOfTouches = 1
        panGes.minimumNumberOfTouches = 1
        progressView.addGestureRecognizer(panGes)
        return progressView
    }()

    override private init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder _: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    init(frame: CGRect, duration: CGFloat, startTime: CGFloat, endTime: CGFloat, minDuration: CGFloat, maxDuration: CGFloat) {
        super.init(frame: frame)
        isUserInteractionEnabled = true
        clipsToBounds = true
        backgroundColor = UIColor.clear
        totalDuration = duration
        cutStartTime = startTime
        cutEndTime = endTime
        cutMinDuration = minDuration
        cutMaxDuration = maxDuration
        if cutMaxDuration <= 0 || cutMaxDuration > totalDuration {
            cutMaxDuration = totalDuration
        }
        if cutMinDuration <= 0 || (cutMinDuration > totalDuration) {
            cutMinDuration = 7
        }
        if cutEndTime <= 0 {
            cutEndTime = cutStartTime + cutMinDuration
        }
        perSecondWidth = 7
        cutTotalTime = cutEndTime - cutStartTime
        configSubview()
        BFLog(message: "======\(frame),perSecondWidth = \(perSecondWidth),cutMaxDuration = \(cutMaxDuration * perSecondWidth)")
    }

    /// 初始化视图
    /// - Returns: <#description#>
    func configSubview() {
        if leftOprateView.superview == nil {
            addSubview(leftOprateView)
        }
        if rightOprateView.superview == nil {
            addSubview(rightOprateView)
        }
        if topLineView.superview == nil {
            addSubview(topLineView)
        }
        if bottomLineView.superview == nil {
            addSubview(bottomLineView)
        }
        if durationLabel.superview == nil {
            addSubview(durationLabel)
        }
        if progressView.superview == nil {
            addSubview(progressView)
        }
        leftOprateView.frame = CGRect(x: leftMargin + perSecondWidth * cutStartTime, y: topMargin, width: cutingOprateWidth, height: frame.height - topMargin - bottomMargin)
        rightOprateView.frame = CGRect(x: leftOprateView.frame.maxX + perSecondWidth * (cutEndTime - cutStartTime), y: leftOprateView.frame.minY, width: cutingOprateWidth, height: frame.height - topMargin - bottomMargin)
        // 更新子视图布局
        updateSubViewFrame()
    }

    /// 更新子视图布局
    /// - Returns: <#description#>
    func updateSubViewFrame() {
        topLineView.frame = CGRect(x: leftOprateView.frame.maxX, y: leftOprateView.frame.minY, width: rightOprateView.frame.minX - leftOprateView.frame.maxX, height: lineHeight)
        bottomLineView.frame = CGRect(x: topLineView.frame.minX, y: leftOprateView.frame.maxY - lineHeight, width: topLineView.frame.width, height: lineHeight)
        progressView.frame = CGRect(x: leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2), y: 0, width: progressWidth, height: frame.height)
        durationLabel.frame = CGRect(x: topLineView.frame.minX, y: topLineView.frame.maxY, width: topLineView.frame.width, height: bottomLineView.frame.minY - topLineView.frame.maxY)
        durationLabel.text = "\(lround(Double(cutTotalTime)))s"
    }

    /// 更新进度
    /// progress <#progress description#>
    func updateProgress(progress: CGFloat) {
        if currentPanView != nil {
            return
        }
        let width = rightOprateView.frame.minX - leftOprateView.frame.maxX
        var newX = leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2) + progress * width
        BFLog(message: "progress = \(progress),newX = \(newX)")
        if newX.isNaN || newX <= (leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2)) {
            newX = (leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2))
        }
        if newX >= (rightOprateView.frame.minX - (((progressView.frame.width - 3) / 2) + 3)) {
            newX = (rightOprateView.frame.minX - (((progressView.frame.width - 3) / 2) + 3))
        }
        progressView.frame.origin.x = newX
    }

    deinit {
        BFLog(message: "卡点裁剪-裁剪时长视图销毁")
    }
}

extension PQVideoCutingOprateView {
    /// 操作手势
    /// - Parameter ges: <#ges description#>
    /// - Returns: <#description#>
    @objc func panGesture(gesture: UIPanGestureRecognizer) {
        switch gesture.state {
        case .began:
            preOriginX = 0
            currentPanView = gesture.view
        case .changed:
            if currentPanView == leftOprateView || currentPanView == rightOprateView || currentPanView == progressView {
                let point = gesture.translation(in: superview)
                var offsetX = point.x - preOriginX
                preOriginX = point.x
                if currentPanView == leftOprateView {
                    var oprateFrame = leftOprateView.frame
                    oprateFrame.origin.x = oprateFrame.origin.x + offsetX
                    if oprateFrame.origin.x <= leftMargin {
                        offsetX += leftMargin - oprateFrame.origin.x
                        oprateFrame.origin.x = leftMargin
                    }
                    let minLength = rightOprateView.frame.minX - cutingOprateWidth - cutMinDuration * perSecondWidth
                    if oprateFrame.origin.x >= minLength {
                        offsetX -= oprateFrame.origin.x - minLength
                        oprateFrame.origin.x = minLength
                    }
                    let maxLength = rightOprateView.frame.minX - cutingOprateWidth - cutMaxDuration * perSecondWidth
                    if oprateFrame.origin.x <= maxLength {
                        offsetX += maxLength - oprateFrame.origin.x
                        oprateFrame.origin.x = maxLength
                    }
                    let time = offsetX / perSecondWidth
                    cutStartTime = cutStartTime + time
                    leftOprateView.frame = oprateFrame
                } else if currentPanView == rightOprateView {
                    var oprateFrame = rightOprateView.frame
                    oprateFrame.origin.x += offsetX
                    var rightImageMaxX = leftOprateView.frame.maxX + cutMaxDuration * perSecondWidth
                    if rightImageMaxX > frame.width - rightMargin - cutingOprateWidth {
                        rightImageMaxX = frame.width - rightMargin - cutingOprateWidth
                    }
                    if oprateFrame.origin.x >= rightImageMaxX {
                        offsetX -= oprateFrame.origin.x - rightImageMaxX
                        oprateFrame.origin.x = rightImageMaxX
                    }
                    let rightImageMinX = leftOprateView.frame.maxX + cutMinDuration * perSecondWidth
                    if oprateFrame.origin.x <= rightImageMinX {
                        offsetX += rightImageMinX - oprateFrame.origin.x
                        oprateFrame.origin.x = rightImageMinX
                    }
                    let time = offsetX / perSecondWidth
                    cutEndTime = cutEndTime + time
                    rightOprateView.frame = oprateFrame
                } else if currentPanView == progressView {
                    var progressFrame = progressView.frame
                    BFLog(message: "progressFrame = \(progressFrame),offsetX = \(offsetX)")
                    progressFrame.origin.x += offsetX
                    if progressFrame.origin.x <= (leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2)) {
                        progressFrame.origin.x = (leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2))
                    }
                    if progressFrame.origin.x >= (rightOprateView.frame.minX - (((progressView.frame.width - 3) / 2) + 3)) {
                        progressFrame.origin.x = (rightOprateView.frame.minX - (((progressView.frame.width - 3) / 2) + 3))
                    }
                    progressView.frame = progressFrame
                    BFLog(message: "======\(progressView.frame.minX - (leftOprateView.frame.maxX - ((progressView.frame.width - 3) / 2)))")
                    if progressDidChanged != nil {
                        progressDidChanged!(progress)
                    }
                }
                if currentPanView != progressView {
                    cutTotalTime = cutEndTime - cutStartTime
                    // 更新子视图布局
                    updateSubViewFrame()
                    if cutRangeDidChanged != nil {
                        BFLog(message: "cutStartTime = \(cutStartTime),cutEndTime = \(cutEndTime)")
                        cutRangeDidChanged!(cutStartTime, cutEndTime, cutTotalTime)
                    }
                }
            }
        case .ended:
            if currentPanView == leftOprateView || currentPanView == rightOprateView || currentPanView == progressView {
                if didEndDragging != nil {
                    didEndDragging!(currentPanView == leftOprateView ? 1 : (currentPanView == rightOprateView ? 2 : 3), cutStartTime, cutEndTime, progress)
                }
            }
            currentPanView = nil
        default:
            break
        }
    }
}
