//
//  RoleVoiceSetController.swift

//
//  Created by Leon on 2025/7/20.
//

import JXPagingView
import JXSegmentedView
import UIKit
import Combine

class RoleVoiceSetController: CLBaseViewController {
    weak var viewModel: RoleCreateViewModel!
    
    /// Public 外部传入, 上次选中的声音
    var selectVoiceBefore: VoiceModel?
    /// Public 外部传入, 首次进入，需要根据之前的性别选择，默认选中。
    var sexSelect: Sex?
    
    private let segmentedViewHeight = 40

    private lazy var segmentedView = JXSegmentedView(frame: CGRect(x: 0, y: 0, width: UIScreen.width, height: CGFloat(segmentedViewHeight)))
    private lazy var pagingView = JXPagingListRefreshView(delegate: self)
    private var headerView: RoleVoiceSetHeaderView!
    private var headerViewHeight: CGFloat = 288

    private var controllers = [JXPagingViewListViewDelegate]()
    private let dataSource = JXSegmentedTitleDataSource()

    private var maleVoiceListVc: RoleVoiceListController!
    private var femaleVoiceListVc: RoleVoiceListController!

    var selectVoiceAction: ((_ voice: VoiceModel?) -> Void)?
    // Data
    @Published private var selectVoice:VoiceModel?
    private var cancellables = Set<AnyCancellable>()
    
    // Flag
    var tabSelectIndexLast: Int = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()

        setupViews()
        setupDatas()
        setupEvents()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        navigationController?.interactivePopGestureRecognizer?.isEnabled = false
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        SpeechManager.shared.stopPlayCurrent()
        navigationController?.interactivePopGestureRecognizer?.isEnabled = true
    }

    private func setupViews() {
        navigationView.alpha0Title = "Voice"
        navigationView.styleMainButton.text = "Confirm"
        navigationView.styleMainButton.addTarget(self, action: #selector(tapNaviComfirm), for: .touchUpInside)
        headerView = {
            let v = RoleVoiceSetHeaderView()
            v.heightChangeBlock = { [weak self] height in
                self?.headerViewHeight = height
                self?.pagingView.resizeTableHeaderViewHeight()
            }
            return v
        }()

        pagingView.mainTableView.backgroundColor = .clear
        view.addSubview(pagingView)
        pagingView.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview()
            make.bottom.equalToSuperview()
            make.top.equalTo(navigationView.snp.bottom)
        }

        dataSource.clNormalStyle()
        dataSource.titles = ["Male", "Female"]

        segmentedView.listContainer = pagingView.listContainerView
        segmentedView.dataSource = dataSource
        segmentedView.delegate = self
        segmentedView.clNormalStyle()

        maleVoiceListVc = {
            let vc = RoleVoiceListController()
            controllers.append(vc)
            return vc
        }()

        femaleVoiceListVc = {
            let vc = RoleVoiceListController()
            controllers.append(vc)
            return vc
        }()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        disabledFullScreenPan()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        enabledFullScreenPan()
    }

    private func setupDatas() {
        
        guard let timbreDictArray = AppDictManager.shared.aiDict?.timbreDictList else{
            Hud.showIndicator()
            AppDictManager.shared.loadAIDict {[weak self] ok in
                Hud.hideIndicator()
                if let array = AppDictManager.shared.aiDict?.timbreDictList, array.count > 0{
                    self?.setupDatas()
                }
            }
            return
        }
        
        // 分男女
        var maleVoices = [VoiceModel]()
        var femaleVoices = [VoiceModel]()
        
        // 上次选中的
        var selectVoiceLastTimeId = 0
        if let lastTime = selectVoiceBefore{
            selectVoiceLastTimeId = lastTime.voiceDict.id!
        }
        var defaultTabIndex = 0
        let sex = sexSelect ?? .noncomfirming
        
        for (_, per) in timbreDictArray.enumerated(){
            // 男
            if let type = per.type, type == 1{
                let model = VoiceModel(voiceDict: per)
                if maleVoices.count <= 0 && sex == .male{
                    defaultTabIndex = 0
                }
                if per.id! == selectVoiceLastTimeId{
                    selectVoice = model
                    selectVoice?.syncConfigFrom(other: selectVoiceBefore)
                    defaultTabIndex = 0
                }
                
                maleVoices.append(model)
            }else{
                // 女
                let model = VoiceModel(voiceDict: per)
                if femaleVoices.count <= 0 && sex == .female{
                    defaultTabIndex = 1
                }
                if per.id! == selectVoiceLastTimeId{
                    selectVoice = model
                    selectVoice?.syncConfigFrom(other: selectVoiceBefore)
                    defaultTabIndex = 1
                }
                femaleVoices.append(model)
            }
        }
        
        tabSelectIndexLast = defaultTabIndex
        segmentedView.defaultSelectedIndex = defaultTabIndex
        
        maleVoiceListVc.voices = maleVoices
        femaleVoiceListVc.voices = femaleVoices
        
    }

    private func setupEvents() {
        headerView.roleVoiceAdjustView.tapCloseButtonBlock = {[weak self] in
            self?.selectVoice = nil
        }
        
        maleVoiceListVc.selectVoiceAction = {[weak self] result in
            dlog("🎤当前选中的音频：\(String(describing: result))")
            self?.selectVoice = result
        }
        
        femaleVoiceListVc.selectVoiceAction = {[weak self] result in
            dlog("🎤当前选中的音频2：\(String(describing: result))")
        
//            self?.headerView.bind(voice: result)
//            self?.refreshViewStates()
            
            self?.selectVoice = result

        }
        
        $selectVoice.sink {[weak self] result in
            guard let `self` = self else {
                return
            }
            
            SpeechManager.shared.stopPlayCurrent()
            
            self.headerView.bind(voice: result)
            self.refreshViewStates()
            
            assert(self.femaleVoiceListVc != nil, "femaleVoiceListVc must be initialized")
            if let voice = result{
                self.femaleVoiceListVc.select(voiceId: voice.voiceDict.id!)
                self.maleVoiceListVc.select(voiceId: voice.voiceDict.id!)
            }else{
                self.femaleVoiceListVc.select(voiceId: 0)
                self.maleVoiceListVc.select(voiceId: 0)
            }
        }.store(in: &cancellables)
    }
    
    // MARK: - Helper
    
    private func refreshViewStates(){
//        dlog("两个voice:\(String(describing: maleVoiceListVc.selectVoice)) and \(String(describing: femaleVoiceListVc.selectVoice))")
//        navigationView.styleMainButton.isEnabled = (maleVoiceListVc.selectVoice != nil || femaleVoiceListVc.selectVoice != nil)
        dlog("headView's voice \(String(describing: headerView.roleVoiceAdjustView.voice))")
        navigationView.styleMainButton.isEnabled = headerView.roleVoiceAdjustView.voice != nil
    }
    
    // MARK: - Action
    
    @objc private func tapNaviComfirm(){
        guard selectVoice != nil else {return}
        
        let pitch = "\(headerView.roleVoiceAdjustView.speechLoudness)"
        let speed = "\(headerView.roleVoiceAdjustView.speechRate)"
        selectVoice?.dialoguePitch = pitch
        selectVoice?.dialogueSpeechRate = speed
        
        selectVoiceAction?(selectVoice)
        navigationController?.popViewController(animated: true)
    }
    
    
    
}

extension RoleVoiceSetController: JXPagingViewDelegate, JXSegmentedViewDelegate {
    func tableHeaderViewHeight(in _: JXPagingView) -> Int {
        return Int(headerViewHeight)
    }

    func tableHeaderView(in _: JXPagingView) -> UIView {
        return headerView
    }

    func heightForPinSectionHeader(in _: JXPagingView) -> Int {
        return segmentedViewHeight
    }

    func viewForPinSectionHeader(in _: JXPagingView) -> UIView {
        return segmentedView
    }

    func numberOfLists(in _: JXPagingView) -> Int {
        return controllers.count
    }

    func pagingView(_: JXPagingView, initListAtIndex index: Int) -> JXPagingViewListViewDelegate {
        let vc = controllers[index]
        return vc
    }

    func segmentedView(_ segmentedView: JXSegmentedView, didSelectedItemAt index: Int) {
        if tabSelectIndexLast != index{
            tabSelectIndexLast = index;
            SpeechManager.shared.stopPlayCurrent()
        }
    }

    func mainTableViewDidScroll(_ scrollView: UIScrollView) {
        NaviAlphaHandle.changeNaviTitleAlpha(scrollView: scrollView, titleLabel: navigationView.titleLabel)
    }
}

class RoleVoiceSetHeaderView: UIView {
    var voiceRecommentTitle: UILabel!
    var voiceSelectView: VoiceSelectView!
    var roleVoiceAdjustView: RoleVoiceAdjustView!
    
    var heightChangeBlock: ((CGFloat) -> Void)?

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupViews() {
        let titleView = {
            let v = TitleView()
            v.optionInnerBottomPadding = 16
            v.optionInnerTopPadding = 16
            addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.equalToSuperview()
                make.trailing.equalToSuperview()
                make.top.equalToSuperview()
            }
            return v
        }()
        titleView.titleLabel.text = "Voice"

        let subTitleView = {
            let v = UILabel()
            v.font = .t.tlm
            v.textColor = .c.ctsn
            addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.equalToSuperview().offset(CGFloat.lrs)
                make.trailing.equalToSuperview().offset(-CGFloat.lrs)
                make.top.equalTo(titleView.snp.bottom).offset(12)
            }
            v.text = "Select your voice"
            return v
        }()

        // StackViewV has voiceSelectView, RoleVoiceAdjustView
        let stackView = {
            let v = UIStackView()
            v.axis = .vertical
            v.spacing = 12
            addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.equalToSuperview().offset(CGFloat.lrs)
                make.trailing.equalToSuperview().offset(-CGFloat.lrs)
                make.top.equalTo(subTitleView.snp.bottom).offset(12)
            }
            return v
        }()

        voiceSelectView = {
            let v = VoiceSelectView()
            stackView.addArrangedSubview(v)
            v.snp.makeConstraints { _ in
                // make.height.equalTo(120)
            }
            return v
        }()

        roleVoiceAdjustView = {
            let v = RoleVoiceAdjustView()
            stackView.addArrangedSubview(v)
            v.snp.makeConstraints { _ in
                // make.height.equalTo(120)
            }
            return v
        }()

        voiceSelectView.isHidden = false
        roleVoiceAdjustView.isHidden = true

        voiceRecommentTitle = {
            let v = UILabel()
            v.font = .t.ttm
            v.textColor = .c.ctpn
            addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.equalToSuperview().offset(CGFloat.lrs)
                make.top.equalTo(stackView.snp.bottom).offset(12)
            }
            v.text = "Voice Recommendation"
            return v
        }()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let maxY = voiceRecommentTitle.frame.maxY + 12
        heightChangeBlock?(maxY)
    }
    
    public func bind(voice: VoiceModel?){
        if voice != nil{
            voiceSelectView.isHidden = true
            roleVoiceAdjustView.isHidden = false
            
            let name = voice?.voiceDict.name ?? "-"
            roleVoiceAdjustView.titleLabel.text = name
            
        }else{
            voiceSelectView.isHidden = false
            roleVoiceAdjustView.isHidden = true
        }
        roleVoiceAdjustView.bind(voice: voice)
    }
}
