//
//  ChipButtons.swift

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

import SnapKit
import UIKit

// MARK: - Base Class

class EPChipButton: CLControl {
    // MARK: - Constants

    let chipButtonHeight: CGFloat = 32

    // MARK: - Properties

    lazy var stack: UIStackView = {
        let stack = UIStackView()
        stack.alignment = .fill
        stack.distribution = .fill
        stack.alignment = .center
        stack.axis = .horizontal
        stack.spacing = 8
        return stack
    }()

    lazy var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.isUserInteractionEnabled = true
        return imageView
    }()

    lazy var textLabel: UILabel = {
        let label = UILabel()
        label.font = CLSystemToken.font(token: .tlm)
        label.isUserInteractionEnabled = true
        return label
    }()

    lazy var iconView: UIImageView = {
        let iconView = UIImageView()
        iconView.contentMode = .scaleAspectFit
        iconView.isUserInteractionEnabled = true
        return iconView
    }()

    var text: String? {
        didSet {
            textLabel.text = text
            setNeedsLayout()
        }
    }

    var iconCode: IconCode = .sort {
        didSet {
            iconView.isHidden = (iconCode.rawValue <= 0)
            iconView.image = defaultIcon
        }
    }

    var defaultIconColor: UIColor? {
        didSet {
            iconView.image = defaultIcon
        }
    }

    var defaultIcon: UIImage? {
        let color = defaultIconColor ?? UIColor.c.ctsn
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    var selectedIcon: UIImage? {
        nil // Subclasses override
    }

    var defaultImage: UIImage? {
        nil // Subclasses override
    }

    var selectedImage: UIImage? {
        nil // Subclasses override
    }

    var paddingInsets: UIEdgeInsets {
        .zero // Subclasses override
    }

    var iconSize: CGSize {
        .zero // Subclasses override
    }

    var imageSize: CGSize {
        .zero // Subclasses override
    }

    // MARK: - Initialization

    override init(frame: CGRect) {
        super.init(frame: frame)
        clipsToBounds = true
        layer.cornerRadius = chipButtonHeight * 0.5

        setupTheme()
    }

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

    // MARK: - Setup

    func setupTheme() {
        textLabel.textColor = .c.ctpn // EPSystemToken.color(.txtPrimaryNormal)
    }

    // MARK: - Hit Testing

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard isUserInteractionEnabled, alpha != 0, !isHidden else { return nil }

        if self.point(inside: point, with: event) {
            return self
        }
        return super.hitTest(point, with: event)
    }
}

// MARK: - EPChipFilterButton

/// 只有文字，左右16。 height 32
class EPChipFilterButton: EPChipButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .c.csen // EPSystemToken.color(.surfaceElementNormal)
        layer.borderWidth = 0

        addSubview(textLabel)
        textLabel.snp.makeConstraints { make in
            make.edges.equalTo(self).inset(paddingInsets).priority(.high)
            make.height.equalTo(chipButtonHeight)
        }
    }

    override func setupTheme() {
        super.setupTheme()
        layer.borderColor = UIColor.c.cpvn.cgColor // EPSystemToken.color(.primaryVariantNormal).cgColor
    }

    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
    }
    
    override var intrinsicContentSize: CGSize{
        return CGSize(width: textLabel.size.width + 32, height: chipButtonHeight)
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = isSelected
                ? (isHighlighted ? UIColor.c.cpp : UIColor.c.cpn)
                : (isHighlighted ? UIColor.c.csep : UIColor.c.csen)
        }
    }

    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected
                ? UIColor.c.cpn
                : UIColor.c.csen
            layer.borderWidth = isSelected ? 1 : 0
        }
    }

    override var isEnabled: Bool {
        didSet {
            textLabel.textColor = isEnabled
                ? UIColor.c.ctpn
                : UIColor.c.ctd
            backgroundColor = isEnabled
                ? UIColor.c.csen
                : UIColor.c.csed
        }
    }
}

class EPRoleTagsFilterButton: EPChipButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor(hex: "#BAC5D2") // EPSystemToken.color(.surfaceElementNormal)
        layer.borderWidth = 0

        addSubview(textLabel)
        textLabel.snp.makeConstraints { make in
            make.edges.equalTo(self).inset(paddingInsets).priority(.high)
            make.height.equalTo(chipButtonHeight)
        }
    }

    override func setupTheme() {
        super.setupTheme()
        layer.borderColor = UIColor(hex: "#0065FF").cgColor // EPSystemToken.color(.primaryVariantNormal).cgColor
    }

    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
    }
    
    override var intrinsicContentSize: CGSize{
        return CGSize(width: textLabel.size.width + 32, height: chipButtonHeight)
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = isSelected
                ? (isHighlighted ? UIColor(hex: "#BAC5D2") : UIColor(hex: "#0065FF"))
                : (isHighlighted ? UIColor(hex: "#0065FF") : UIColor(hex: "#BAC5D2"))
        }
    }

    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected
                ? UIColor(hex: "#0065FF")
                : UIColor(hex: "#BAC5D2")
            layer.borderWidth = isSelected ? 1 : 0
        }
    }

    override var isEnabled: Bool {
        didSet {
            textLabel.textColor = isEnabled
                ? UIColor.white
                : UIColor(hex: "#E5F1FF")
            backgroundColor = isEnabled
                ? UIColor.c.csen
                : UIColor.c.csed
        }
    }
}

class EPChipCenterIconButton: EPChipButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .c.csen // EPSystemToken.color(.surfaceElementNormal)
        layer.borderWidth = 0
        defaultIconColor = .c.ctpn

        addSubview(iconView)
        iconView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            // make.height.equalTo(chipButtonHeight)
        }
    }

    override func setupTheme() {
        super.setupTheme()
        layer.borderColor = UIColor.c.cpvn.cgColor // EPSystemToken.color(.primaryVariantNormal).cgColor
    }

    override var iconSize: CGSize {
        return .init(width: 20, height: 20)
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = isSelected
                ? (isHighlighted ? UIColor.c.cpp : UIColor.c.cpn)
                : (isHighlighted ? UIColor.c.csep : UIColor.c.csen)
        }
    }

    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected
                ? UIColor.c.cpn
                : UIColor.c.csen
            layer.borderWidth = isSelected ? 1 : 0
        }
    }

    override var isEnabled: Bool {
        didSet {
            textLabel.textColor = isEnabled
                ? UIColor.c.ctpn
                : UIColor.c.ctd
            backgroundColor = isEnabled
                ? UIColor.c.csen
                : UIColor.c.csed
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.size.height * 0.5
    }
}

// MARK: - EPChipDropdownButton

class EPChipDropdownButton: EPChipButton {
    var needTransform: Bool = true

    override init(frame: CGRect) {
        super.init(frame: frame)
        stack.spacing = 4

        addSubview(stack)
        stack.snp.makeConstraints { make in
            make.edges.equalTo(self).inset(paddingInsets)
            make.height.equalTo(chipButtonHeight)
        }

        stack.addArrangedSubview(textLabel)
        stack.addArrangedSubview(iconView)
        iconView.snp.makeConstraints { make in
            make.size.equalTo(iconSize)
        }
    }

    override func setupTheme() {
        super.setupTheme()
        textLabel.textColor = isSelected
            ? UIColor.c.cpvn
            : UIColor.c.ctpn
        iconView.image = isSelected ? selectedIcon : defaultIcon
    }

    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 8)
    }

    override var iconSize: CGSize {
        CGSize(width: 12, height: 12)
    }

    override var defaultIcon: UIImage? {
        let color = UIColor.c.ctsn // EPSystemToken.color(.txtSecondaryNormal)
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    override var selectedIcon: UIImage? {
        let color = UIColor.c.cpvn // EPSystemToken.color(.primaryVariantNormal)
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = isHighlighted ? UIColor.c.csep : nil
        }
    }

    override var isSelected: Bool {
        didSet {
            textLabel.textColor = isSelected
                ? UIColor.c.cpvn
                : UIColor.c.ctpn

            UIView.animate(withDuration: 0.2) {
                if self.needTransform {
                    self.iconView.transform = self.isSelected ? CGAffineTransform(rotationAngle: .pi) : .identity
                }
                self.iconView.image = self.isSelected ? self.selectedIcon : self.defaultIcon
            }
        }
    }
}

// MARK: - EPChipRemovableButton

class EPChipRemovableButton: EPChipButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        stack.spacing = 8

        addSubview(stack)
        stack.snp.makeConstraints { make in
            make.edges.equalTo(self).inset(paddingInsets).priority(998)
            make.height.equalTo(chipButtonHeight)
        }

        stack.addArrangedSubview(textLabel)
        stack.addArrangedSubview(iconView)
        iconView.snp.makeConstraints { make in
            make.size.equalTo(iconSize)
        }
    }

    override func setupTheme() {
        super.setupTheme()
        backgroundColor = .c.csen
        iconView.image = defaultIcon
    }

    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
    }

    override var iconSize: CGSize {
        CGSize(width: 16, height: 16)
    }

    override var defaultIcon: UIImage? {
        let color = UIColor.c.ctsn // EPSystemToken.color(.txtSecondaryNormal)
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    override var selectedIcon: UIImage? {
        let color = UIColor.c.cpvn
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = isHighlighted
                ? UIColor.c.csep
                : UIColor.c.csen
        }
    }

    func widthPreCal(tagHeight: CGFloat) -> CGFloat {
        let paddingInsets = self.paddingInsets
        return textLabel.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: tagHeight)).width +
            paddingInsets.left + paddingInsets.right + iconSize.width + stack.spacing
    }

    func setupHasImageMode() {
        stack.insertArrangedSubview(imageView, at: 0)
        imageView.isHidden = false
        imageView.snp.makeConstraints { make in
            make.size.equalTo(imageSize)
        }
    }
}

// MARK: - EPChipAssistButton

/// 图标在左，文字在右（用处eg：Interests添加页面Add按钮）
class EPChipAssistButton: EPChipButton {
    var iconTextSpacing: CGFloat = 8 {
        didSet {
            stack.spacing = iconTextSpacing
        }
    }

    var buttonHeight: CGFloat = 32 {
        didSet {
            layer.cornerRadius = buttonHeight * 0.5
            stack.snp.updateConstraints { make in
                make.height.equalTo(buttonHeight)
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        stack.spacing = 8

        addSubview(stack)
        stack.snp.makeConstraints { make in
            make.edges.equalTo(self).inset(paddingInsets)
            make.height.equalTo(chipButtonHeight)
        }

        stack.addArrangedSubview(iconView)
        stack.addArrangedSubview(textLabel)
        iconView.snp.makeConstraints { make in
            make.size.equalTo(iconSize)
        }
    }

    override func setupTheme() {
        super.setupTheme()
        backgroundColor = .c.csen // EPSystemToken.color(.surfaceElementNormal)
        iconView.image = defaultIcon
    }

    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
    }

    override var iconSize: CGSize {
        CGSize(width: 16, height: 16)
    }

    override var defaultIcon: UIImage? {
        let color = defaultIconColor ?? UIColor.c.ctsn // EPSystemToken.color(.txtSecondaryNormal)
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

//    override var isHighlighted: Bool {
//        didSet {
//            backgroundColor = isHighlighted
//                ? UIColor.c.csep
//                : UIColor.c.csen
//        }
//    }
    
    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected
                ? UIColor.c.cpn
                : UIColor.c.csen
            //layer.borderWidth = isSelected ? 1 : 0
        }
    }

    func setDefaultImage(_ image: UIImage?) {
        iconView.image = image
    }

    func setIconSize(_ size: CGSize) {
        iconView.snp.updateConstraints { make in
            make.size.equalTo(size)
        }
    }

    func widthPreCal(tagHeight: CGFloat) -> CGFloat {
        let paddingInsets = self.paddingInsets
        return textLabel.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: tagHeight)).width +
            paddingInsets.left + paddingInsets.right + iconSize.width + stack.spacing
    }
}

// MARK: - EPChipContrastButton:EPChipAssistButton
/// Like EPIconContrastTertiaryButton的加文字版本, 特别处理
class EPChipContrastButton:EPChipAssistButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .c.csedn
        buttonHeight = 48
        defaultIconColor = .white
        textLabel.font = .t.tll
    }
    
    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 32, bottom: 0, right: 32)
    }
    
    override var iconSize: CGSize {
        CGSize(width: 24, height: 24)
    }
}


// MARK: - EPChipImageIconButton

/// 左边image+中间文字+右边iconFont
class EPChipImageIconButton: EPChipFilterButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        stack.spacing = 8

        addSubview(stack)
        stack.snp.makeConstraints { make in
            make.edges.equalTo(self).inset(paddingInsets)
            make.height.equalTo(chipButtonHeight)
        }

        stack.addArrangedSubview(imageView)
        stack.addArrangedSubview(textLabel)
        stack.addArrangedSubview(iconView)
        imageView.snp.makeConstraints { make in
            make.size.equalTo(imageSize)
        }
        iconView.snp.makeConstraints { make in
            make.size.equalTo(iconSize)
        }

        imageView.isHidden = true
        iconView.isHidden = true
    }

    override var paddingInsets: UIEdgeInsets {
        UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
    }

    override var iconSize: CGSize {
        CGSize(width: 16, height: 16)
    }

    override var imageSize: CGSize {
        CGSize(width: 16, height: 16)
    }

    override var defaultIcon: UIImage? {
        let color = UIColor.c.ctsn // EPSystemToken.color(.txtSecondaryNormal)
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    override var selectedIcon: UIImage? {
        let color = UIColor.c.cswn // EPSystemToken.color(.surfaceWhiteNormal)
        return MWIconFont.image(fromIconInt: iconCode.rawValue, size: iconSize, color: color, edgeInsets: .zero)
    }

    override var isSelected: Bool {
        didSet {
            iconView.image = isSelected ? selectedIcon : defaultIcon
            imageView.image = isSelected ? selectedImage : defaultImage
        }
    }

    func reloadPadding(showImage: Bool, showIcon: Bool) {
        var leftPadding: CGFloat = 16
        var rightPadding: CGFloat = 16
        if showImage {
            leftPadding = 12
        }
        if showIcon {
            rightPadding = 12
        }
        stack.snp.remakeConstraints { make in
            make.edges.equalTo(self).inset(UIEdgeInsets(top: 0, left: leftPadding, bottom: 0, right: rightPadding))
            make.height.equalTo(chipButtonHeight)
        }
    }
}
