//
//  LNMultiSelectionPanel.swift
//  Gami
//
//  Created by OneeChan on 2026/1/20.
//

import Foundation
import UIKit
import SnapKit


class LNMultiSelectionPanel: LNPopupView {
    private var minCount: Int = 0
    private var maxCount: Int = 0
    
    private let titleLabel = UILabel()
    private let descLabel = UILabel()
    private let stackView = LNMultiLineStackView()
    private let confirmButton = UIButton()
    
    private var itemViews: [LNMultiSelectPanelItemView] = []
    private var curSelection: [Int] {
        var indexs: [Int] = []
        for (index, itemView) in itemViews.enumerated() {
            if itemView.isSelected {
                indexs.append(index)
            }
        }
        return indexs
    }
    
    var handler: (([Int]) -> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
    }
    
    func setTitles(_ title: String, desc: String? = nil) {
        titleLabel.text = title
        descLabel.text = desc
        descLabel.isHidden = desc?.isEmpty != false
    }
    
    func update(_ items: [String], curSelected: [String]) {
        var views: [LNMultiSelectPanelItemView] = []
        for item in items {
            let itemView = LNMultiSelectPanelItemView()
            itemView.titleLabel.text = item
            itemView.isSelected = curSelected.contains(item)
            itemView.onTap { [weak self, weak itemView] in
                guard let self, let itemView else { return }
                itemView.isSelected.toggle()
                if maxCount > 0, curSelection.count >= maxCount {
                    itemViews.forEach {
                        $0.isEnable = $0.isSelected
                    }
                } else {
                    itemViews.forEach {
                        $0.isEnable = true
                    }
                }
                updateConfirm()
            }
            
            views.append(itemView)
        }
        
        itemViews = views
        stackView.update(views)
        updateConfirm()
    }
    
    func setLimie(min: Int, max: Int) {
        minCount = min
        maxCount = max
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNMultiSelectionPanel {
    private func updateConfirm() {
        let isEmpty = if minCount > 0 {
            curSelection.count < minCount
        } else {
            curSelection.isEmpty
        }
        if isEmpty == confirmButton.isEnabled {
            confirmButton.isEnabled = !isEmpty
            confirmButton.setBackgroundImage(isEmpty ? nil : .primary_8, for: .normal)
        }
    }
    
    private func setupViews() {
        let headerView = buildHeader()
        container.addSubview(headerView)
        headerView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
            make.height.equalTo(56)
        }
        
        let selection = buildSelection()
        container.addSubview(selection)
        selection.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(21)
            make.top.equalTo(headerView.snp.bottom).offset(16)
        }
        
        confirmButton.setTitle(.init(key: "A00223"), for: .normal)
        confirmButton.setTitleColor(.text_1, for: .normal)
        confirmButton.titleLabel?.font = .heading_h3
        confirmButton.layer.cornerRadius = 23.5
        confirmButton.clipsToBounds = true
        confirmButton.isEnabled = false
        confirmButton.backgroundColor = .fill_4
        confirmButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            dismiss()
            handler?(curSelection)
        }), for: .touchUpInside)
        container.addSubview(confirmButton)
        confirmButton.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalTo(selection.snp.bottom).offset(24)
            make.bottom.equalToSuperview().offset(commonBottomInset)
            make.height.equalTo(47)
        }
    }
    
    private func buildHeader() -> UIView {
        let container = UIView()
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 3
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        titleLabel.font = .heading_h3
        titleLabel.textColor = .text_5
        titleLabel.textAlignment = .center
        stackView.addArrangedSubview(titleLabel)
        
        descLabel.font = .body_s
        descLabel.textColor = .text_3
        descLabel.textAlignment = .center
        stackView.addArrangedSubview(descLabel)
        
        return container
    }
    
    private func buildSelection() -> UIView {
        stackView.columns = 3
        stackView.itemSpacing = 16
        stackView.spacing = 20
        
        return stackView
    }
}

private class LNMultiSelectPanelItemView: UIView {
    let titleLabel = UILabel()
    
    var isSelected: Bool = false {
        didSet {
            backgroundColor = isSelected ? .fill_5 : .fill_1
            titleLabel.font = isSelected ? .heading_h5 : .body_s
            titleLabel.textColor = isSelected ? .text_6 : .text_4
        }
    }
    var isEnable: Bool = true {
        didSet {
            isUserInteractionEnabled = isEnable
            alpha = isEnable ? 1.0 : 0.5
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        layer.cornerRadius = 13
        snp.makeConstraints { make in
            make.height.equalTo(26)
        }
        
        titleLabel.textAlignment = .center
        addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.horizontalEdges.equalToSuperview().inset(7)
        }
        
        isSelected = false
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
