//
//  LineSpaceLabel.swift

//
//  Created by Leon on 2025/7/18.
//
import UIKit

class LineSpaceLabel: UILabel {
    // MARK: - Properties

    var paragraphSpace: CGFloat = 0

    private var typography: EPTypography?
    private var typographyText: String?

    // MARK: - Initialization

    override init(frame: CGRect) {
        super.init(frame: frame)
        numberOfLines = 0
        textColor = .text
        guard let text = typographyText, !text.isEmpty else { return }
        self.text = text
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Public Methods (Way 1)

    func setupLineSpace(_ space: CGFloat) {
        guard let text = text, !text.isEmpty else {
            assertionFailure("self.text should not be empty.")
            return
        }

        let attributedString: NSMutableAttributedString
        if let existingAttributedText = attributedText {
            attributedString = NSMutableAttributedString(attributedString: existingAttributedText)
        } else {
            attributedString = NSMutableAttributedString(string: text)
        }

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = space
        attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: text.count))

        self.text = nil
        attributedText = attributedString
        lineBreakMode = .byTruncatingTail
    }

    func setupText(_ text: String?, lineSpace: CGFloat) {
        let safeText = text ?? ""

        let attributedString = NSMutableAttributedString(string: safeText)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpace
        attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: safeText.count))

        attributedText = attributedString
        lineBreakMode = .byTruncatingTail
    }

    func setupHighlightText(_ highlight: String?, color: UIColor) {
        guard let attributedText = attributedText, let highlight = highlight, !highlight.isEmpty else {
            assertionFailure("attributedText and highlight must be valid")
            return
        }

        let attributedString = NSMutableAttributedString(attributedString: attributedText)
        if let range = attributedString.string.range(of: highlight) {
            let nsRange = NSRange(range, in: attributedString.string)
            attributedString.addAttribute(.foregroundColor, value: color, range: nsRange)
        }
        self.attributedText = attributedString
    }

    // MARK: - Public Methods (Way 2)

    func config(_ typography: EPTypography) {
        self.typography = typography
        self.text = text
    }

    // MARK: - Overrides

    override var text: String? {
        get { super.text }
        set {
            let safeText = newValue ?? ""

            if let typography = typography {
                typographyText = safeText
                let attributes: [NSAttributedString.Key: Any] = [
                    .font: typography.font!,
                    .foregroundColor: textColor ?? .black,
                ]
                let attributedString = NSMutableAttributedString(string: safeText, attributes: attributes)

                let calLineHeight = typography.lineHeight * 0.5 // Temporary conversion, may need testing
                let paragraphStyle = NSMutableParagraphStyle()
                paragraphStyle.lineSpacing = calLineHeight
                paragraphStyle.alignment = textAlignment
                if paragraphSpace > 0 {
                    paragraphStyle.paragraphSpacing = paragraphSpace
                }
                attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: safeText.count))

                self.attributedText = attributedString
                self.lineBreakMode = .byTruncatingTail
                
                layoutIfNeeded()
            } else {
                super.text = safeText
            }
        }
    }

    override var textColor: UIColor! {
        get { super.textColor }
        set {
            super.textColor = newValue
            if let typographyText = typographyText, !typographyText.isEmpty {
                text = typographyText
            }
        }
    }
}
