//
//  SpeakEleQAViewCtr.swift
//  SpeakEasyLearnEnglish
//
//  Created by edy on 2025/7/11.
//

import UIKit

class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {

    // MARK: - ib
    @IBOutlet weak var SpeakProgres: UISlider!
    @IBOutlet weak var SpeakContentV: UIView!
    @IBOutlet weak var SpeakTableView: UITableView!
    @IBOutlet weak var SpeakInputBox: SpeakResizableTextView!
    @IBOutlet weak var InputBoxContent: UIStackView!
    @IBOutlet weak var contiuneBtn: SpeakEleButton!
    
    @IBOutlet weak var SpeakTopVideoView: UIView!
    @IBOutlet weak var SpeakBottomTool: UIView!
    
    @IBOutlet weak var ContiueContentV: UIView!
    
    private var offsets = 0
    
    private var max = 7
    private var moreItem:[String] = []
    private let viewModel = SpeakEleQAViewModel()
    private var SpeakTask : [SpeakEleQAModel] = []
    private var tm:String = Date().toStr("hh:mm aa") ?? ""
    private var selectSets = NSMutableSet()
    
    private var player = SpeakVideoPlayer()
    
    private var isCountiue:Int = -1 {
        didSet {
            let enable = !(isCountiue == -1)
            if !enable {
                contiuneBtn.setBackgroundImage(UIImage(named: "icon-button_no(1)"), for: .normal)
                contiuneBtn.setBackgroundImage(UIImage(named: "button_guide_on-Heigiose"), for: .highlighted)
            }else{
                contiuneBtn.setBackgroundImage(UIImage(named: "icon-button_guide_on"), for: .normal)
                contiuneBtn.setBackgroundImage(UIImage(named: "icon-button_no-hight"), for: .highlighted)
            }
            SpeakTableView.reloadData()
        }
    }
    
    private var step = 0 {
        didSet{
            contiuneBtn.isHidden = step < 3
            ContiueContentV.isHidden = contiuneBtn.isHidden
            InputBoxContent.isHidden = !(step < 3)
            SpeakInputBox.isUserInteractionEnabled = (step == 2)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel.fetchData()
        SpeakElePublicManager.share.PublicData.state = .qanda
        display.isPaused = true
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
        viewModel.anwerUpdate = { [weak self] in
            self?.update()
        }
        SpeakInputBox.callblack = { [weak self] v in
            DispatchQueue.main.async {
                self?.sendTo()
            }
        }
        player.loadVideo(state: .none, 0)
        SpeakTopVideoView.layer.addSublayer(player.SpeakPlayerLayer ?? CALayer())
        player.SpeakPlayer?.play()
    }
    
    override func setup() {
        self.SpeakTableView.delegate = self
        self.SpeakTableView.dataSource = self;
        self.SpeakTableView.sectionHeaderTopPadding = 0
        self.SpeakTableView.sectionHeaderHeight = 0.1
        self.SpeakTableView.sectionFooterHeight = 0.1
        self.SpeakTableView.separatorStyle = .none
        self.SpeakTableView.separatorInset = UIEdgeInsets()
        self.SpeakTableView.register(SpeakEleQATextCell.self, forCellReuseIdentifier: SpeakEleQATextCell.id)
        self.SpeakTableView.register(SpeakEleSelectBoxViewCell.self, forCellReuseIdentifier: SpeakEleSelectBoxViewCell.id)
        self.SpeakTableView.register(SpeakEleMutabSelectBoxViewCell.self, forCellReuseIdentifier: SpeakEleMutabSelectBoxViewCell.id)
        self.SpeakTableView.register(SpeakEleSelectTimeViewCell.self, forCellReuseIdentifier: SpeakEleSelectTimeViewCell.id)
        self.SpeakTableView.register(SpeakEleTranSCell.self, forCellReuseIdentifier: SpeakEleTranSCell.id)
        self.SpeakTableView.register(UINib(nibName: SpeakDialogLoadingCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogLoadingCell.id)
        SpeakInputBox.isUserInteractionEnabled = false
        SpeakTableView.contentInsetAdjustmentBehavior = .never
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        titleView.isHidden = true
        isCountiue = -1
        GetLostMessage()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        SpeakContentV.cornerRect(radius: 16, [.topLeft,.topRight])
        player.SpeakPlayerLayer?.frame = SpeakTopVideoView.bounds
    }
    
    @IBAction func SpeakSendMsg(_ sender: Any) {
        sendTo()
    }
    
    @IBAction func contineTaps(_ sender: Any) {
        if self.isCountiue < 0 {
            return
        }
        if let last = viewModel.anwer.last {
            if last.speakMsg == "" {
                let  language = moreItem[safe:self.isCountiue] ?? ""
                let len = viewModel.anwer.count - 1
                if last.messageType == .language {
                    SpeakElePublicManager.share.userInfo.nativeLanguage = language
                    let msg = SpeakEleQAModel(speakMsg: language , role: .speakUser, messageType: .language)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .like {
                    SpeakElePublicManager.share.PublicData.LikeLanguage = language
                    let msg = SpeakEleQAModel(speakMsg: language , role: .speakUser, messageType: .like)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .hobby {
                    var hoby = ""
                    for i in self.selectSets {
                        if let i:Int = i as? Int{
                            hoby += "\(moreItem[i]),"
                        }
                    }
                    SpeakElePublicManager.share.PublicData.MHobby = hoby
                    let msg = SpeakEleQAModel(speakMsg: hoby , role: .speakUser, messageType: .hobby)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .improving {
                    var hoby = ""
                    for i in self.selectSets {
                        if let i:Int = i as? Int{
                            hoby += "\(moreItem[i]),"
                        }
                    }
                    SpeakElePublicManager.share.PublicData.MImproving = hoby
                    let msg = SpeakEleQAModel(speakMsg: hoby , role: .speakUser, messageType: .improving)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .proficiency {
                    var iv = 1
                    for (i,data) in viewModel.proficiency.enumerated() {
                        if data == language {
                            iv = i+1
                            break
                        }
                    }
                    SpeakElePublicManager.share.PublicData.MProficiency = iv
                    let msg = SpeakEleQAModel(speakMsg: language , role: .speakUser, messageType: .proficiency)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .goalDays {
                    SpeakElePublicManager.share.PublicData.MGoalDays = language
                    let msg = SpeakEleQAModel(speakMsg: language , role: .speakUser, messageType: .goalDays)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .studytime{
                    SpeakElePublicManager.share.PublicData.MStudytime = language
                    let msg = SpeakEleQAModel(speakMsg: language , role: .speakUser, messageType: .studytime)
                    viewModel.anwer[len] = msg
                }else if last.messageType == .practice {
                    SpeakElePublicManager.share.PublicData.MPractice = tm
                    let msg = SpeakEleQAModel(speakMsg: tm , role: .speakUser, messageType: .practice)
                    viewModel.anwer[len] = msg
                }
                viewModel.anwer.append(SpeakEleQAModel(speakMsg: "", role: .speakNone))
                SpeakElePublicManager.share.saveData()
                self.isCountiue = -1
                self.selectSets.removeAllObjects()
            }else if last.messageType == .finish {
                let plan = SpeakEleGeneratePlanViewCtr()
                self.navigationController?.pushViewController(plan, animated: true)
                return
            }
            offsets = 0
            display.isPaused = false
        }
    }
    
    override func SpeakUpdate() {
        if offsets % 2 == 1 {
            let msg = viewModel.questionArrys[safe: step] ?? SpeakEleQAModel()
            
            if msg.speakMsg.isEmpty || msg.messageType == .finish {
                display.isPaused = true
                offsets = 0
            }
            if msg.messageType == .name && msg.speakMsg.isEmpty {
                
            }else{
                if let lasss = viewModel.anwer.last,
                   lasss.role == .speakNone{
                    viewModel.anwer.removeLast()
                }
                viewModel.anwer.append(msg)
                step += 1
            }
            if msg.messageType == .language {
                moreItem = viewModel.SpeakLanguages[0..<max].map({String($0)})
            }else if msg.messageType == .like {
                moreItem = [SpeakElePublicManager.share.userInfo.nativeLanguage ?? "--" ,"🇬🇧 English"].reduce(into: [String]()) { result, element in
                    if !result.contains(element) {
                        result.append(element)
                    }
                }
            }else if msg.messageType == .hobby {
                moreItem = viewModel.SpeakHoby[0..<max].map({String($0)})
            }else if msg.messageType == .improving {
                moreItem = viewModel.improving
            }else if msg.messageType == .proficiency {
                moreItem = viewModel.proficiency
            }else if msg.messageType == .goalDays {
                moreItem = viewModel.goalDays
            }else if msg.messageType == .studytime{
                moreItem = viewModel.studyTime
            }else if msg.messageType == .practice {
                self.isCountiue = 0
            }else if msg.messageType == .finish {
                self.isCountiue = 0
                self.contiuneBtn.setTitle("Start", for: .normal)
                SpeakPermission.requestNotificationPermission()
            }
            return
        }
        offsets += 1
    }
    
}

extension SpeakEleQAViewCtr {
    
    private func GetLostMessage() -> Void {
        if let lasss = viewModel.anwer.last,
           lasss.role == .speakNone{
            viewModel.anwer.removeLast()
        }
        step = viewModel.anwer.count
        if let last:SpeakEleQAModel = viewModel.anwer.last {
            display.isPaused = (last.speakMsg.isEmpty || last.messageType == .finish)
            if last.messageType == .language {
                moreItem = viewModel.SpeakLanguages[0..<max].map({String($0)})
            }else if last.messageType == .like {
                moreItem = [SpeakElePublicManager.share.userInfo.nativeLanguage ?? "--" ,"🇬🇧 English"].reduce(into: [String]()) { result, element in
                    if !result.contains(element) {
                        result.append(element)
                    }
                }
            }else if last.messageType == .hobby {
                moreItem = viewModel.SpeakHoby[0..<max].map({String($0)})
            }else if last.messageType == .improving {
                moreItem = viewModel.improving
            }else if last.messageType == .proficiency {
                moreItem = viewModel.proficiency
            }else if last.messageType == .goalDays {
                moreItem = viewModel.goalDays
            }else if last.messageType == .studytime{
                moreItem = viewModel.studyTime
            }else if last.messageType == .practice{
                self.isCountiue = 0
            }else if last.messageType == .finish {
                self.isCountiue = 0
                self.contiuneBtn.setTitle("Start", for: .normal)
            }
        }else{
            display.isPaused = false
        }
        update()
        self.view.layoutIfNeeded()
        DispatchQueue.main.asyncAfter(deadline: .now()+0.01) {
            if self.SpeakTableView.contentSize.height > self.SpeakTableView.height {
                self.SpeakTableView.beginUpdates()
                self.SpeakTableView.scrollToRow(at: IndexPath(row: self.step-1, section: 0), at: .bottom, animated: true)
                self.SpeakTableView.endUpdates()
            }
        }
    }
    
    private func sendTo() -> Void {
        let text = SpeakInputBox.text
        if text?.count ?? 0 > 0 {
            self.view.endEditing(true)
            SpeakInputBox.text = ""
            SpeakElePublicManager.share.userInfo.userName = text ?? ""
            SpeakElePublicManager.share.saveData()
            viewModel.anwer.append(SpeakEleQAModel(speakMsg: text ?? "", role: .speakUser, messageType: .name))
            viewModel.anwer.append(SpeakEleQAModel(speakMsg: "", role: .speakNone, messageType: .name))
            step += 1
            display.isPaused = false
        }
    }
    
    private func update() -> Void {
        var pro = 0
        for v in self.viewModel.anwer {
            if (v.role == .speakUser && v.speakMsg.count > 0){
                pro += 1
            }
        }
        if let last = self.viewModel.anwer.last {
            if (last.role == .speakUser && last.speakMsg.count <= 0) || last.messageType == .name  || last.messageType == .finish{
                SpeakBottomTool.isHidden = false
            }else{
                SpeakBottomTool.isHidden = true
            }
        }else{
            SpeakBottomTool.isHidden = true
        }
        self.SpeakProgres.value = Float(pro) / 9.0
        self.SpeakTableView.reloadData()
        self.view.layoutIfNeeded()
        if self.viewModel.anwer.count > 0 {
            if SpeakTableView.numberOfRows(inSection: 0) != self.viewModel.anwer.count{
                let indexpath = IndexPath(row: self.viewModel.anwer.count - 1, section: 0)
                self.SpeakTableView.beginUpdates()
                self.SpeakTableView.insertRows(at: [indexpath] , with: .automatic)
                self.SpeakTableView.endUpdates()
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
                guard let self = self else { return }
                self.SpeakTableView.reloadData()
                self.view.layoutIfNeeded()
                UIView.animate(withDuration: 0.2) {
                    let contentSize = self.SpeakTableView.contentSize
                    if contentSize.height > self.SpeakTableView.height {
                        let lastSection = self.SpeakTableView.numberOfSections - 1
                        let lastRow = self.SpeakTableView.numberOfRows(inSection: lastSection) - 1
                        let indexPath = IndexPath(row: lastRow, section: lastSection)
                        let rect = self.SpeakTableView.rectForRow(at: indexPath)
                        let offsetY = rect.maxY - self.SpeakTableView.bounds.height + self.SpeakTableView.contentInset.bottom
                        self.SpeakTableView.setContentOffset(CGPoint(x: 0, y: offsetY),
                                                             animated: false)
                    }
                }
            }
        }
    }
}

extension SpeakEleQAViewCtr : UITableViewDelegate,UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.anwer.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let mds = viewModel.anwer[indexPath.row]
        if mds.role == .speakNone {
            let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogLoadingCell.id, for: indexPath) as! SpeakDialogLoadingCell
            DispatchQueue.main.async {
                cell.LoadingView.stopAnimating()
                cell.LoadingView.startAnimating()
            }
            return cell
        }else if mds.speakMsg.count <= 0 {
            if mds.messageType == .practice {
                let cell = tableView.dequeueReusableCell(withIdentifier: SpeakEleSelectTimeViewCell.id, for: indexPath) as! SpeakEleSelectTimeViewCell
                cell.data = mds
                cell.callblack = {[weak self] tm in
                    guard let tm:String = tm as? String else { return }
                    self?.tm = tm
                }
                return cell
            }else if mds.messageType == .hobby || mds.messageType == .improving {
                let cell = tableView.dequeueReusableCell(withIdentifier: SpeakEleMutabSelectBoxViewCell.id) as! SpeakEleMutabSelectBoxViewCell
                cell.isMore = (mds.messageType == .hobby)
                cell.datastr = moreItem
                cell.type = mds.messageType
                cell.selectSets = self.selectSets
                cell.callblack = {[weak self] idx in
                    if let idx:Int = idx as? Int{
                        if (self?.selectSets.contains(idx) ?? false) {
                            self?.selectSets.remove(idx)
                        }else{
                            if ( mds.messageType == .improving || (self?.selectSets.count ?? 0) < 4) {
                                self?.selectSets.add(idx)
                            }
                        }
                    }else if let sts = idx as? String {
                        self?.moreItem.insert(sts, at: 0)
                        let swiftSet = self?.selectSets.map { ($0 as! Int) + 1 }
                        self?.selectSets = NSMutableSet(array: swiftSet ?? [])
                        if (self?.selectSets.count ?? 0) < 4 {
                            self?.selectSets.add(0)
                        }
                        self?.selectSets = NSMutableSet(array: self?.selectSets.filter({($0 as! Int) < (self?.max ?? 0) }) ?? [])
                    }
                    self?.isCountiue = (self?.selectSets.count ?? 0 > 0) ? 1 : -1
                    self?.SpeakTableView.beginUpdates()
                    self?.SpeakTableView.reloadRows(at: [indexPath], with: .none)
                    self?.SpeakTableView.endUpdates()
                    self?.view.layoutIfNeeded()
                    DispatchQueue.main.asyncAfter(deadline: .now()+0.01) {
                        self?.SpeakTableView.reloadData()
                    }
                }
                return cell
            }else{
                let cell = tableView.dequeueReusableCell(withIdentifier: SpeakEleSelectBoxViewCell.id) as! SpeakEleSelectBoxViewCell
                cell.isMore = !(mds.messageType == .like ||
                                mds.messageType == .proficiency ||
                                mds.messageType == .goalDays ||
                                mds.messageType == .studytime)
                cell.datastr = moreItem
                cell.type = mds.messageType
                cell.selectIdx = self.isCountiue
                cell.callblack = {[weak self] idx in
                    if let idx:Int = idx as? Int{
                        self?.isCountiue = idx
                    }else if let sts = idx as? String {
                        self?.moreItem.insert(sts, at: 0)
                        self?.isCountiue = 0
                    }
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                        self?.SpeakTableView.reloadData()
                    }
                }
                return cell
            }
        }else{
//            if mds.messageType.rawValue > SpeakMessageType.language.rawValue && mds.role == .speakAI && (indexPath.row == step-2) {
//                let cell = tableView.dequeueReusableCell(withIdentifier: SpeakEleTranSCell.id, for: indexPath) as! SpeakEleTranSCell
//                cell.data = mds
//                return cell
//            }else{
                let cell = tableView.dequeueReusableCell(withIdentifier: SpeakEleQATextCell.id) as! SpeakEleQATextCell
                cell.data = mds
                return cell
//            }
        }
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let c = cell as? SpeakEleQABaseViewCell {
            c.reload()
        }
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView()
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
}
