//
//  ChatFontCell.swift
//  Visual_Novel_iOS
//
//  Created by mh on 2025/10/27.
//

import UIKit
import SnapKit

//  font
struct FontRow: RowModel {
    let count: String
    let icon: String
    let title: String
    var cellReuseID: String { "ChatFontCell" }
    func cellHeight(tableWidth: CGFloat) -> CGFloat { 80 }
}
 
class ChatFontCell: ChatSettingBaseCell, CellConfigurable {
    
    private var currentFontSize: Int = 20
    private let minFontSize: Int = 10
    private let maxFontSize: Int = 30
    
    lazy var iconImgView: UIImageView = {
        let imgView = UIImageView(image: UIImage(named: "role_font"))
        return imgView
    }()
    
    lazy var titleLab: UILabel = {
        let lab = UILabel()
        lab.text = "Font size"
        lab.font = UIFont.systemFont(ofSize: 14)
        lab.textColor = UIColor(hex: "#666666")
        return lab
    }()
    
    lazy var fontSizeLab: UILabel = {
        let lab = UILabel()
        lab.text = "20"
        lab.font = UIFont.systemFont(ofSize: 14)
        lab.textColor = UIColor(hex: "#999999")
        lab.textAlignment = .right
        return lab
    }()
    
    lazy var sliderContainer: UIView = {
        let view = UIView()
        return view
    }()
    
    lazy var minusButton: UIButton = {
        let btn = UIButton(type: .custom)
        // 优先使用图片，否则显示蓝色文字
        if let image = UIImage(named: "role_setting_font_sub") {
            btn.setImage(image, for: .normal)
        } else {
            btn.setTitle("A-", for: .normal)
            btn.setTitleColor(UIColor(hex: "#0066FF"), for: .normal)
            btn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
        }
        btn.addTarget(self, action: #selector(decreaseFontSize), for: .touchUpInside)
        return btn
    }()
    
    lazy var plusButton: UIButton = {
        let btn = UIButton(type: .custom)
        // 优先使用图片，否则显示蓝色文字
        if let image = UIImage(named: "role_setting_font_add") {
            btn.setImage(image, for: .normal)
        } else {
            btn.setTitle("A+", for: .normal)
            btn.setTitleColor(UIColor(hex: "#0066FF"), for: .normal)
            btn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
        }
        btn.addTarget(self, action: #selector(increaseFontSize), for: .touchUpInside)
        return btn
    }()
    
    lazy var slider: UISlider = {
        let slider = UISlider()
        slider.minimumValue = Float(minFontSize)
        slider.maximumValue = Float(maxFontSize)
        slider.value = Float(currentFontSize)
        
        // 隐藏默认的 track，我们将用自定义视图绘制
        slider.minimumTrackTintColor = .clear
        slider.maximumTrackTintColor = .clear
        
        // 自定义白色圆形 thumb
        let thumbSize: CGFloat = 20
        UIGraphicsBeginImageContextWithOptions(CGSize(width: thumbSize, height: thumbSize), false, 0.0)
        if let context = UIGraphicsGetCurrentContext() {
            context.setFillColor(UIColor.white.cgColor)
            context.fillEllipse(in: CGRect(x: 0, y: 0, width: thumbSize, height: thumbSize))
            // 添加轻微阴影效果
            context.setShadow(offset: CGSize(width: 0, height: 1), blur: 2, color: UIColor.black.withAlphaComponent(0.15).cgColor)
            context.fillEllipse(in: CGRect(x: 0, y: 0, width: thumbSize, height: thumbSize))
        }
        let thumbImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        slider.setThumbImage(thumbImage, for: .normal)
        slider.setThumbImage(thumbImage, for: .highlighted)
        
        // 添加所有相关的事件监听
        slider.addTarget(self, action: #selector(sliderValueChanged(_:)), for: .valueChanged)
        slider.addTarget(self, action: #selector(sliderTouchDown(_:)), for: .touchDown)
        slider.addTarget(self, action: #selector(sliderTouchUp(_:)), for: [.touchUpInside, .touchUpOutside])
        
        return slider
    }()
    
    // 自定义轨道视图：绘制横线和竖线
    private lazy var customTrackView: UIView = {
        let view = UIView()
        view.backgroundColor = .clear
        view.isUserInteractionEnabled = false // 不拦截触摸事件
        return view
    }()
    
    // 横线视图（高度为 5pt）
    private lazy var trackLine: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(hex: "#A4A8B7")
        return view
    }()
    
    // 5 个小竖线，每个 5*11
    private var tickMarks: [UIView] = []
    private var isTickMarksCreated = false
    private var isDragging = false
    private var dragStartValue: Float = 0 // 拖动开始时的值
    private var dragStartTickIndex: Int = 0 // 拖动开始时的刻度索引
    private var currentSnappedTickIndex: Int = 0 // 当前吸附到的刻度索引
    private var lastGestureValue: Float = 0 // 上一次手势的值，用于检测手势方向
    
    // 5 个刻度对应的字体大小值
    private var tickValues: [Int] {
        let step = (maxFontSize - minFontSize) / 4 // 5个刻度，4个间隔
        return (0...4).map { minFontSize + $0 * step }
    }
    
    func configure(with row: RowModel) {
        guard let row = row as? FontRow else { return }
        titleLab.text = row.title
        iconImgView.image = UIImage(named: row.icon)
        
        // 更新容器高度
        updateContainerHeight(80)
        
        if let size = Int(row.count) {
            currentFontSize = max(minFontSize, min(maxFontSize, size))
            // 对齐到最近的刻度位置
            currentFontSize = alignToNearestTick(currentFontSize)
            updateFontSize(currentFontSize, updateSlider: true)
        }
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configureViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configureViews() {
        containerView.addSubview(iconImgView)
        containerView.addSubview(titleLab)
        containerView.addSubview(fontSizeLab)
        containerView.addSubview(sliderContainer)
        
        // 添加顺序很重要：先添加自定义轨道视图，再添加 slider
        sliderContainer.addSubview(minusButton)
        sliderContainer.addSubview(plusButton)
        sliderContainer.addSubview(customTrackView)
        customTrackView.addSubview(trackLine)
        sliderContainer.addSubview(slider)
        
        // 确保竖线在横线之上，但不拦截触摸事件
        // 竖线会在 setupTrackAndTickMarks() 中添加到 customTrackView
        
        iconImgView.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(12)
            make.left.equalToSuperview().offset(12)
            make.width.height.equalTo(21)
        }
        
        titleLab.snp.makeConstraints { make in
            make.centerY.equalTo(iconImgView)
            make.left.equalTo(iconImgView.snp.right).offset(9)
        }
        
        fontSizeLab.snp.makeConstraints { make in
            make.centerY.equalTo(iconImgView)
            make.right.equalToSuperview().inset(20)
        }
        
        sliderContainer.snp.makeConstraints { make in
            make.top.equalTo(iconImgView.snp.bottom).offset(12)
            make.left.right.equalToSuperview().inset(12)
            make.bottom.equalToSuperview().inset(12)
            make.height.equalTo(30)
        }
        
        minusButton.snp.makeConstraints { make in
            make.left.centerY.equalToSuperview()
            make.width.equalTo(30)
        }
        
        plusButton.snp.makeConstraints { make in
            make.right.centerY.equalToSuperview()
            make.width.equalTo(30)
        }
        
        slider.snp.makeConstraints { make in
            make.left.equalTo(minusButton.snp.right).offset(8)
            make.right.equalTo(plusButton.snp.left).offset(-8)
            make.centerY.equalToSuperview()
            make.height.equalTo(30)
        }
        
        // 自定义轨道视图：覆盖 slider 的 track 区域
        customTrackView.snp.makeConstraints { make in
            make.left.right.equalTo(slider)
            make.centerY.equalTo(slider)
            make.height.equalTo(11) // 确保能容纳 11pt 高的竖线
        }
        
        // 横线：高度为 5pt，垂直居中
        trackLine.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.centerY.equalToSuperview()
            make.height.equalTo(5)
        }
    }
    
    private func setupTrackAndTickMarks() {
        guard !isTickMarksCreated else { return }
        
        // 创建 5 个小竖线（5*11），均匀分布在横线上
        let tickCount = 5
        for _ in 0..<tickCount {
            let tick = UIView()
            tick.backgroundColor = UIColor(hex: "#A4A8B7")
            tick.isUserInteractionEnabled = false // 不拦截触摸
            // 设置上下圆角
            tick.layer.cornerRadius = 2.5 // 宽度是5，所以圆角半径是2.5
            tick.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
            customTrackView.addSubview(tick)
            tickMarks.append(tick)
        }
        isTickMarksCreated = true
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 确保竖线已创建（在 bounds 确定后）
        if customTrackView.bounds.width > 0 {
            setupTrackAndTickMarks()
            // 重新布局竖线（在 layout 完成后）
            updateTickMarksLayout()
            // 强制设置竖线的 isHidden 为 false，确保显示
            tickMarks.forEach { $0.isHidden = false }
        }
    }
    
    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        // 当视图添加到父视图后，延迟确保竖线显示
        if superview != nil {
            DispatchQueue.main.async { [weak self] in
                self?.ensureTickMarksVisible()
            }
        }
    }
    
    private func ensureTickMarksVisible() {
        if customTrackView.bounds.width > 0 && !isTickMarksCreated {
            setupTrackAndTickMarks()
        }
        updateTickMarksLayout()
        // 强制显示竖线
        tickMarks.forEach { 
            $0.isHidden = false
            $0.backgroundColor = UIColor(hex: "#A4A8B7")
        }
    }
    
    private func updateTickMarksLayout() {
        guard customTrackView.bounds.width > 0 else { return }
        let totalWidth = customTrackView.bounds.width
        // 5 个竖线，等分横线，需要 4 个间隔
        let spacing = totalWidth / 4.0
        let tickWidth: CGFloat = 5
        let tickHeight: CGFloat = 11
        let centerY = customTrackView.bounds.height / 2.0
        
        for (index, tick) in tickMarks.enumerated() {
            let centerX = CGFloat(index) * spacing
            tick.frame = CGRect(
                x: centerX - tickWidth / 2.0,
                y: centerY - tickHeight / 2.0,
                width: tickWidth,
                height: tickHeight
            )
            tick.isHidden = false // 确保显示
        }
    }
    
    // 根据 slider 值计算对应的刻度索引
    private func tickIndexForValue(_ value: Float) -> Int {
        let normalizedValue = (value - Float(minFontSize)) / Float(maxFontSize - minFontSize)
        let index = Int(round(normalizedValue * 4)) // 0-4
        return max(0, min(4, index))
    }
    
    // 根据刻度索引获取对应的 slider 值
    private func valueForTickIndex(_ index: Int) -> Float {
        guard index >= 0 && index < tickValues.count else { return Float(currentFontSize) }
        return Float(tickValues[index])
    }
    
    // 对齐到最近的刻度值
    private func alignToNearestTick(_ value: Int) -> Int {
        return tickValues.min(by: { abs($0 - value) < abs($1 - value) }) ?? value
    }
    
    // 获取当前刻度索引
    private func currentTickIndex() -> Int {
        if let index = tickValues.firstIndex(of: currentFontSize) {
            return index
        }
        // 如果当前值不在刻度上，找到最近的
        let nearest = alignToNearestTick(currentFontSize)
        return tickValues.firstIndex(of: nearest) ?? 2 // 默认中间位置
    }
    
    @objc private func decreaseFontSize() {
        let currentIndex = currentTickIndex()
        if currentIndex > 0 {
            currentFontSize = tickValues[currentIndex - 1]
            updateFontSize(currentFontSize, updateSlider: true)
        }
    }
    
    @objc private func increaseFontSize() {
        let currentIndex = currentTickIndex()
        if currentIndex < tickValues.count - 1 {
            currentFontSize = tickValues[currentIndex + 1]
            updateFontSize(currentFontSize, updateSlider: true)
        }
    }
    
    @objc private func sliderValueChanged(_ slider: UISlider) {
        guard isDragging else { return }
        
        // 手势拖动时，白色圆圈不跟随手势，保持在当前刻度位置
        // 计算从当前吸附位置到手势位置的距离（以刻度为单位）
        let currentGestureValue = slider.value
        let snappedValue = valueForTickIndex(currentSnappedTickIndex)
        let valueDelta = currentGestureValue - snappedValue
        let range = Float(maxFontSize - minFontSize)
        let tickDelta = valueDelta / (range / 4.0) // 转换为刻度单位（0-4的范围）
        
        // 阈值：两个竖线一半距离 = 0.5 个刻度的距离
        let threshold: Float = 0.5
        
        // 判断是否超过阈值，需要跳动到下一个刻度
        var targetTickIndex = currentSnappedTickIndex
        if tickDelta > threshold && currentSnappedTickIndex < 4 {
            // 向右滑动超过阈值，跳动到下一个刻度
            targetTickIndex = currentSnappedTickIndex + 1
        } else if tickDelta < -threshold && currentSnappedTickIndex > 0 {
            // 向左滑动超过阈值，跳动到上一个刻度
            targetTickIndex = currentSnappedTickIndex - 1
        }
        
        // 如果目标刻度发生了变化，立即跳动
        if targetTickIndex != currentSnappedTickIndex {
            let targetValue = valueForTickIndex(targetTickIndex)
            // 使用 UIView.performWithoutAnimation 避免动画
            UIView.performWithoutAnimation {
                slider.setValue(targetValue, animated: false) // 立即跳动到新位置
            }
            currentFontSize = tickValues[targetTickIndex]
            fontSizeLab.text = "\(currentFontSize)"
            // 更新吸附位置和手势值，为下一次跳动做准备
            currentSnappedTickIndex = targetTickIndex
            lastGestureValue = targetValue
        } else {
            // 未超过阈值，白色圆圈保持不动，slider 值回到当前刻度位置
            // 但要允许手势继续，所以不立即重置，而是延迟检查
            if abs(currentGestureValue - snappedValue) > 0.01 {
                // 只有当差值较大时才重置，避免频繁设置
                UIView.performWithoutAnimation {
                    slider.setValue(snappedValue, animated: false)
                }
            }
            // 显示当前刻度对应的值
            fontSizeLab.text = "\(tickValues[currentSnappedTickIndex])"
            lastGestureValue = currentGestureValue
        }
    }
    
    @objc private func sliderTouchDown(_ slider: UISlider) {
        // 开始拖动，记录初始值
        isDragging = true
        dragStartValue = slider.value
        dragStartTickIndex = tickIndexForValue(slider.value)
        currentSnappedTickIndex = dragStartTickIndex // 初始化吸附位置
        lastGestureValue = slider.value
    }
    
    @objc private func sliderTouchUp(_ slider: UISlider) {
        // 结束拖动，对齐到最近的刻度位置（类似微信的效果）
        isDragging = false
        let finalTickIndex = tickIndexForValue(slider.value)
        currentFontSize = tickValues[finalTickIndex]
        slider.setValue(Float(currentFontSize), animated: true) // 平滑对齐到刻度位置
        updateFontSize(currentFontSize, updateSlider: false)
    }
    
    private func updateFontSize(_ size: Int, updateSlider: Bool = true) {
        // 确保值对齐到刻度
        let alignedSize = alignToNearestTick(size)
        fontSizeLab.text = "\(alignedSize)"
        
        if updateSlider {
            // 使用动画更新 slider，使滑动更平滑（类似微信）
            slider.setValue(Float(alignedSize), animated: true)
        }
        
        // 这里可以添加字体大小改变的回调
        // delegate?.fontSizeChanged(to: alignedSize)
    }
}

