//
//  LNMultiLineStackView.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/14.
//

import Foundation
import UIKit
import SnapKit


class LNMultiLineStackView: UIStackView {
    var columns: Int = 0
    var itemDistribution: UIStackView.Distribution = .fillEqually
    var itemSpacing: CGFloat = 0
    
    private var lineViews: [UIStackView] = []
    private(set) var curItemViews: [UIView] = []
    private var emptyView: [UIView] = []
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        axis = .vertical
    }
    
    func update(_ itemViews: [UIView]) {
        arrangedSubviews.forEach {
            removeArrangedSubview($0)
            $0.removeFromSuperview()
        }
        lineViews.removeAll()
        curItemViews.removeAll()
        emptyView.removeAll()
        
        if itemViews.isEmpty { return }
        
        var line = buildLine()
        itemViews.forEach {
            if $0.isHidden {
                return
            }
            if line.arrangedSubviews.count == columns {
                line = buildLine()
            }
            line.addArrangedSubview($0)
            curItemViews.append($0)
        }
        fillLastLine()
    }
    
    func append(_ itemViews: [UIView]) {
        var last = lineViews.last ?? buildLine()
        emptyView.forEach {
            last.removeArrangedSubview($0)
            $0.removeFromSuperview()
        }
        itemViews.forEach {
            if $0.isHidden {
                return
            }
            if last.arrangedSubviews.count == columns {
                last = buildLine()
            }
            last.addArrangedSubview($0)
            curItemViews.append($0)
        }
        fillLastLine()
    }
    
    func remove(_ itemViews: [UIView]) {
        curItemViews.removeAll {
            itemViews.contains($0)
        }
        update(curItemViews)
    }
    
    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNMultiLineStackView {
    private func fillLastLine() {
        if lineViews.isEmpty { return }
        guard let last = lineViews.last else { return }
        guard last.arrangedSubviews.count < columns else { return }
        
        for _ in last.arrangedSubviews.count..<columns {
            let empty = UIView()
            last.addArrangedSubview(empty)
            if itemDistribution == .equalSpacing
                || itemDistribution == .equalCentering {
                empty.snp.makeConstraints { make in
                    make.width.equalTo(last.arrangedSubviews[0])
                }
            }
            
            emptyView.append(empty)
        }
    }
    
    private func buildLine() -> UIStackView {
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.distribution = itemDistribution
        stackView.spacing = itemSpacing
        
        lineViews.append(stackView)
        addArrangedSubview(stackView)
        
        return stackView
    }
}

#if DEBUG

import SwiftUI

struct LNMultiLineStackViewPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNMultiLineStackView()
        view.backgroundColor = .orange
        container.addSubview(view)
        view.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview()
            make.centerY.equalToSuperview()
        }
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

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

