//
//  EGNewNormalAlert.swift

//
//  Created by Leon on 2025/8/3.
//

import SnapKit
import UIKit

class EGNewNormalAlert: EGNewBaseAlert {
    // MARK: - Properties
    
    var showCloseButton: Bool = false
    private(set) var contentStackView: UIStackView!
    private(set) var imageBGview: UIView!
    private(set) var imageView: UIImageView!
    
    /// 隐藏titleBGView才能隐藏titleLabel
    private(set) var titleBGview: UIView!
    private(set) var titleLabel: UILabel!
    
    private(set) var textBGview: UIView!
    private(set) var textView: UITextView!
    
    private(set) var optionContainer: UIView!
    private(set) var btnsPartStackView: UIStackView!
    private var closeButton: EPIconGhostButton!
    private(set) var masTopToImageBgForImageView: Constraint?
    private(set) var masBottomToImageBgForImageView: Constraint?
    private var image: UIImage?
    var counting: Int = 0
    var operatingAction: EGNewAlertAction?
    var timerEndAction: (() -> Void)?
    
    private let kMarginLRText: CGFloat = 24
    private let kMarginTBButton: CGFloat = 10
    private let kMarginContent: CGFloat = 24
    
    var bgBlurImageNode:Bool = false
    
    lazy var bgImageView = {
        let v  = AutoRatioImageView()
        v.setContentHuggingPriority(UILayoutPriority(240), for: .horizontal)
        v.setContentHuggingPriority(UILayoutPriority(240), for: .vertical)
        v.setContentCompressionResistancePriority(UILayoutPriority(740), for: .horizontal)
        v.setContentCompressionResistancePriority(UILayoutPriority(740), for: .vertical)
        containerView.insertSubview(v, at: 0)
        v.snp.makeConstraints { make in
            make.top.leading.trailing.equalToSuperview().priority(.medium)
        }
        v.isHidden = true
        return v
    }()
    
    lazy var effectView = {
        let v = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
        v.alpha = 1
        containerView.insertSubview(v, aboveSubview: bgImageView)
        v.snp.makeConstraints { make in
//            make.edges.equalToSuperview()
            make.edges.equalTo(bgImageView)
        }
        return v
    }()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        if bgBlurImageNode{
            bgImageView.frame = containerView.bounds
        }
    }

    // MARK: - Initialization

    init(title: String, text: String) {
        super.init(frame: .zero)
        uiInit()
        titleLabel.text = title
        textView.text = text
        reloadLayout()
    }

    init(title: String, lineSpaceText text: String) {
        super.init(frame: .zero)
        uiInit()
        titleLabel.text = title
//        let paragraphStyle = NSMutableParagraphStyle().then {
//            $0.paragraphSpacing = 6
//            $0.lineSpacing = 3
//        }
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.paragraphSpacing = 6
        paragraphStyle.lineSpacing = 3
        let attributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 16), // 🔥 Assuming EPF.bm is a body font
            .foregroundColor: UIColor.black, // 🔥 Assuming EPC.tpn is a primary text color
            .paragraphStyle: paragraphStyle,
        ]
        textView.attributedText = NSAttributedString(string: text, attributes: attributes)
        reloadLayout()
    }

    init(title: String, attributeText text: NSAttributedString) {
        super.init(frame: .zero)
        uiInit()
        titleLabel.text = title
        textView.attributedText = text
        reloadLayout()
    }

    init(title: String, text: String, image: UIImage) {
        super.init(frame: .zero)
        self.image = image
        uiInit()
        titleLabel.text = title
        textView.text = text
        reloadLayout()
    }

    init(title: String, attributeText text: NSAttributedString, image: UIImage?) {
        super.init(frame: .zero)
        self.image = image
        uiInit()
        titleLabel.text = title
        textView.attributedText = text
        reloadLayout()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        uiInit()
        reloadLayout()
    }

    private func uiInit() {
        contentStackView = UIStackView().then {
            textContentView.addSubview($0)
            $0.spacing = kMarginContent
            $0.axis = .vertical
            $0.alignment = .center
            $0.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(image != nil ? 0 : 32)
                make.bottom.leading.trailing.equalToSuperview()
            }
        }

        imageBGview = UIView().then {
            contentStackView.addArrangedSubview($0)
            $0.isUserInteractionEnabled = false
            $0.isHidden = true
            $0.snp.makeConstraints { make in
                make.leading.trailing.equalToSuperview()
            }
        }

        imageView = UIImageView().then {
            imageBGview.addSubview($0)
            $0.snp.makeConstraints { make in
                self.masTopToImageBgForImageView = make.top.equalToSuperview().offset(0).constraint
                self.masBottomToImageBgForImageView = make.bottom.equalToSuperview().offset(0).constraint
                make.center.equalToSuperview()
                make.size.equalTo(CGSize.zero)
            }
        }

        titleBGview = UIView().then {
            contentStackView.addArrangedSubview($0)
            $0.isUserInteractionEnabled = false
            $0.snp.makeConstraints { make in
                make.leading.equalToSuperview().offset(kMarginLRText)
                make.trailing.equalToSuperview().offset(-kMarginLRText)
            }
        }

        titleLabel = UILabel().then {
            titleBGview.addSubview($0)
            $0.font = .t.ttm
            $0.textColor = .c.ctpn
            $0.textAlignment = .center
            $0.numberOfLines = 2
            $0.setContentHuggingPriority(.required, for: .vertical)
            $0.setContentCompressionResistancePriority(.required, for: .vertical)
            $0.snp.makeConstraints { make in
                make.centerX.top.bottom.equalToSuperview()
                make.leading.greaterThanOrEqualToSuperview()
                make.trailing.lessThanOrEqualToSuperview()
            }
        }

        textBGview = UIView().then {
            contentStackView.addArrangedSubview($0)
            $0.snp.makeConstraints { make in
                make.leading.equalToSuperview().offset(kMarginLRText)
                make.trailing.equalToSuperview().offset(-kMarginLRText)
            }
        }

        textView = UITextView().then {
            textBGview.addSubview($0)
            $0.backgroundColor = .clear
            $0.font = .t.tbm
            $0.textColor = .c.ctpn
            $0.textAlignment = .center
            $0.isScrollEnabled = false
            $0.isEditable = false
            $0.isSelectable = false
            $0.showsVerticalScrollIndicator = false
            $0.showsHorizontalScrollIndicator = false
            $0.indicatorStyle = .white
            $0.setContentHuggingPriority(.defaultLow, for: .vertical)
            $0.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
            $0.snp.makeConstraints { make in
                make.edges.equalToSuperview()
                make.height.equalTo(0)
            }
        }

        optionContainer = UIView().then {
            contentStackView.addArrangedSubview($0)
            $0.isHidden = true
            $0.snp.makeConstraints { make in
                make.leading.equalTo(kMarginLRText)
                make.trailing.equalTo(-kMarginLRText)
            }
        }

        closeButton = EPIconGhostButton(radius: .none, iconSize: .small, iconCode: .delete).then {
            textContentView.addSubview($0)
            $0.isHidden = true
            $0.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
            $0.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(6)
                make.trailing.equalToSuperview().offset(-10)
                make.size.equalTo(CGSize(width: 32, height: 32))
            }
        }

        btnsPartStackView = UIStackView().then {
            buttonContainer.addSubview($0)
            $0.spacing = 24
            $0.distribution = .equalSpacing
            $0.axis = .vertical
            $0.alignment = .center
            $0.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(24)
                make.bottom.equalToSuperview().offset(-24)
                make.leading.equalToSuperview().offset(24)
                make.trailing.equalToSuperview().offset(-24)
            }
        }
    }

    func reloadLayout() {
        let textWidth = containerWidth - (kMarginLRText * 2)
        var imageHeight: CGFloat = 0
        var imageWidth: CGFloat = 0
        var height: CGFloat = 0

        if let image = image {
            imageBGview.isHidden = false
            imageView.image = image
            imageHeight = image.size.height
            imageWidth = image.size.width
            if imageWidth > textWidth {
                let newWidth = containerWidth
                imageHeight = imageHeight * (newWidth / imageWidth)
                imageWidth = newWidth
            }
            imageView.snp.updateConstraints { make in
                make.size.equalTo(CGSize(width: imageWidth, height: imageHeight))
            }
        } else {
            height = kMarginContent + kMarginTBButton
        }

        let fitSize = CGSize(width: textWidth, height: .greatestFiniteMagnitude)
        let titleHeight = titleLabel.sizeThatFits(fitSize).height + 0.6
        let textHeight = textView.sizeThatFits(fitSize).height + 0.6

        if image != nil {
            height += imageHeight + 12
            height += kMarginContent
        }
        if !titleLabel.text!.isEmpty {
            height += titleHeight
            height += kMarginContent
        }
        height += kMarginTBButton

        let minHeight = textContentMinHeight()
        let maxHeight = textContentMaxHeight()
        var textViewHeight = textHeight

        textView.isScrollEnabled = false
        if height + textHeight > maxHeight {
            textViewHeight = maxHeight - height
            textView.isScrollEnabled = true
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
                self?.textView.flashScrollIndicators()
            }
        } else if height + textHeight < minHeight {
            textViewHeight = minHeight - height
        }

        textView.snp.updateConstraints { make in
            make.height.equalTo(textViewHeight)
        }
    }

    func layoutButtons() {
        guard !actions.isEmpty else { return }
        let alertWidth = containerWidth - kMarginLRText * 2
        let buttonWidth = btnsPartStackView.axis == .horizontal
            ? (alertWidth - CGFloat(actions.count - 1) * 8) / CGFloat(actions.count)
            : alertWidth

        for button in buttons {
            btnsPartStackView.addArrangedSubview(button)
            button.snp.makeConstraints { make in
                make.width.equalTo(buttonWidth)
            }
        }
    }

    @objc private func closeAction() {
        endEditing(true)
        dismiss()
    }

    deinit {
        print("🌪️ EGNewNormalAlert dealloc")
    }

    // MARK: - Override

    override func show() {
        if showCloseButton {
            titleLabel.snp.updateConstraints { make in
                make.leading.greaterThanOrEqualToSuperview().offset(16) // 🔥 Assuming pageLR is 16
                make.trailing.lessThanOrEqualToSuperview().offset(-16)
            }
            closeButton.isHidden = false
        }
        layoutButtons()
        super.show()
    }

    // MARK: - Public Methods

    func setupButtonAxis(_ buttonAxis: NSLayoutConstraint.Axis) {
        btnsPartStackView.axis = buttonAxis
    }

    func setupContentAlignment(_ textAlignment: NSTextAlignment) {
        textView.textAlignment = textAlignment
    }

    func setupButtonsSpacing(_ spacing: CGFloat) {
        btnsPartStackView.spacing = spacing
    }

    func setupContentStackSpacing(_ spacing: CGFloat) {
        contentStackView.spacing = spacing
    }

    func setupButtonsStackLayoutTop(_ margin: CGFloat) {
        btnsPartStackView.snp.updateConstraints { make in
            make.top.equalToSuperview().offset(margin)
        }
    }

    func setupOptionContainerInnerView(_ view: UIView?) {
        guard let view = view else { return }
        optionContainer.isHidden = false
        optionContainer.addSubview(view)
        view.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

    func isTextViewScrollEnable() -> Bool {
        return textView.contentSize.height > textView.bounds.size.height + 10
    }

    func refreshTextViewText(_ textObj: Any) {
        if let text = textObj as? String {
            textView.text = text
        } else if let attributedText = textObj as? NSAttributedString {
            textView.attributedText = attributedText
        } else {
            assertionFailure("Invalid text object")
        }
    }

    func addTopButtonForTextView(_ block: (() -> Void)?) {
        let button = UIButton(type: .custom)
        textBGview.addSubview(button)
        button.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        button.addTarget(self, action: #selector(executeBlock(_:)), for: .touchUpInside)
        objc_setAssociatedObject(button, &AssociatedKeys.block, block, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }

    @objc private func executeBlock(_ sender: UIButton) {
        let block = objc_getAssociatedObject(sender, &AssociatedKeys.block) as? (() -> Void)
        block?()
    }
    
    func setupBottomBlurImage(image: UIImage?){
        bgBlurImageNode = true
        bgImageView.image = image
        bgImageView.isHidden = false
        effectView.isHidden = false
        layoutIfNeeded()
    }

    func setupBottomBlurImageUrl(url: String?) {
//        guard let urlObj = URL(string: url) else {
//            return
//        }
        guard let urlString = url else{return}
        
        bgImageView.setImage(with: urlString.urlValue)
        bgImageView.isHidden = false
        effectView.isHidden = false
        layoutIfNeeded()
    }
}

private struct AssociatedKeys {
    static var block = "block"
}
