//
//  LNGameMateFilterPanel.swift
//  Lanu
//
//  Created by OneeChan on 2025/11/18.
//

import Foundation
import UIKit
import SnapKit


protocol LNGameMateFilterPanelDelegate: AnyObject {
    func onGameMateFilterPanel(panel: LNGameMateFilterPanel, filterGame filter: LNGameMateFilter)
}


class LNGameMateFilterPanel: UIView {
    private let columns = 4
    private let stackView = UIStackView()
    private var curFilter: LNGameMateFilter?
    private var curGame: LNGameCategoryItemVO?
    
    weak var delegate: LNGameMateFilterPanelDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
    }
    
    func update(game: LNGameCategoryItemVO, filter: LNGameMateFilter) {
        let old = stackView.arrangedSubviews
        old.forEach {
            stackView.removeArrangedSubview($0)
            $0.removeFromSuperview()
        }
        
        let gender = buildFilterSection(title: .init(key: "A00032"), filters: LNGameMateGenderRange.allCases.map({ $0.text }), selected: LNGameMateGenderRange.allCases.firstIndex(of: filter.gender)!) { [weak self] index in
            guard let self else { return }
            curFilter?.gender = LNGameMateGenderRange.allCases[index]
        }
        stackView.addArrangedSubview(gender)
        
        let age = buildFilterSection(title: .init(key: "A00033"), filters: LNGameMateAgeRange.allCases.map({ $0.text }), selected: LNGameMateAgeRange.allCases.firstIndex(of: filter.ageRange)!) { [weak self] index in
            guard let self else { return }
            curFilter?.ageRange = LNGameMateAgeRange.allCases[index]
        }
        stackView.addArrangedSubview(age)
        
        let areas = LNConfigManager.shared.commonConfig.commonAreaConsts
        if !areas.isEmpty {
            let areaView = buildFilterSection(title: .init(key: "A00017"), filters: areas.map({ $0.name }), selected: areas.firstIndex(where: { $0.code == filter.areCode }) ?? 0) { [weak self] index in
                guard let self else { return }
                curFilter?.areCode = areas[index].code
            }
            stackView.addArrangedSubview(areaView)
        }
        
        let score = buildFilterSection(title: .init(key: "A00034"), filters: LNSortedType.allCases.map({ $0.text }), selected: LNSortedType.allCases.firstIndex(of: filter.sortByStar)!) { [weak self] index in
            guard let self else { return }
            curFilter?.sortByStar = LNSortedType.allCases[index]
        }
        stackView.addArrangedSubview(score)
        
        let price = buildFilterSection(title: .init(key: "A00035"), filters: LNGameMatePriceRange.allCases.map({ $0.text }), selected: LNGameMatePriceRange.allCases.firstIndex(of: filter.priceRange)!) { [weak self] index in
            guard let self else { return }
            curFilter?.priceRange = LNGameMatePriceRange.allCases[index]
        }
        stackView.addArrangedSubview(price)
        
        for item in LNGameMateManager.shared.gameFilter(for: game.code) {
            let curSelect = filter.categoryFilters.first { $0.fieldCode == item.fieldCode }?.filterValues.first
            let index = item.constants.firstIndex { $0.value == curSelect } ?? 0
            var filters = item.constants.map({ $0.value })
            filters.insert(.init(key: "A00008"), at: 0) // 手动插入"无限制"选项
            let filterSection = buildFilterSection(title: item.name, filters: filters, selected: index)
            { [weak self] index in
                guard let self else { return }
                
                curFilter?.categoryFilters.removeAll { $0.fieldCode == item.fieldCode }
                if index != 0 { // 0 为"无限制"，不需要填充值
                    curFilter?.categoryFilters.append((item.fieldCode, [item.constants[index - 1].key]))
                }
            }
            stackView.addArrangedSubview(filterSection)
        }
        
        
        curFilter = filter
        curGame = game
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNGameMateFilterPanel {
    private func setupViews() {
        let container = UIView()
        container.layer.cornerRadius = 20
        container.backgroundColor = .fill
        addSubview(container)
        container.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview()
        }
        
        let scrollView = UIScrollView()
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        container.addSubview(scrollView)
        scrollView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(14)
        }
        
        stackView.axis = .vertical
        stackView.spacing = 12
        scrollView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.width.equalToSuperview()
        }
        
        let confirmButton = UIButton()
        confirmButton.setTitle(.init(key: "A00002"), for: .normal)
        confirmButton.setTitleColor(.text_1, for: .normal)
        confirmButton.titleLabel?.font = .heading_h3
        confirmButton.setBackgroundImage(UIImage.primary_8, for: .normal)
        confirmButton.layer.cornerRadius = 23.5
        confirmButton.clipsToBounds = true
        confirmButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curFilter else { return }
            delegate?.onGameMateFilterPanel(panel: self, filterGame: curFilter)
        }), for: .touchUpInside)
        addSubview(confirmButton)
        confirmButton.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(16)
            make.top.equalTo(container.snp.bottom).offset(8)
            make.bottom.equalToSuperview()
            make.height.equalTo(47)
            make.width.equalToSuperview().multipliedBy(0.6)
        }
        
        let resetButton = UIButton()
        resetButton.setTitle(.init(key: "A00036"), for: .normal)
        resetButton.setTitleColor(.text_4, for: .normal)
        resetButton.titleLabel?.font = .body_l
        resetButton.layer.cornerRadius = 23.5
        resetButton.layer.borderWidth = 1
        resetButton.layer.borderColor = UIColor.fill_4.cgColor
        resetButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curGame else { return }
            update(game: curGame, filter: LNGameMateFilter())
        }), for: .touchUpInside)
        addSubview(resetButton)
        resetButton.snp.makeConstraints { make in
            make.centerY.equalTo(confirmButton)
            make.leading.equalToSuperview().offset(16)
            make.trailing.equalTo(confirmButton.snp.leading).offset(-10)
            make.height.equalTo(47)
        }
    }
    
    private func buildFilterSection(
        title: String, filters: [String], selected: Int,
        handler: @escaping (Int) -> Void) -> UIView
    {
        let container = UIStackView()
        container.axis = .vertical
        container.spacing = 6
        
        let titleLabel = UILabel()
        titleLabel.text = title
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_5
        container.addArrangedSubview(titleLabel)
        
        var itemViews: [LNGameMateFilterItemView] = []
        let stackView = LNMultiLineStackView()
        stackView.itemSpacing = 8
        stackView.itemDistribution = .fillEqually
        stackView.columns = 4
        stackView.spacing = 6
        container.addArrangedSubview(stackView)
        for (index, type) in filters.enumerated() {
            let itemView = LNGameMateFilterItemView()
            itemView.titleLabel.text = type
            itemView.onTap { [weak self, weak itemView] in
                guard self != nil, let itemView else { return }
                itemViews.forEach {
                    $0.showHighLight($0 == itemView)
                }
                handler(index)
            }
            itemView.showHighLight(selected == index)
            itemViews.append(itemView)
        }
        stackView.update(itemViews)
        
        return container
    }
}

private class LNGameMateFilterItemView: UIView {
    let titleLabel = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        layer.cornerRadius = 12
        snp.makeConstraints { make in
            make.height.equalTo(24)
        }
        
        titleLabel.textAlignment = .center
        addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(8)
            make.centerY.equalToSuperview()
        }
        
        showHighLight(false)
    }
    
    func showHighLight(_ highLight: Bool) {
        backgroundColor = highLight ? .fill_5 : .fill_1
        titleLabel.textColor = highLight ? .text_6 : .text_4
        titleLabel.font = highLight ? .heading_h5 : .body_xs
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
}

#if DEBUG

import SwiftUI

struct LNGameMateFilterPanelPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNGameMateFilterPanel()
        container.addSubview(view)
        view.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
            make.height.equalToSuperview().multipliedBy(0.6)
        }
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

#Preview(body: {
    LNGameMateFilterPanelPreview()
})
#endif

