//
//  TagFlowLayout.swift
//  Visual_Novel_iOS
//
//  Created by mh on 2025/10/16.
//

import UIKit

final class TagFlowLayout: UICollectionViewLayout {
    // MARK: - 可外部配置
    var maxLineWidth: CGFloat = UIScreen.width - 20.0
    var maxItemWidth: CGFloat = (UIScreen.width - 50.0) / 2.0
    var interItemSpacing: CGFloat = 8
    var lineSpacing: CGFloat = 6
    var sectionInset: UIEdgeInsets = .init(top: 12, left: 20, bottom: 12, right: 10)
    var delegate: TagFlowLayoutDelegate? = nil
    
    // MARK: - 私有缓存
    private var cache: [UICollectionViewLayoutAttributes] = []
    private var contentHeight: CGFloat = 0
    
    override var collectionViewContentSize: CGSize {
        CGSize(width: maxLineWidth, height: contentHeight)
    }
    
    override func prepare() {
        super.prepare()
        guard cache.isEmpty, let cv = collectionView else { return }
        
        contentHeight = sectionInset.top
        var x: CGFloat = sectionInset.left
        var y: CGFloat = sectionInset.top
        var lineHeight: CGFloat = 0
        
        for idx in 0..<cv.numberOfItems(inSection: 0) {
            let indexPath = IndexPath(item: idx, section: 0)
            // 拿 size（走 delegate 或默认）
            let size = delegate?.collectionView(cv, layout: self, sizeForItemAt: indexPath) ??
            CGSize(width: 60, height: 32)
            
            // 换行判断
            if x + size.width + sectionInset.right > maxLineWidth && idx > 0 {
                x = sectionInset.left
                y += lineHeight + lineSpacing
                lineHeight = 0
            }
            
            // 缓存 frame
            let attr = UICollectionViewLayoutAttributes(forCellWith: indexPath)
            attr.frame = CGRect(origin: CGPoint(x: x, y: y), size: size)
            cache.append(attr)
            
            // 更新游标
            x += size.width + interItemSpacing
            lineHeight = max(lineHeight, size.height)
        }
        
        contentHeight = y + lineHeight + sectionInset.bottom
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        cache.filter { $0.frame.intersects(rect) }
    }
    
    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        cache[safe: indexPath.item]
    }
    
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        newBounds.width != maxLineWidth
    }
}

// MARK: - 可选 delegate（动态 size）
protocol TagFlowLayoutDelegate: AnyObject {
    func collectionView(_ collectionView: UICollectionView,
                        layout: TagFlowLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize
}
