//
//  LNIMChatGameMateSkillView.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/11.
//

import Foundation
import UIKit
import SnapKit
import Combine


class LNIMChatGameMateSkillView: UIView {
    private let scrollView = UIScrollView()
    private let stackView = UIStackView()
    private var itemViews: [LNIMChatGameMateSkillCell] = []
    private var indicatorContainer = UIStackView()
    private var indicators: [UIView] = []
    private var curPage: Int = 0 {
        didSet {
            if curPage != oldValue {
                for (index, indicator) in  indicators.enumerated() {
                    indicator.backgroundColor = index == curPage ? .text_6 : .init(hex: "#9FCD9B")
                }
            }
        }
    }
    private var skills: [LNGameMateSkillVO] = []
    var curSkill: LNGameMateSkillVO {
        skills[curPage]
    }
    
    var defaultId: String?
    
    weak var viewModel: LNIMChatViewModel? {
        didSet {
            viewModel?.$myOrders.sink { [weak self] list in
                guard let self else { return }
                isHidden = viewModel?.userInfo?.playmate != true
                || viewModel?.peerSkills.isEmpty != false
                || !list.isEmpty
            }.store(in: &cancellables)
            viewModel?.$peerSkills.sink { [weak self] skills in
                guard let self else { return }
                isHidden = viewModel?.userInfo?.playmate != true
                || skills.isEmpty
                || viewModel?.myOrders.isEmpty != true
                self.skills = skills
                buildSkillViews()
            }.store(in: &cancellables)
            viewModel?.$userInfo.sink { [weak self] info in
                guard let self else { return }
                isHidden = info?.playmate != true
                || viewModel?.peerSkills.isEmpty != false
                || viewModel?.myOrders.isEmpty != true
            }.store(in: &cancellables)
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNIMChatGameMateSkillView: LNIMChatGameMateSkillCellDelegate {
    func onIMChatGameMateSkillCell(cell: LNIMChatGameMateSkillCell, didClickOrder skill: LNGameMateSkillVO) {
        guard let userInfo = viewModel?.userInfo else { return }
        let panel = LNCreateOrderPanel()
        panel.update(skill, user: userInfo)
        panel.editable = true
        panel.popup()
    }
}

extension LNIMChatGameMateSkillView: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard skills.count > 2 else {
            curPage = Int(scrollView.contentOffset.x / scrollView.bounds.width)
            return
        }
        
        if scrollView.contentOffset.x < scrollView.bounds.width * 0.5 {
            curPage -= 1
            if curPage < 0 {
                curPage = skills.count - 1
            }
            let last = itemViews.removeLast()
            stackView.removeArrangedSubview(last)
            last.removeFromSuperview()
            itemViews.insert(last, at: 0)
            stackView.insertArrangedSubview(last, at: 0)
            last.snp.makeConstraints { make in
                make.width.equalTo(scrollView)
                make.height.equalToSuperview()
            }
            
            let skill = skills[curPage > 0 ? curPage - 1 : skills.count - 1]
            last.update(skill)
            
            scrollView.contentOffset.x = scrollView.contentOffset.x + scrollView.bounds.width
        } else if scrollView.contentOffset.x > scrollView.bounds.width * 1.5 {
            curPage += 1
            if curPage > skills.count - 1 {
                curPage = 0
            }
            let first = itemViews.removeFirst()
            stackView.removeArrangedSubview(first)
            first.removeFromSuperview()
            itemViews.append(first)
            stackView.addArrangedSubview(first)
            first.snp.makeConstraints { make in
                make.width.equalTo(scrollView)
                make.height.equalToSuperview()
            }
            
            let skill = skills[curPage < skills.count - 1 ? curPage + 1 : 0]
            first.update(skill)
            
            scrollView.contentOffset.x = scrollView.contentOffset.x - scrollView.bounds.width
        }
    }
}
 
extension LNIMChatGameMateSkillView {
    private func buildSkillViews() {
        let defaultIndex: Int = if let defaultId {
            skills.firstIndex(where: { $0.id == defaultId }) ?? 0
        } else {
            0
        }
        if skills.count < 3 {
            scrollView.setContentOffset(.init(x: 0, y: 0), animated: false)
            for (index, skill) in skills.enumerated() {
                itemViews[index].isHidden = false
                itemViews[index].update(skill)
            }
            for index in skills.count..<itemViews.count {
                itemViews[index].isHidden = true
            }
        } else {
            scrollView.setContentOffset(.init(x: scrollView.bounds.width, y: 0), animated: false)
            for index in 0..<itemViews.count {
                itemViews[index].isHidden = false
            }
            itemViews[0].update(skills[defaultIndex - 1 >= 0 ? defaultIndex - 1 : skills.count - 1])
            itemViews[1].update(skills[defaultIndex])
            itemViews[2].update(skills[defaultIndex + 1 > skills.count - 1 ? 0 : defaultIndex + 1])
        }
        
        indicatorContainer.arrangedSubviews.forEach {
            indicatorContainer.removeArrangedSubview($0)
            $0.removeFromSuperview()
        }
        indicators.removeAll()
        for index in 0..<skills.count {
            let indicator = buildIndicator()
            indicator.backgroundColor = index == defaultIndex ? .text_6 : .init(hex: "#9FCD9B")
            indicatorContainer.addArrangedSubview(indicator)
            indicators.append(indicator)
        }
        
        curPage = defaultIndex
        
        // 移除默认定位
        if !skills.isEmpty {
            defaultId = nil
        }
    }
    
    private func setupViews() {
        clipsToBounds = true
        scrollView.backgroundColor = .clear
        scrollView.clipsToBounds = false
        scrollView.isPagingEnabled = true
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.delegate = self
        addSubview(scrollView)
        scrollView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(14)
            make.bottom.equalToSuperview()
            make.top.equalToSuperview().offset(8)
            make.height.equalTo(72)
        }
        
        let fakeView = UIView()
        scrollView.addSubview(fakeView)
        fakeView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalToSuperview()
            make.width.equalTo(0)
        }
        
        stackView.axis = .horizontal
        stackView.spacing = 0
        scrollView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.height.equalToSuperview()
        }
        
        for _ in 0..<3 {
            let itemView = LNIMChatGameMateSkillCell()
            itemView.delegate = self
            stackView.addArrangedSubview(itemView)
            itemView.snp.makeConstraints { make in
                make.width.equalTo(scrollView)
                make.height.equalToSuperview()
            }
            
            itemViews.append(itemView)
        }
        
        indicatorContainer.axis = .horizontal
        indicatorContainer.spacing = 6
        addSubview(indicatorContainer)
        indicatorContainer.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.size.equalTo(0).priority(.low)
            make.bottom.equalToSuperview().offset(-6.5)
        }
    }
    
    private func buildIndicator() -> UIView {
        let dot = UIView()
        dot.layer.cornerRadius = 2.5
        dot.snp.makeConstraints { make in
            make.width.height.equalTo(5)
        }
        
        return dot
    }
}
