//
//  UICollectionView+Ext.swift
//  PQSpeed
//
//  Created by SanW on 2020/6/6.
//  Copyright © 2020 BytesFlow. All rights reserved.
//

import KingfisherWebP
import UIKit

// MARK: - UIView的分类扩展

/// UIView的分类扩展
public extension UIView {
    func addCorner(roundingCorners: UIRectCorner = .allCorners, corner: CGFloat = 10) {
        if roundingCorners == .allCorners {
            layer.cornerRadius = corner
            layer.masksToBounds = true
        } else {
            let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: roundingCorners, cornerRadii: CGSize(width: corner, height: corner))
            let cornerLayer = CAShapeLayer()
            cornerLayer.frame = bounds
            cornerLayer.path = path.cgPath
            layer.mask = cornerLayer
        }
    }

    /// 添加阴影
    /// - Parameters:
    ///   - color: <#color description#>
    ///   - offset: <#offset description#>
    /// - Returns: <#description#>
    func addShadowLayer(isAll: Bool = false, color: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5), offset: CGSize = CGSize(width: 1, height: 1)) {
        layer.shadowColor = color.cgColor
        layer.shadowOffset = offset
        layer.shadowRadius = 0.5
        layer.shadowOpacity = 1.0
        if isAll {
            layer.shadowColor = color.cgColor
            layer.shadowOffset = CGSize.zero
            // 设置偏移量为0,四周都有阴影
            layer.shadowRadius = 0.5 // 阴影半径
            layer.shadowOpacity = 0.3 // 阴影透明度
            layer.masksToBounds = false
            layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath
        }
    }

    /// 添加虚线条
    func addBorderToLayer(frame: CGRect? = nil) {
        // 线条颜色
        let borderLayer: CAShapeLayer = CAShapeLayer()
        borderLayer.strokeColor = UIColor.hexColor(hexadecimal: "#FFFFFF").cgColor
        borderLayer.fillColor = nil
        borderLayer.path = UIBezierPath(rect: frame == nil ? bounds : frame!).cgPath
        borderLayer.frame = bounds
        borderLayer.lineWidth = 2.0
        borderLayer.lineCap = .round
        // 第一位是 线条长度   第二位是间距 nil时为实线
        borderLayer.lineDashPattern = [5, 5]
        layer.addSublayer(borderLayer)
    }

    func animateZoom() {
        transform = CGAffineTransform(scaleX: 0.4, y: 0.4)
        UIView.animate(withDuration: 0.5, animations: {
            self.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
        }) { _ in
            UIView.animate(withDuration: 0.5, animations: {
                self.transform = .identity
            }) { _ in
            }
        }
    }

    /// 添加抖动功能
    /// - Parameters:
    ///   - fromValue: <#fromValue description#>
    ///   - toValue: <#toValue description#>
    ///   - duration: <#duration description#>
    ///   - repeatCount: <#repeatCount description#>
    /// - Returns: <#description#>
    func shakeAnimation(_ fromValue: Float, _ toValue: Float, _ duration: Float, _: Float) {
        layer.removeAllAnimations()
        let shake = CABasicAnimation(keyPath: "transform.rotation.z")
        shake.fromValue = fromValue
        shake.toValue = toValue
        shake.duration = CFTimeInterval(duration)
        shake.autoreverses = true
        shake.repeatCount = Float(CGFloat.greatestFiniteMagnitude)
        shake.isRemovedOnCompletion = false
        layer.add(shake, forKey: "imageView")
        // 增加锚点
        layer.anchorPoint = CGPoint(x: 0.5, y: 1)
    }

    /// 添加心跳动画
    /// - Parameters:
    ///   - duration: <#duration description#>
    ///   - isRepeat: <#isRepeat description#>
    ///   - multiple: <#multiple description#>
    /// - Returns: <#description#>
    func heartbeatAnimate(duration: TimeInterval, isRepeat: Bool, multiple: CGFloat) {
        UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
            self.transform = CGAffineTransform(scaleX: 1.0 + multiple, y: 1.0 + multiple)
        }) { _ in
            UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
                self.transform = .identity
            }) { _ in
                UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
                    self.transform = CGAffineTransform(scaleX: 1.0 + multiple * 2, y: 1.0 + multiple * 2)
                }) { _ in
                    UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
                        self.transform = .identity
                    }) { _ in
                        if isRepeat {
                            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.3) {
                                self.heartbeatAnimate(duration: duration, isRepeat: isRepeat, multiple: multiple)
                            }
                        }
                    }
                }
            }
        }
    }

    /// 活动心跳动画
    /// - Returns: <#description#>
    func activityHeartbeatAnimate() {
        layer.removeAllAnimations()
        UIView.animateKeyframes(withDuration: 0.45, delay: 0, options: .allowUserInteraction, animations: {
            self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
        }) { _ in
            UIView.animateKeyframes(withDuration: 0.45, delay: 0, options: .allowUserInteraction, animations: {
                self.transform = .identity
            }) { _ in
                self.activityHeartbeatAnimate()
            }
        }
    }

    /// 活动心跳动画
    /// - Returns: <#description#>
    func heartbeatAnimate() {
        layer.removeAllAnimations()
        UIView.animateKeyframes(withDuration: 1, delay: 0, options: .allowUserInteraction, animations: {
            self.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        }) { isFinished in
            UIView.animateKeyframes(withDuration: 1, delay: 0, options: .allowUserInteraction, animations: {
                self.transform = .identity
            }) { isFinished in
                if isFinished {
                    self.heartbeatAnimate()
                }
            }
        }
    }

    func addScaleBasicAnimation() {
        let animation = CABasicAnimation(keyPath: "transform.scale")
        animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
        animation.duration = 0.5
        animation.repeatCount = 1000
        animation.autoreverses = true
        animation.fromValue = 0.8
        animation.toValue = 1.1
        layer.add(animation, forKey: nil)
    }

    func addScaleYBasicAnimation() {
        let animation = CAKeyframeAnimation(keyPath: "transform.translation.y")
        animation.duration = 0.5
        animation.repeatCount = 100
        animation.isRemovedOnCompletion = true
        //        animation.
        animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
        layer.add(animation, forKey: nil)
        //            CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
        //            CGFloat duration = 1.f;
        //            CGFloat height = 7.f;
        //            CGFloat currentY = self.animationView.transform.ty;
        //            animation.duration = duration;
        //            animation.values = @[@(currentY),@(currentY - height/4),@(currentY - height/4*2),@(currentY - height/4*3),@(currentY - height),@(currentY - height/ 4*3),@(currentY - height/4*2),@(currentY - height/4),@(currentY)];
        //            animation.keyTimes = @[ @(0), @(0.025), @(0.085), @(0.2), @(0.5), @(0.8), @(0.915), @(0.975), @(1) ];
        //            animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        //            animation.repeatCount = HUGE_VALF;
        //            [self.animationView.layer addAnimation:animation forKey:@"kViewShakerAnimationKey"];
        //        }
    }

    /// 将view生成一张图片
    /// - Returns: <#description#>
    func graphicsGetImage() -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(frame.size, true, 0.0)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }

    /// 动画显示View
    /// - Returns: <#description#>
    func showViewAnimate(duration: TimeInterval = 0.3, completion: ((Bool) -> Void)? = nil) {
        UIView.animate(withDuration: duration, animations: { [weak self] in
            self?.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - self!.frame.height, width: self!.frame.width, height: self!.frame.height)
        }) { isFinished in
            if completion != nil {
                completion!(isFinished)
            }
        }
    }

    /// 动画隐藏view
    /// - Returns: <#description#>
    func dismissViewAnimate(duration: TimeInterval = 0.3, completion: ((Bool) -> Void)? = nil) {
        UIView.animate(withDuration: duration, animations: { [weak self] in
            self?.frame = CGRect(x: 0, y: UIScreen.main.bounds.height, width: self!.frame.width, height: self!.frame.height)
        }) { isFinished in
            if completion != nil {
                completion!(isFinished)
            }
        }
    }

    /// add  by ak 添加虚线框
    /// - Parameter color: 框色
    /// - Parameter lineWidth: 框宽
    func addBorderToLayer(color: CGColor, lineWidth: CGFloat) {
        let border = CAShapeLayer()

        //  线条颜色
        border.strokeColor = color
        border.fillColor = nil

        border.path = UIBezierPath(rect: bounds).cgPath

        border.frame = bounds
        border.lineWidth = lineWidth
        border.lineCap = .square

        //  第一位是 线条长度   第二位是间距 nil时为实线
        border.lineDashPattern = [9, 4]
        layer.addSublayer(border)
    }
}

// MARK: - UICollectionView的分类扩展

/// UICollectionView的分类扩展
public extension UICollectionView {
    /// 获取当前cell
    /// - Returns: <#description#>
    func visibleCell() -> UICollectionViewCell? {
        let visibleRect = CGRect(origin: contentOffset, size: bounds.size)
        let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
        guard let visibleIndexPath = indexPathForItem(at: visiblePoint) else { return nil }
        return cellForItem(at: visibleIndexPath)
    }

    func indexPathsForElements(in rect: CGRect) -> [IndexPath] {
        let allLayoutAttributes = collectionViewLayout.layoutAttributesForElements(in: rect)!
        return allLayoutAttributes.map { $0.indexPath }
    }
}

// MARK: - UITabBar的分类扩展

/// UITabBar的分类扩展
public extension UITabBar {
    /// 展示小红点
    /// - Parameter index: <#index description#>
    /// - Returns: <#description#>
    func showPoint(index: Int) {
        let pointW: CGFloat = 8
        let pointView = UIView()
        pointView.tag = 11111 + index
        pointView.layer.cornerRadius = pointW / 2
        pointView.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
        let percentX: CGFloat = CGFloat(Double(index) + 0.7) / CGFloat(items?.count ?? 1)
        let pointX = ceil(percentX * frame.width)
        let pointY = ceil(0.1 * frame.height)
        pointView.frame = CGRect(x: pointX, y: pointY, width: pointW, height: pointW)
        addSubview(pointView)
    }

    /// 移除小红点
    /// - Parameter index: <#index description#>
    /// - Returns: <#description#>
    func removePoint(index: Int) {
        for item in subviews {
            if item.tag == 11111 + index {
                item.removeFromSuperview()
            }
        }
    }

    /// 展示创作视频引导
    /// - Parameter index: <#index description#>
    /// - Returns: <#description#>
    func showVideoMakeRemindView() {
        let isOldUploadClick: String? = getUserDefaults(key: cIsUploadClick) as? String
        let isUploadClick: String? = getUserDefaultsForJson(key: cIsUploadClick) as? String
        let isVerticalSlip: String? = getUserDefaults(key: cIsVerticalSlip) as? String
        if isOldUploadClick == nil && isVerticalSlip != nil && isVerticalSlip == "1", isUploadClick == nil || isUploadClick?.count ?? 0 <= 0 || isUploadClick != "2" {
            let width: CGFloat = 275 // 275
            let height: CGFloat = 107 // 107
            let videoMakeRemindBtn = UIButton(frame: CGRect(x: 0, y: -height + 5, width: width, height: height))
            videoMakeRemindBtn.tag = cVideoMakeRemindTag
            videoMakeRemindBtn.setBackgroundImage(UIImage(named: "videomk_guide"), for: .normal)
            addSubview(videoMakeRemindBtn)
            videoMakeRemindBtn.center.x = center.x
            videoMakeRemindBtn.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
            videoMakeRemindBtn.addScaleBasicAnimation()
            if isUploadClick == "1" {
                saveUserDefaultsToJson(key: cIsUploadClick, value: "2")
            } else {
                saveUserDefaultsToJson(key: cIsUploadClick, value: "1")
            }
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) { [weak self] in
                self?.removeVideoMakeRemindView()
            }
        }
    }

    @objc func dismiss() {}

    /// 移除创作视频引导
    /// - Returns: <#description#>
    func removeVideoMakeRemindView() {
        viewWithTag(cVideoMakeRemindTag)?.removeFromSuperview()
    }
}

// MARK: - UILabel的分类扩展

/// UILabel的分类扩展
extension UILabel {
    var isTruncated: Bool {
        guard let labelText = text else {
            return false
        }

        // 计算理论上显示所有文字需要的尺寸
        let rect = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude)
        let labelTextSize = (labelText as NSString)
            .boundingRect(with: rect, options: .usesLineFragmentOrigin,
                          attributes: [NSAttributedString.Key.font: font as Any], context: nil)

        // 计算理论上需要的行数
        let labelTextLines = Int(ceil(CGFloat(labelTextSize.height) / font.lineHeight))

        // 实际可显示的行数
        var labelShowLines = Int(floor(CGFloat(bounds.size.height) / font.lineHeight))
        if numberOfLines != 0 {
            labelShowLines = min(labelShowLines, numberOfLines)
        }

        // 比较两个行数来判断是否需要截断
        return labelTextLines > labelShowLines
    }

    /// 添加阴影
    /// - Parameters:
    ///   - color: <#color description#>
    ///   - offset: <#offset description#>
    /// - Returns: <#description#>
    public func addShadow(color: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5), offset: CGSize = CGSize(width: 1, height: 1)) {
        shadowColor = color
        shadowOffset = offset
    }
}

public extension UIImageView {
    /// imageView加载网络图片
    /// - Parameters:
    ///   - url: 网络url
    func setNetImage(url: String?, placeholder: UIImage = UIImage().BF_Image(named: "placehold_image")) {
        if url == nil || (url?.count ?? 0) <= 0 {
            return
        }
        kf.setImage(with: URL(string: url!), placeholder: placeholder, options: url?.suffix(5) == ".webp" ? [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)] : nil, progressBlock: { _, _ in

        }) { _ in
        }
    }

    /// 展示加载中动画
    /// - Returns: <#description#>
    func showLoadingAnimation(duration: Double = 1) {
        let rotationAnim = CABasicAnimation(keyPath: "transform.rotation.z")
        rotationAnim.fromValue = 0
        rotationAnim.toValue = Double.pi * 2
        rotationAnim.repeatCount = MAXFLOAT
        rotationAnim.duration = duration
        rotationAnim.isRemovedOnCompletion = false
        layer.add(rotationAnim, forKey: nil)
    }

    /// 播放GIF
    /// - Parameters:
    ///   - data : 图片二进制数据
    ///   - images: 图片
    ///   - repeatCount: 循环次数
    ///   - duration: 时长
    /// - Returns: <#description#>
    func displayGIF(data: Data? = nil, images: [UIImage]? = nil, repeatCount: Int = Int.max, duration: Double = 1) {
        if images != nil, (images?.count ?? 0) > 0, !isAnimating {
            layer.removeAllAnimations()
            stopAnimating()
            animationImages = images
            animationDuration = duration
            animationRepeatCount = repeatCount
            startAnimating()
        } else if images == nil && data != nil {
            PQPHAssetVideoParaseUtil.parasGIFImage(data: data!) { [weak self] _, images, duration in
                if images != nil, (images?.count ?? 0) > 0 {
                    self?.displayGIF(images: images!, repeatCount: repeatCount, duration: duration ?? 1)
                }
            }
        }
    }

    /// 移除
    func removePlayGIF() {
        layer.removeAllAnimations()
        stopAnimating()
    }
}

public extension UIButton {
    /// UIButton加载网络图片
    /// - Parameters:
    ///   - url: 网络url
    func setNetImage(url: String?, placeholder: UIImage = UIImage().BF_Image(named: "placehold_image")) {
        if url == nil || (url?.count ?? 0) <= 0 {
            BFLog(message: "设置按钮网络图片地址为空")
            return
        }
        kf.setImage(with: URL(string: url!), for: .normal, placeholder: placeholder, options: url?.suffix(5) == ".webp" ? [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)] : nil, progressBlock: { _, _ in

        }) { _ in
        }
    }

    /// UIButton加载网络背景图片
    /// - Parameters:
    ///   - url: 网络url
    func setNetBackgroundImage(url: String, placeholder: UIImage = UIImage().BF_Image(named: "placehold_image")) {
        kf.setBackgroundImage(with: URL(string: url), for: .normal, placeholder: placeholder, options: url.suffix(5) == ".webp" ? [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)] : nil, progressBlock: { _, _ in

        }) { _ in
        }
    }
}
