//
//  EGNewBaseAlert.swift

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

import UIKit
import SnapKit

// MARK: - EGNewAlertAction

enum EGNewAlertActionStyle: Int {
    case `default`
    case cancel
    case confirm
    case disabled
    case inputSave
    case destructive
}

class EGNewAlertAction : Equatable {
    var title: String
    var attributedTitle: NSAttributedString?
    var actionStyle: EGNewAlertActionStyle
    var autoDismiss: Bool
    var actionBlock: (() -> Void)?

    init(title: String, actionStyle: EGNewAlertActionStyle = .default, autoDismiss: Bool = true, block: (() -> Void)? = nil) {
        self.title = title
        self.attributedTitle = nil
        self.actionStyle = actionStyle
        self.autoDismiss = autoDismiss
        self.actionBlock = block
    }
    
    // 新增：使用 NSAttributedString 的初始化方法
    init(attributedTitle: NSAttributedString, actionStyle: EGNewAlertActionStyle = .default, autoDismiss: Bool = true, block: (() -> Void)? = nil) {
        self.title = "" // 当使用富文本时，title 为空
        self.attributedTitle = attributedTitle
        self.actionStyle = actionStyle
        self.autoDismiss = autoDismiss
        self.actionBlock = block
    }

    static func action(title: String, block: (() -> Void)? = nil) -> EGNewAlertAction {
        return EGNewAlertAction(title: title, block: block)
    }

    static func action(title: String, actionStyle: EGNewAlertActionStyle, block: (() -> Void)? = nil) -> EGNewAlertAction {
        return EGNewAlertAction(title: title, actionStyle: actionStyle, block: block)
    }

    static func action(title: String, actionStyle: EGNewAlertActionStyle, autoDismiss: Bool, block: (() -> Void)? = nil) -> EGNewAlertAction {
        return EGNewAlertAction(title: title, actionStyle: actionStyle, autoDismiss: autoDismiss, block: block)
    }
    
    // 新增：使用 NSAttributedString 的静态方法
    static func action(attributedTitle: NSAttributedString, block: (() -> Void)? = nil) -> EGNewAlertAction {
        return EGNewAlertAction(attributedTitle: attributedTitle, block: block)
    }

    static func action(attributedTitle: NSAttributedString, actionStyle: EGNewAlertActionStyle, block: (() -> Void)? = nil) -> EGNewAlertAction {
        return EGNewAlertAction(attributedTitle: attributedTitle, actionStyle: actionStyle, block: block)
    }

    static func action(attributedTitle: NSAttributedString, actionStyle: EGNewAlertActionStyle, autoDismiss: Bool, block: (() -> Void)? = nil) -> EGNewAlertAction {
        return EGNewAlertAction(attributedTitle: attributedTitle, actionStyle: actionStyle, autoDismiss: autoDismiss, block: block)
    }
    
    // MARK: - Equatable
    static func == (lhs: EGNewAlertAction, rhs: EGNewAlertAction) -> Bool {
        return lhs === rhs // 🔥 Using identity comparison; adjust if unique identifier exists
    }
}

// MARK: - EGNewBaseAlert

enum EGNewAlertPriority: Int {
    case `default` = 0
    case update = 10
    case forceUpdate = 100
}

class EGNewBaseAlert: UIView {
    // MARK: - Properties
    private(set) var backgroundView: UIView!
    private(set) var containerView: UIView!
    private(set) var textContentView: UIView!
    private(set) var buttonContainer: UIView!
    private(set) var buttons: [StyleButton] = []
    private(set) var actions: [EGNewAlertAction] = []
    var priority: EGNewAlertPriority = .default
    private var maxActionCount: Int = 2

    var containerWidth: CGFloat {
        return UIScreen.main.bounds.width - containerMarginLR() * 2
    }

    // MARK: - Initialization
    override init(frame: CGRect) {
        super.init(frame: frame)
        baseDataInit()
        baseUIInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        baseDataInit()
        baseUIInit()
    }

    private func baseDataInit() {
        maxActionCount = 2
        buttons = []
        actions = []
    }

    private func baseUIInit() {
        backgroundView = UIView().then {
            addSubview($0)
            $0.backgroundColor = .c.cbs
            $0.alpha = 0
            $0.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }
        }

        containerView = UIView().then {
            addSubview($0)
            $0.backgroundColor = .c.csbn // 🔥 Assuming EPS_Color_Surface_base_normal is a light color
            $0.layer.cornerRadius = containerCornerRadius()
            $0.clipsToBounds = true
            $0.alpha = 0
            let width = UIScreen.main.bounds.width * 0.8
            $0.snp.makeConstraints { make in
                make.center.equalToSuperview()
                make.width.equalTo(width)
            }
        }

        textContentView = UIView().then {
            containerView.addSubview($0)
            $0.backgroundColor = .clear
            $0.setContentHuggingPriority(.defaultLow, for: .vertical)
            $0.snp.makeConstraints { make in
                make.leading.trailing.top.equalToSuperview()
                make.height.greaterThanOrEqualTo(textContentMinHeight())
            }
        }

        buttonContainer = UIView().then {
            containerView.addSubview($0)
            $0.backgroundColor = .clear
            $0.snp.makeConstraints { make in
                make.top.equalTo(textContentView.snp.bottom)
                make.leading.trailing.bottom.equalToSuperview()
            }
        }
    }

    // MARK: - Layout Methods (Overridable)
    func containerMarginLR() -> CGFloat {
        return 40
    }

    func textContentMaxHeight() -> CGFloat {
        return UIScreen.main.bounds.height * 0.65
    }

    func textContentMinHeight() -> CGFloat {
        return 100
    }

    func containerCornerRadius() -> CGFloat {
        return 16
    }

    func containerAlphaDuration() -> CGFloat {
        return 0.35
    }

    func backgroundAlphaValue() -> CGFloat {
        return 0.65
    }

    func alertInitRatio() -> CGFloat {
        return 0.6
    }

    // MARK: - Actions
    func addAction(_ action: EGNewAlertAction) {
        addAction(action, propertySetup: nil)
    }

    func addAction(_ action: EGNewAlertAction, propertySetup: ((UIButton) -> Void)?) {
        guard actions.count < maxActionCount else { return }

        let button = StyleButton(type: .custom)
        button.addTarget(self, action: #selector(baseButtonPressed(_:)), for: .touchUpInside)
        
        // 支持富文本和普通文本
        if let attributedTitle = action.attributedTitle {
            button.setAttributedTitle(attributedTitle, for: .normal)
        } else {
            button.setTitle(action.title, for: .normal)
        }
        
        button.tag = actions.count
        button.titleLabel?.font = .t.tbsl// EPS_Txt_BodySemibold_l is a bold font
        reloadButton(button, style: action.actionStyle)

        if let setup = propertySetup {
            setup(button)
        }

        actions.append(action)
        buttons.append(button)
    }

    func reloadAction(_ action: EGNewAlertAction, title: String) {
        guard let index = actions.firstIndex(of: action) else {
            assertionFailure("Action not found")
            return
        }
        let button = buttons[index]
        button.setTitle(title, for: .normal)
        reloadButton(button, style: action.actionStyle)
    }
    
    // 新增：支持富文本的 reloadAction 方法
    func reloadAction(_ action: EGNewAlertAction, attributedTitle: NSAttributedString) {
        guard let index = actions.firstIndex(of: action) else {
            assertionFailure("Action not found")
            return
        }
        let button = buttons[index]
        button.setAttributedTitle(attributedTitle, for: .normal)
        reloadButton(button, style: action.actionStyle)
    }

    private func reloadButton(_ button: StyleButton, style: EGNewAlertActionStyle) {
        button.isEnabled = true
        switch style {
        case .default, .cancel:
            button.tertiary(size: .large)
        case .confirm,.inputSave:
            button.primary(size: .large)
        case .disabled:
            button.tertiary(size: .large)
            button.isEnabled = false
        case .destructive:
            button.defaultDestructive(size: .large)
        }
    }

    // MARK: - Events
    @objc private func baseButtonPressed(_ button: UIButton) {
        endEditing(true)
        let action = actions[button.tag]
        if action.autoDismiss {
            dismiss()
        }
        action.actionBlock?()
    }

    func alertDidShow() {
        // Overridable by subclasses
    }

    // MARK: - Animation
    func showWithAnimation() {
        containerView.transform = CGAffineTransform(scaleX: alertInitRatio(), y: alertInitRatio())
        UIView.animate(withDuration: containerAlphaDuration(), delay: 0, options: .curveEaseOut, animations: {
            self.backgroundView.alpha = self.backgroundAlphaValue()
            self.containerView.alpha = 1
            self.containerView.transform = .identity
        }) { _ in
            self.alertDidShow()
        }
    }

    func dismissWithAnimation() {
        UIView.animate(withDuration: containerAlphaDuration(), delay: 0, options: .curveEaseIn, animations: {
            self.containerView.transform = CGAffineTransform(scaleX: 1.05, y: 1.05)
            self.backgroundView.alpha = 0
            self.containerView.alpha = 0
        }) { _ in
            self.removeFromSuperview()
        }
    }

    // MARK: - Display
    func show() {
        // ⚠️ Before is windows's first
        //guard let window = UIApplication.shared.windows.first else { return }
        
        // 第二种方式：
//        var window: UIWindow!
//        for per in UIApplication.shared.windows.reversed(){
//            if per.isHidden == false{
//                window = per
//                break
//            }
//        }
        
        // 第3种方式： 会过滤一些
        var window: UIWindow!
        window = UIWindow.getTopDisplayWindow()!
        
        if window == nil{
            assert(false, "alert window not found")
        }
        
        window.endEditing(true)

        // 隐藏已有的Alert（覆盖显示）
        for subview in window.subviews {
            if let oldAlert = subview as? EGNewBaseAlert {
                if oldAlert.priority != .default && oldAlert.priority.rawValue >= priority.rawValue {
                    return
                } else {
                    oldAlert.dismiss()
                }
            }
        }

        window.addSubview(self)
        self.frame = window.bounds
        showWithAnimation()
        
        Hud.hideIndicator()
    }

    func dismiss() {
        dismissWithAnimation()
    }

    static func existingAlert() -> Bool {
        return existingAlertObj() != nil
    }

    static func existingAlertObj() -> EGNewBaseAlert? {
        //guard let window = UIApplication.shared.windows.first else { return nil }
        guard let window = UIWindow.getTopDisplayWindow() else { return nil }
        return window.subviews.first(where: { $0 is EGNewBaseAlert }) as? EGNewBaseAlert
    }

    static func hideAllAlert() {
        guard let window = UIApplication.shared.windows.first else { return }
        for subview in window.subviews {
            if let alert = subview as? EGNewBaseAlert {
                alert.isHidden = true
                alert.removeFromSuperview()
            }
        }
    }

    func setupMaxActionCount(_ count: Int) {
        maxActionCount = count
    }
}

// MARK: - Then Protocol for Chaining
protocol Then {}
extension Then where Self: AnyObject {
    func then(_ block: (Self) -> Void) -> Self {
        block(self)
        return self
    }
}
extension UIView: Then {}
