//
//  UIButton+Extension.swift
//  QuickSearchLocation
//
//  Created by mac on 2024/4/11.
//

import UIKit

extension UIButton {
    
    enum ThemeButtonType {
        case mainTheme
    }
    
    // MARK: 1.1、创建一个带颜色的 Button, 默认为主题色，默认高度44
    /// 创建一个带颜色的 Button
    /// - Parameters:
    ///   - type: 类型
    ///   - height: 高度
    /// - Returns: 返回自身
    @discardableResult
    static func normal() -> UIButton {
        let normalColor: UIColor
        let disabledColor: UIColor
        let titleColorNormal: UIColor
        let titleColorDisable: UIColor
        
        normalColor = QSLColor.themeMainColor
        disabledColor = QSLColor.buttonDisabledColor
        titleColorNormal = .white
        titleColorDisable = .white
        
        let btn = UIButton(type: .custom).font(.systemFont(ofSize: 16))
        btn.setTitleColor(titleColorNormal, for: .normal)
        btn.setTitleColor(titleColorDisable, for: .disabled)
        btn.setBackgroundColor(normalColor, forState: .normal)
        btn.setBackgroundColor(disabledColor, forState: .disabled)
        return btn
    }
    
    //MARK: 1.3、设置背景色
    /// 设置背景色
    /// - Parameters:
    ///   - color: 背景色
    ///   - forState: 状态
    func setBackgroundColor(_ color: UIColor, forState: UIControl.State) {
        self.setBackgroundImage(backgroundImage(color), for: forState)
    }
    
    private func backgroundImage(_ color: UIColor) -> UIImage? {
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        UIGraphicsGetCurrentContext()?.setFillColor(color.cgColor)
        UIGraphicsGetCurrentContext()?.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
        let colorImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return colorImage
    }
}

// MARK: - 二、链式调用
public extension UIButton {
    
    // MARK: 2.1、设置title
    /// 设置title
    /// - Parameters:
    ///   - text: 文字
    ///   - state: 状态
    /// - Returns: 返回自身
    @discardableResult
    func title(_ text: String, _ state: UIControl.State = .normal) -> Self {
        setTitle(text, for: state)
        return self
    }
    
    // MARK: 2.2、设置文字颜色
    /// 设置文字颜色
    /// - Parameters:
    ///   - color: 文字颜色
    ///   - state: 状态
    /// - Returns: 返回自身
    @discardableResult
    func textColor(_ color: UIColor, _ state: UIControl.State = .normal) -> Self {
        setTitleColor(color, for: state)
        return self
    }
    
    // MARK: 2.3、设置字体大小(UIFont)
    /// 设置字体大小
    /// - Parameter font: 字体 UIFont
    /// - Returns: 返回自身
    @discardableResult
    func font(_ font: UIFont) -> Self {
        titleLabel?.font = font
        return self
    }
    
    // MARK: 2.4、设置字体大小(CGFloat)
    /// 设置字体大小(CGFloat)
    /// - Parameter fontSize: 字体的大小
    /// - Returns: 返回自身
    @discardableResult
    func font(_ fontSize: CGFloat) -> Self {
        titleLabel?.font = UIFont.textF(fontSize)
        return self
    }
    
    // MARK: 2.5、设置字体中等粗(CGFloat)
    /// 设置字体大小(CGFloat)
    /// - Parameter fontSize: 字体的大小
    /// - Returns: 返回自身
    @discardableResult
    func mediumFont(_ fontSize: CGFloat) -> Self {
        titleLabel?.font = UIFont.textM(fontSize)
        return self
    }
    
    // MARK: 2.6、设置字体粗体
    /// 设置粗体
    /// - Parameter fontSize: 设置字体粗体
    /// - Returns: 返回自身
    @discardableResult
    func boldFont(_ fontSize: CGFloat) -> Self {
        titleLabel?.font = UIFont.textB(fontSize)
        return self
    }
    
    // MARK: 2.7、设置图片
    /// 设置图片
    /// - Parameters:
    ///   - image: 图片
    ///   - state: 状态
    /// - Returns: 返回自身
    @discardableResult
    func image(_ image: UIImage?, _ state: UIControl.State = .normal) -> Self {
        setImage(image, for: state)
        return self
    }
    
}

// MARK: - UIButton 图片 与 title 位置关系
extension UIButton {
    
    /// 图片 和 title 的布局样式
    enum ImageTitleLayout {
        case imgTop
        case imgBottom
        case imgLeft
        case imgRight
    }
    
    // MARK: 3.1、设置图片和 title 的位置关系(提示：title和image要在设置布局关系之前设置)
    /// 设置图片和 title 的位置关系(提示：title和image要在设置布局关系之前设置)
    /// - Parameters:
    ///   - layout: 布局
    ///   - spacing: 间距
    /// - Returns: 返回自身
    @discardableResult
    func setImageTitleLayout(_ layout: ImageTitleLayout, spacing: CGFloat = 0) -> UIButton {
        switch layout {
        case .imgLeft:
            alignHorizontal(spacing: spacing, imageFirst: true)
        case .imgRight:
            alignHorizontal(spacing: spacing, imageFirst: false)
        case .imgTop:
            alignVertical(spacing: spacing, imageTop: true)
        case .imgBottom:
            alignVertical(spacing: spacing, imageTop: false)
        }
        return self
    }
    
    /// 水平方向
    /// - Parameters:
    ///   - spacing: 间距
    ///   - imageFirst: 图片是否优先
    private func alignHorizontal(spacing: CGFloat, imageFirst: Bool) {
        let edgeOffset = spacing / 2
        imageEdgeInsets = UIEdgeInsets(top: 0, left: -edgeOffset,
                                            bottom: 0,right: edgeOffset)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: edgeOffset,
                                            bottom: 0, right: -edgeOffset)
        if !imageFirst {
            transform = CGAffineTransform(scaleX: -1, y: 1)
            imageView?.transform = CGAffineTransform(scaleX: -1, y: 1)
            titleLabel?.transform = CGAffineTransform(scaleX: -1, y: 1)
        }
        contentEdgeInsets = UIEdgeInsets(top: 0, left: edgeOffset, bottom: 0, right: edgeOffset)
    }
    
    /// 垂直方向
    /// - Parameters:
    ///   - spacing: 间距
    ///   - imageTop: 图片是不是在顶部
    private func alignVertical(spacing: CGFloat, imageTop: Bool) {
        
        guard let imageWidth = self.imageView?.qsl_width,
              let imageHeight = self.imageView?.qsl_height,
              let text = self.titleLabel?.text,
              let font = self.titleLabel?.font
        else {
            return
        }
        
        let labelString = NSString(string: text)
        let titleSize = labelString.size(withAttributes: [NSAttributedString.Key.font: font])
        let titleHeight = titleSize.height
        let titleWidth = titleSize.width
        let insetAmount = spacing / 2
        
        if imageTop {
            
            imageEdgeInsets = UIEdgeInsets(top: -titleHeight - insetAmount,
                                           left: (self.qsl_width - imageWidth) / 2,
                                           bottom: 0,
                                           right: (self.qsl_width - imageWidth) / 2 - titleWidth)
            titleEdgeInsets = UIEdgeInsets(top: 0,
                                           left: -imageWidth,
                                           bottom: -imageWidth - insetAmount,
                                           right: 0)
        } else {
            
            imageEdgeInsets = UIEdgeInsets(top: 0,
                                           left: (self.qsl_width - imageWidth) / 2,
                                           bottom: -titleHeight - insetAmount,
                                           right: (self.qsl_width - imageWidth) / 2 - titleWidth)
            titleEdgeInsets = UIEdgeInsets(top: -imageHeight - insetAmount,
                                           left: -imageWidth,
                                           bottom: 0,
                                           right: 0)
        }
    }
    
}

extension UIButton {
    
    //倒计时
    func countDown(_ timeOut: Int){
        //倒计时时间
        var timeout = timeOut
        let queue:DispatchQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.default)
        let _timer:DispatchSource = DispatchSource.makeTimerSource(flags: [], queue: queue) as! DispatchSource
        _timer.schedule(wallDeadline: DispatchWallTime.now(), repeating: .seconds(1))
            //每秒执行
        _timer.setEventHandler(handler: { () -> Void in
            if(timeout<=0){ //倒计时结束，关闭
                _timer.cancel();
                DispatchQueue.main.sync(execute: { () -> Void in
                    self.setTitle("重新发送", for: .normal)
                    self.isEnabled = true
                })
            }else{//正在倒计时
                let seconds = timeout
                DispatchQueue.main.sync(execute: { () -> Void in
                    let str = String(describing: seconds)
                    self.setTitle("\(str)s", for: .normal)
                    self.isEnabled = false
                })
                timeout -= 1;
            }
        })
        _timer.resume()
    }
}

// MARK: - 六、Button扩大点击事件
private var UIButtonExpandSizeKey = UnsafeRawPointer("UIButtonExpandSizeKey".withCString { $0 })

public extension UIButton {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if self.touchExtendInset == .zero || isHidden || !isEnabled {
            return super.point(inside: point, with: event)
        }
        var hitFrame = bounds.inset(by: self.touchExtendInset)
        hitFrame.size.width = max(hitFrame.size.width, 0)
        hitFrame.size.height = max(hitFrame.size.height, 0)
        return hitFrame.contains(point)
    }
}

public extension UIButton {
    
    // MARK: 6.1、扩大UIButton的点击区域，向四周扩展10像素的点击范围
    /// 扩大按钮点击区域 如UIEdgeInsets(top: -50, left: -50, bottom: -50, right: -50)将点击区域上下左右各扩充50
    ///
    /// 提示：theView 扩展点击相应区域时，其扩展的区域不能超过 superView 的 frame ，否则不会相应改点击事件；如果需要响应点击事件，需要对其 superView 进行和 theView 进行同样的处理
    var touchExtendInset: UIEdgeInsets {
        get {
            if let value = objc_getAssociatedObject(self, &UIButtonExpandSizeKey) {
                var edgeInsets: UIEdgeInsets = UIEdgeInsets.zero
                (value as AnyObject).getValue(&edgeInsets)
                return edgeInsets
            } else {
                return UIEdgeInsets.zero
            }
        }
        set {
            objc_setAssociatedObject(self, &UIButtonExpandSizeKey, NSValue(uiEdgeInsets: newValue), .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
    }
}
