//
//  SpeakDialogueViewCtr.swift
//  SpeakEasyLearnEnglish
//
//  Created by edy on 2025/8/4.
//

import UIKit

class SpeakNewUserViewCtr: SpeakEleBaseViewCtr {

    
    @IBOutlet weak var SpeakDialogTopPlayVideo: UIView!
    @IBOutlet weak var SpeakVideoPPPPPP: UIView!
    
    @IBOutlet weak var SpeakLeassonName: UILabel!
    @IBOutlet weak var SpeakLeassonCollect: UIButton!
    
    @IBOutlet weak var SpeakContentView: UIView!
    @IBOutlet weak var SpeakLeassonTableView: UITableView!
    
    
    @IBOutlet weak var SpeakTimes: UIButton!
    @IBOutlet weak var SpeakInputView: UIView!
    
    
    @IBOutlet weak var SentAudioSound: UIButton!
    
    
    var dataSource:[SpeakDialogueModel] = []
    @BoundedZeroNumber private var studyTm:Int = 300
    private var studyTime:Int = 0
    var isReStart = false
    var isMute = false
    
    
    private var Translates = NSMutableSet()
    let viewModel = SpeakDialogueViewModel()
    let homeModel = SpeakHomeViewModel()
    var dataLesssion:SpeakLessonDescpModel?
    
    private var isSing = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
//        viewModel.DialogLeasson = self.dataLesssion
        SentAudioSound.setBackgroundImage(UIColor.init(hex: 0x1C2634,alpha: 0.3).generate(), for: .normal)
        InputTextView.state = .defult
        SpeakTimes.isHidden = IAPViewModel.share.isSubscribed
        DispatchQueue.main.async {
            let leaase = (SpeakElePublicManager.share.userInfo.targetLanguage == "🇬🇧 English" ? 185 : 1)
            self.homeModel.fetchLeasson(leassonId: leaase) {[weak self] data in
                self?.dataLesssion = data
                self?.viewModel.DialogLeasson = data;
                self?.viewModel.fetchHistroy(leassonId: self?.dataLesssion?.id ?? 0 ,isReStart: self?.isReStart ?? true)
                self?.setLeasse()
            }
    
        }
    }
    
    private func setLeasse() -> Void {
        self.SpeakLeassonName.text = "\(dataLesssion?.name ?? "")"
        self.SpeakLeassonCollect.isSelected = dataLesssion?.isCollect ?? false
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        AudioPlayerManager.shared.isMute = self.isMute
        viewModel.SpeakUpdate = { [weak self] data in
            if  data is SpeakNetBaseDeflutMode {
                self?.SpeakLeassonCollect.isSelected = !(self?.SpeakLeassonCollect.isSelected ?? false)
            }else if let d = data as? [SpeakDialogueModel] {
                self?.dataSource = d
                self?.SpeakLeassonTableView.reloadData()
                self?.SpeakLeassonTableView.layoutIfNeeded()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.01, execute: {
                    self?.SpeakLeassonTableView.reloadData()
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                        self?.tipsAnimateFinish()
                        self?.scrollTop()
                    }
                })
            }else if let dsta = data as? SpeakdialogueTalkModel {
                self?.isSing = true
                DispatchQueue.global().async {
                    var Audioplay:[Data] = []
                    var duration = 0.0
                    for save in (dsta.contentList ?? []){
                        if let d = save.video {
                            duration += save.videoTime ?? 0
                            Audioplay.append(d)
                            SpeakCache.cache.saveData(data: d, fileName: "\(save.recordId ?? 0)")
                        }
                    }
                    DispatchQueue.main.async {
                        if Audioplay.count > 0 {
                            AudioPlayerManager.shared.setupAudioPlayer(with: Audioplay.first! ,isMuted: self?.isMute ?? false)
                            Audioplay.remove(at: 0)
                            AudioPlayerManager.shared.task = Audioplay
                            let speed = SpeakElePublicManager.share.PublicData.speed
                            SpeakAIVideoPlayManager.share.PlaySpeak(duration / speed)
                        }
                    }
                }
            }
        }
        
        var loading = SpeakDialogueModel()
        loading.role = .loading
        viewModel.dialogLeassAsk.append(loading)
        
        if self.dataSource.count != viewModel.dialogLeassAsk.count {
            self.dataSource = viewModel.dialogLeassAsk
            self.SpeakLeassonTableView.reloadData()
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                self.tipsAnimateFinish()
                self.scrollTop()
            }
        }
        audioText()
        titleView.isHidden = true
        self.didddd.isPaused = false
        studyTm = SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm ?? 0
        studyTime = SpeakDayEveryManager.manager.SpeakDayData.studytime ?? 0
        SentAudioSound.isSelected = isMute
        if isReStart {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                let vc = SpeakDialogTipsViewCtr()
                vc.show()
            }
        }
        SpeakVideoPPPPPP.addSubview(SpeakAIVideoPlayManager.share)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            SpeakAIVideoPlayManager.share.PlayBg()
        }
    }
    
    override func setup() {
        SpeakLeassonTableView.delegate = self
        SpeakLeassonTableView.dataSource = self
        SpeakLeassonTableView.sectionHeaderTopPadding = 0
        SpeakLeassonTableView.sectionHeaderHeight = 0.01
        SpeakLeassonTableView.sectionFooterHeight = 0.01
        SpeakLeassonTableView.contentInsetAdjustmentBehavior = .never
        SpeakLeassonTableView.contentInset = UIEdgeInsets()
        SpeakLeassonTableView.register(UINib(nibName: SpeakDialogSenderCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogSenderCell.id)
        SpeakLeassonTableView.register(UINib(nibName: SpeakDialogAIerCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogAIerCell.id)
        SpeakLeassonTableView.register(UINib(nibName: SpeakDialogLoadingCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogLoadingCell.id)
        SpeakLeassonTableView.register(UINib(nibName: SpeakDialogAIReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogAIReviewCell.id)
        SpeakLeassonTableView.register(UINib(nibName: SpeakDialogQuReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogQuReviewCell.id)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.view.layoutIfNeeded()
        SpeakContentView.cornerRect(radius: 16, [.topLeft,.topRight])
        SpeakAIVideoPlayManager.share.frame = self.SpeakVideoPPPPPP.bounds
        self.SentAudioSound.corners = self.SentAudioSound.height/2.0
    }
    
    @IBAction func SpeakFavatorTaps(_ sender: UIButton) {
        viewModel.collect(id: self.dataLesssion?.id ?? 0, isCollect: !sender.isSelected)
    }
    
    
    @IBAction func SoundTapCloseTaps(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        isMute = sender.isSelected
        AudioPlayerManager.shared.isMute = self.isMute
        AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1)
        for (i,_) in self.dataSource.enumerated() {
            if let cell = self.SpeakLeassonTableView.cellForRow(at: IndexPath(row: i, section: 0)) as? SpeakDialogAIerCell {
                cell.isMute = isMute
            }
        }
    }
    
    
    @IBAction func SpeakDialogCloseTaps(_ sender: Any) {
        let configs = SpeakPublicTipsViewCtr.PublicTipsModel(icon: UIImage(named: "img_wanliu"),title: "The teacher is waiting for you",descAttr: "Are you sure you want to quit? Continuous learning is more efficient",sureAction: "Return to the classroom", cancel: "Persist in withdrawing")
        let alert = SpeakPublicTipsViewCtr(configs: configs)
        alert.show()
        alert.view.callblack = {[weak self] data in
            if let b = data as? Bool ,
               b == true{
                self?.didddd.isPaused = true
                self?.didddd.invalidate()
                self?.display.isPaused = true
                self?.display.invalidate()
                SpeakAIVideoPlayManager.share.removeFromSuperview()
                SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = self?.studyTm
                SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime
                SpeakDayEveryManager.manager.update()
                if let call = self?.view.callblack {
                    call(self?.isSing)
                }
                AudioPlayerManager.shared.stop()
                self?.navigationController?.popViewController(animated: true)
            }
        }
    }
    
    
    @IBAction func SpeakDialogueSet(_ sender: Any) {
        let vc = SpeakDialogueSetViewCtr()
        vc.show { [weak self] Restart in
            if self?.InputTextView.state == .defult {
                self?.InputTextView.state = .defult
            }
            if Restart {
                var loading = SpeakDialogueModel()
                loading.role = .loading
                self?.viewModel.dialogLeassAsk = [loading]
                self?.dataSource = self?.viewModel.dialogLeassAsk ?? []
                self?.SpeakLeassonTableView.reloadData()
                self?.viewModel.fetchHistroy(leassonId: self?.dataLesssion?.id ?? 0 ,isReStart: true)
            }else{
                if let last = self?.dataSource.last,
                   last.role == .AI ,
                   let len = self?.dataSource.count, len > 0 {
                    if SpeakElePublicManager.share.PublicData.Smarttips {
                        self?.dataSource[len-1].AniState = .final
                    }else{
                        self?.dataSource[len-1].AniState = .ANone
                    }
                    self?.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: len-1, section: 0)], with: .bottom)
                }
            }
        }
    }
    
   
    
    override func SpeakUpdate() {
        InputTextView.update()
    }
    
    private lazy var InputTextView: SpeakDialogueInputTextView = {
        let input = SpeakDialogueInputTextView.xib()
        input.delegate = self
        self.SpeakInputView.addSubview(input)
        
        SpeakAudioRecorder.shared.callblocksssssss = { [weak self] success in
            if success {
                let call = SpeakEleCallAIViewCtr(viewModel: self?.viewModel)
                call.isMate = self?.isMute ?? false
                call.leasses = self?.dataLesssion?.id
                SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = self?.studyTm
                SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime
                SpeakDayEveryManager.manager.update()
                call.view.callblack = {[weak self] data in
                    if let isMate = data as? Bool {
                        self?.isMute = isMate
                        self?.dataSource = self?.viewModel.dialogLeassAsk ?? []
                        self?.scrollTop()
                        self?.tipsAnimateFinish()
                    }
                }
                self?.navigationController?.pushViewController(call, animated: true)
            }
        }
        
        input.callblack = {[weak self] bt in
            if SpeakAudioRecorder.shared.hasPermission {
                let call = SpeakEleCallAIViewCtr(viewModel: self?.viewModel)
                call.isMate = self?.isMute ?? false
                call.leasses = self?.dataLesssion?.id
                SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = self?.studyTm
                SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime
                SpeakDayEveryManager.manager.update()
                call.view.callblack = {[weak self] data in
                    if let isMate = data as? Bool {
                        self?.isMute = isMate
                        self?.dataSource = self?.viewModel.dialogLeassAsk ?? []
                        self?.scrollTop()
                        self?.tipsAnimateFinish()
                    }
                }
                self?.navigationController?.pushViewController(call, animated: true)
            }else{
                let alert = UIAlertController(title: nil, message: "Microphone permission not enabled", preferredStyle: .alert)
                SpWindow.rootViewController?.present(alert, animated: true)
                DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                    alert.dismiss(animated: true)
                }
            }
        }
        input.snp.makeConstraints { make in
            make.left.right.bottom.top.equalToSuperview()
        }
        return input
    }()
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        SpeakAIVideoPlayManager.share.stop()
    }
    
    private lazy var didddd: CADisplayLink = {
        let ddd = CADisplayLink(target: self, selector: #selector(uuuup))
        ddd.preferredFramesPerSecond = 1
        ddd.add(to: .main, forMode: .common )
        return ddd
    }()
    
    deinit {
        self.display.invalidate()
        self.didddd.invalidate()
        self.view.callblack = nil
    }
}

// MARK: - sender
extension SpeakNewUserViewCtr {
    
    @objc private func uuuup() -> Void {
        if !IAPViewModel.share.isSubscribed {
            studyTm -= 1
            let min = studyTm / 60
            let sec = studyTm % 60
            SpeakTimes.setTitle(String(format: "%02d:%02d", min,sec), for: .normal)
        }
        studyTime += 1
    }
    
    private func tipsAnimateFinish() {
        self.view.layoutIfNeeded()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
            if let last = self.dataSource.last,
               last.AniState == .loading,
               last.role == .AI {
                let len = self.dataSource.count - 1
                self.dataSource[len].AniState = SpeakDialogueRoleAnimation.final
                self.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: len, section: 0)], with: .none)
                self.SpeakLeassonTableView.layoutIfNeeded()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                    self.scrollTop()
                }
            }
        }
    }
    
    @objc private func scrollTop() -> Void {
        self.SpeakLeassonTableView.reloadData()
        self.SpeakLeassonTableView.layoutIfNeeded()
        if self.SpeakLeassonTableView.contentSize.height > self.SpeakLeassonTableView.height {
            self.SpeakLeassonTableView.beginUpdates()
            self.SpeakLeassonTableView.scrollToRow(at: IndexPath(row: self.dataSource.count-1, section: 0), at: .bottom, animated: true)
            self.SpeakLeassonTableView.endUpdates()
            self.SpeakLeassonTableView.reloadData()
        }
    }
    
}

// MARK: - TableViewDelegate
extension SpeakNewUserViewCtr : UITableViewDelegate,UITableViewDataSource{
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let data = dataSource[indexPath.row]
        if data.role == .AI {
            let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogAIerCell.id, for: indexPath) as! SpeakDialogAIerCell
            cell.isTranslate = self.Translates.contains(indexPath.row)
            cell.data = data
            cell.isMute = isMute
            cell.callblack = { [weak self]  idx in
                if let ask = idx as? String {
                    if self?.Translates.contains(indexPath.row) ?? false{
                        self?.Translates.remove(indexPath.row)
                        cell.isTranslate = false
                        tableView.beginUpdates()
                        tableView.reloadRows(at: [indexPath], with: .automatic)
                        tableView.endUpdates()
                    }else{
                        self?.Translates.add(indexPath.row)
                        if data.translate?.count ?? 0 <= 0 {
                            self?.viewModel.translate(msg: ask) { t in
                                self?.dataSource[indexPath.row].translate = t
                                tableView.beginUpdates()
                                tableView.reloadRows(at: [indexPath], with: .automatic)
                                tableView.endUpdates()
                            }
                        }else{
                            tableView.beginUpdates()
                            tableView.reloadRows(at: [indexPath], with: .automatic)
                            tableView.endUpdates()
                        }
                    }
                }
            }
            return cell
        }else if data.role == .User{
            let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogSenderCell.id, for: indexPath) as! SpeakDialogSenderCell
            cell.data = data
            cell.leasession = self.dataLesssion?.id
            return cell
        }else if data.role == .AIReview {
            let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogAIReviewCell.id, for: indexPath) as! SpeakDialogAIReviewCell
            cell.data = data
            return cell
        }else if data.role == .review {
            let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogQuReviewCell.id, for: indexPath) as! SpeakDialogQuReviewCell
            return cell
        }else{
            let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogLoadingCell.id, for: indexPath) as! SpeakDialogLoadingCell
            return cell
        }
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let cell = cell as? SpeakDialogAIerCell{
            cell.reload()
        }else if let cell = cell as? SpeakDialogLoadingCell{
            cell.LoadingView.stopAnimating()
            cell.LoadingView.startAnimating()
        }
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView()
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
}


// MARK: - input
extension SpeakNewUserViewCtr : SpeakDialogueInputDelegate {
    
    func SpeakTipComplate() {
        if let last = self.dataSource.last,
           last.role == .AI {
            if last.AniState == .ANone {
                self.dataSource[self.dataSource.count-1].AniState = .loading
                self.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: self.dataSource.count-1, section: 0)], with: .bottom)
                self.SpeakLeassonTableView.reloadData()
                self.view.layoutIfNeeded()
                tipsAnimateFinish()
            }else{
                self.dataSource[self.dataSource.count-1].AniState = .ANone
                self.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: self.dataSource.count-1, section: 0)], with: .bottom)
                self.SpeakLeassonTableView.reloadData()
                self.view.layoutIfNeeded()
            }
        }
    }
    
    func speakSendMessage(message: String) {

        if !IAPViewModel.share.isSubscribed && studyTm <= 0{
            let iap = SpeakEleIAPViewCtr()
            iap.state = .other
            self.navigationController?.AnimationState = .present
            self.navigationController?.pushViewController(iap, animated: true)
            return
        }
        AudioPlayerManager.shared.stop()
        if message.count > 0 {
            var talk = SpeakDialogueModel()
            talk.content = message
            talk.role = .User
            talk.AniState = .ANone
            viewModel.dialogLeassAsk.append(talk)
            viewModel.AIAsk(lessonId: self.dataLesssion?.id ?? 0, userAnswer: message)
            
            var loading = SpeakDialogueModel()
            loading.role = .loading
            viewModel.dialogLeassAsk.append(loading)
        }else if message.count == 0 {
            self.display.isPaused = true
            InputTextView.state = .record
            SpeakAudioRecorder.shared.stopRecording { url, error in
                if error == nil ,
                let urls = url {
                    SpeakAudioToTextConverter.share.recognizeAudioFile(at: urls)
                }
            }
        }
    }
    
    private func audioText() -> Void {
        SpeakAudioToTextConverter.share.onResult = { [weak self]  text in
            if text.count > 0 {
                var talk = SpeakDialogueModel()
                talk.content = text
                talk.role = .User
                talk.AniState = .ANone
                self?.viewModel.dialogLeassAsk.append(talk)
                self?.viewModel.AIAsk(lessonId: self?.dataLesssion?.id ?? 0, userAnswer: text)
                var loading = SpeakDialogueModel()
                loading.role = .loading
                self?.viewModel.dialogLeassAsk.append(loading)
            }
        }
        SpeakAudioToTextConverter.share.onError = { error in
            
        }
    }
    
    func startRecord() {
        self.display.isPaused = false
        SpeakAudioRecorder.shared.startRecording { su, error in
            if su {}
        }
    }
    
    func cancelRecord() {
        SpeakAudioRecorder.shared.stopRecording()
        self.display.isPaused = true
    }
    
}
