//
//  LNFiveStarScoreView.swift
//  Lanu
//
//  Created by OneeChan on 2025/11/14.
//

import Foundation
import UIKit
import SnapKit


protocol LNFiveStarScoreViewDelegate: AnyObject {
    func onFiveStarScoreView(view: LNFiveStarScoreView, scoreChanged newScore: Double)
}


class LNFiveStarScoreView: UIView {
    private let stackView = UIStackView()
    private var starViews: [LNStarScoreView] = []
    weak var delegate: LNFiveStarScoreViewDelegate? = nil
    
    var score: Double = 0.0 {
        didSet {
            guard oldValue != score else { return }
            let fixed = score.bounded(min: 0.0, max: 5.0)
            for (index, view) in starViews.enumerated() {
                if fixed - 1 > Double(index) {
                    view.score = 1.0
                } else {
                    view.score = fixed - Double(index)
                }
            }
            delegate?.onFiveStarScoreView(view: self, scoreChanged: score)
        }
    }
    var icSize: CGFloat? {
        didSet { starViews.forEach { $0.icSize = icSize } }
    }
    var spacing: CGFloat? {
        didSet { stackView.spacing = spacing ?? 0 }
    }
    var startType: LNStarType = .normal {
        didSet { starViews.forEach { $0.curType = startType } }
    }
    var editable: Bool = false
    
    var unit: Double = 1
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNFiveStarScoreView {
    @objc
    private func handleTap(_ tap: UITapGestureRecognizer) {
        guard editable else { return }
        let position = tap.location(in: self)
        for (index, view) in starViews.enumerated() {
            if CGRectContainsPoint(view.frame, position) {
                let offset = position.x - view.frame.origin.x
                var newScore = offset / view.frame.width
                newScore = ceil(newScore / unit) * unit
                
                score = newScore + Double(index)
                break
            }
        }
    }
}

extension LNFiveStarScoreView {
    private func setupViews() {
        stackView.axis = .horizontal
        stackView.distribution = .equalSpacing
        addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        for _ in 0..<5 {
            let star = LNStarScoreView()
            stackView.addArrangedSubview(star)
            starViews.append(star)
        }
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        addGestureRecognizer(tap)
    }
}

#if DEBUG
 
import SwiftUI

struct LNFiveStarScoreViewPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNFiveStarScoreView()
        view.startType = .whiteBorder
        view.editable = true
        container.addSubview(view)
        view.snp.makeConstraints { make in
            make.leading.centerY.equalToSuperview()
            make.width.equalTo(300)
        }
        view.score = 1.3
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

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

