//
//  UILabel+Extension.swift
//  PhoneManager
//
//  Created by zxhy on 2025/3/19.
//

import UIKit

extension UILabel {
    
    static func getSizeWith(
        font:UIFont = UIFont.systemFont(ofSize: 14, weight: .regular),
        lineSpacing:CGFloat = 5 ,
        paragraphSpacing:CGFloat = 0,
        width:CGFloat = CGFloat(MAXFLOAT),
        numberOfLines:Int = 0,
        content:String) -> CGSize {
            
            let sview:UILabel = UILabel()
            sview.width = width
            sview.font = font
            sview.numberOfLines = 0
            
            let style = NSMutableParagraphStyle()
            
            style.lineSpacing = lineSpacing
            style.paragraphSpacing = paragraphSpacing
            sview.attributedText = NSAttributedString(string: content, attributes: [NSAttributedString.Key.paragraphStyle: style])
            sview.numberOfLines = numberOfLines
            
            sview.sizeToFit()
            
            return sview.size
        }
    
    func setlineSpacing(font:UIFont = UIFont.systemFont(ofSize: 14, weight: .regular),
                        lineSpacing:CGFloat = 5,
                        paragraphSpacing:CGFloat = 0,
                        width:CGFloat = CGFloat(MAXFLOAT),
                        numberOfLines:Int = 0,
                        content:String) {
        
        self.width = width
        self.font = font
        self.numberOfLines = 0
        
        let style = NSMutableParagraphStyle()
        
        style.lineSpacing = lineSpacing
        style.paragraphSpacing = paragraphSpacing
        self.attributedText = NSAttributedString(string: content, attributes: [NSAttributedString.Key.paragraphStyle: style])
        self.numberOfLines = numberOfLines
        
        self.sizeToFit()
        self.width = width
    }
}



var handleTextTapKey = "handleTextTapKey"
var ClickLabelTextsJey = "ClickLabelTextsJey"


extension UILabel {
    
    private var handleTextTap:((String)->Void)? {
        set {
            objc_setAssociatedObject(self, &handleTextTapKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, &handleTextTapKey) as? ((String) -> Void)
        }
    }
    
    private var ClickLabelTexts:[String]? {
        set {
            objc_setAssociatedObject(self, &ClickLabelTextsJey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, &ClickLabelTextsJey) as? [String]
        }
    }
    
    public func AddTapped(_ ClickStrs:[String],handle:@escaping((String)->Void)) -> Void {
        if ClickLabelTexts?.count ?? 0 > 0 {
            return
        }
        let tap = UITapGestureRecognizer(target: self, action: #selector(labelTapped(_:)))
        self.addGestureRecognizer(tap)
        self.isUserInteractionEnabled = true
        ClickLabelTexts = ClickStrs
        handleTextTap = handle
    }
    
    func frameForStringRange(_ range: NSRange) -> CGRect? {
        guard let attributedText = attributedText else { return nil }
        let textStorage = NSTextStorage(attributedString: attributedText)
        let layoutManager = NSLayoutManager()
        textStorage.addLayoutManager(layoutManager)
        
        let textContainer = NSTextContainer(size: bounds.size)
        textContainer.lineFragmentPadding = 0
        layoutManager.addTextContainer(textContainer)
        
        var glyphRange = NSRange()
        layoutManager.characterRange(
            forGlyphRange: range,
            actualGlyphRange: &glyphRange
        )
        return layoutManager.boundingRect(
            forGlyphRange: glyphRange,
            in: textContainer
        )
    }
    
    @objc private func labelTapped(_ gesture: UITapGestureRecognizer) {
        self.layoutIfNeeded()
        // 判断点击范围
        for text in (ClickLabelTexts ?? []) {
            if let range = self.text?.range(of: text) {
                let nsRange = NSRange(range, in: self.text ?? "")
                guard var subStringFrame = self.frameForStringRange(nsRange) else { return }
                let locationInLabel = gesture.location(in: self)
                if CGRectContainsPoint(subStringFrame, locationInLabel) {
                    handleTextTap?(text)
                }
            }
        }
    }
    
    
    func isTapLocationInTextRange(_ gesture: UITapGestureRecognizer, range: NSRange) -> Bool {
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: .zero)
        let textStorage = NSTextStorage(attributedString: self.attributedText ?? NSAttributedString())
        
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)
        
        textContainer.lineFragmentPadding = 0
        textContainer.lineBreakMode = self.lineBreakMode
        textContainer.maximumNumberOfLines = self.numberOfLines
        textContainer.size = self.bounds.size
        
        let location = gesture.location(in: self)
        let textBoundingBox = layoutManager.usedRect(for: textContainer)
        let alignmentOffset = self.alignmentOffsetForText(in: textBoundingBox)
        let touchLocation = CGPoint(
            x: (location.x - alignmentOffset),
            y: (location.y - textBoundingBox.minY)
        )
        let index = layoutManager.characterIndex(
            for: touchLocation,
            in: textContainer,
            fractionOfDistanceBetweenInsertionPoints: nil
        )
        
        return NSLocationInRange(index, range)
    }
    
    private func alignmentOffsetForText(in rect: CGRect) -> CGFloat {
        switch self.textAlignment {
        case .left, .natural, .justified:
            return 0
        case .center:
            return (self.bounds.width - rect.width) / 2
        case .right:
            return self.bounds.width - rect.width
        @unknown default:
            return 0
        }
    }
}



extension UILabel {
    
    /// 获取label高度
    /// - Parameters:
    ///   - maxSize: 最大高度，宽
    /// - Returns: <#description#>
    public func textHeight() -> CGSize {
        let maxSize = CGSize(width: ScreenW, height: CGFloat(MAXFLOAT))
        let attributedStr = NSMutableAttributedString.init(string: text ?? "")
        let size = attributedStr.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, context: nil).size
        return size
    }
    
    /// 根据高度动态计算宽度(new)
    func getLabelWidth(height: CGFloat) -> CGFloat {
        return sizeThatFits(CGSize(width:CGFloat(MAXFLOAT), height: height)).width
    }
    
    /// 根据宽度动态计算高度(new)
    func getLabelHeight(width: CGFloat) -> CGFloat {
        return sizeThatFits(CGSize(width:width, height: CGFloat(MAXFLOAT))).height
    }
    
    /// 中间加下划线
    func addLineInMiddle() {
        guard let text = text else { return }
        let attribute = NSMutableAttributedString.init(string: text)
        attribute.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSNumber.init(value: 1), range: NSRange(location: 0, length: text.count))
        attributedText = attribute
    }
    
    /// 中间加下划线
    func addUnderline() {
        guard let text = text else { return }
        let attribute = NSMutableAttributedString(string: text)
        
        // 添加下划线属性
        attribute.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: text.count))
        
        // 设置 UILabel 的 attributedText
        attributedText = attribute
    }
    
    
}
