//
//  SessionController+Input.swift
//  LegendTeam
//
//  Created by 梁博 on 24/12/21.
//

import Foundation
import UIKit
import NIMSDK
import TZImagePickerController

extension SessionController {
    func setupInputView() {
        
        bottomViewsStackV = {
            let v = InputStackView()
            v.axis = .vertical
            v.clipsToBounds = false  // 允许子视图绘制到框外，支持超框点击
            view.addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.trailing.equalToSuperview()
                make.bottom.equalToSuperview().offset(-UIWindow.safeAreaBottom)
            }
            return v
        }()
        
        inputBar = {
            let v = SessionInputView()
            v.delegate = self
            bottomViewsStackV.addArrangedSubview(v)
            v.isHidden = true
            return v
        }()
        
        toolView = {
            let view = UIView()
            bottomViewsStackV.addArrangedSubview(view)
            
            let exchangeBtn = UIButton(type: .custom)
            exchangeBtn.setImage(UIImage(named: "role_chat_change_open"), for: .normal)
//            exchangeBtn.addTarget(, action: <#T##Selector#>, for: <#T##UIControl.Event#>)
//            view.addSubview(exchangeBtn)
//            exchangeBtn.snp.makeConstraints { make in
//                make.right.equalToSuperview().inset(20)
//                make.bottom.equalToSuperview().inset(2)
//                make.top.equalToSuperview().inset(5)
//            }
            
            let scrToBottomBtn = UIButton(type: .custom)
            scrToBottomBtn.setImage(UIImage(named: "chat_scr_bottom"), for: .normal)
            
            let stackView = UIStackView(arrangedSubviews: [scrToBottomBtn, exchangeBtn])
            stackView.spacing = 10.0
            stackView.alignment = .fill
            stackView.alignment = .fill
            view.addSubview(stackView)
            stackView.snp.makeConstraints { make in
                make.right.equalToSuperview().inset(20)
                make.bottom.equalToSuperview().inset(2)
                make.top.equalToSuperview().inset(5)
            }
            
            let vipImgView = UIImageView(image: UIImage(named: "role_chat_vip"))
            vipImgView.isUserInteractionEnabled = false
            view.addSubview(vipImgView)
            vipImgView.snp.makeConstraints { make in
                make.bottom.equalToSuperview().inset(0)
                make.right.equalToSuperview().inset(18)
            }
            
            return view
        }()
        
        inputEntrance = {
            let v = SessionInputOperateView()
            v.delegate = self
            bottomViewsStackV.addArrangedSubview(v)
            return v
        }()
        
        moreView = {
            let v = IMMoreItemView(frame: CGRectMake(0, 0, UIScreen.width, IMMoreItemView.heightOfMoreItemView))
            v.delegate = self
            bottomViewsStackV.addArrangedSubview(v)
            v.isHidden = true
            return v
        }()
        
        voiceHoldView = {
            let v = IMVoiceHoldView()
            view.addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.trailing.bottom.equalToSuperview()
            }
            v.layer.zPosition = 100
            v.isHidden = true
            return v
        }()
        
        giftSendView = {
            let v = GiftGridSendView()
            v.delegate = self
            bottomViewsStackV.addArrangedSubview(v)
            v.isHidden = true
            return v
        }()
        
        textSuggestionsView = {
            let v = SessionInputSuggestionsView()
            bottomViewsStackV.addArrangedSubview(v)
            v.isHidden = true
            return v
        }()
        
        overlay.snp.remakeConstraints { make in
            make.top.leading.trailing.equalToSuperview()
            make.bottom.equalTo(inputEntrance.snp.bottom).offset(UIWindow.safeAreaBottom)
        }
        
        voiceHoldView.recordFinishedAction = {[weak self] url in
            self?.doSendVoice(url: url)
        }
        
        textSuggestionsView.tapItemWithAction = {[weak self] string , edit in
            guard string.count > 0 else {return}
            self?.textSuggestionsView.isHidden = true
            if edit {
                // 进入编辑框
                self?.inputBar.fillDefaultContent(string: string)
                self?.inputBar.becomeFirstResponder()
            }else{
                let msg = IMMessageMaker.msgWithText(string)
                self?.util.sendMessage(message: msg)
            }
        }
        
        inputBar.textView.textPublisher.sink {[weak self] string in
            self?.inputEntrance.inputTextView.text = string
        }.store(in: &cancellables)
    }
    
    // MARK: - Helper
    
    
    func hideAllBottomViews(except:[UIView]? = nil){
        let viewsExcept = except ?? []
        for view in bottomViewsStackV.arrangedSubviews {
            // 如果在 except 列表中，就保持显示，否则隐藏
            view.isHidden = !viewsExcept.contains(view)
        }
    }
    
    func hideOperateView(){
        hideAllBottomViews(except: [inputEntrance])
    }
    
    // MARK: - Functions
    private func doSendVoice(url: URL?){
        // ⚠️海外和大陆接口方式不同
        //asrWay1(url: url)
        
        asrWay2(url: url)
    }
    
    private func asrWay1(url: URL?){
        guard let voiceString = CLTool.m4aFileToBase64(fileURL: url) else{
            return
        }
        
        Hud.showIndicator()
        AICowProvider.request(.voiceAsr(voiceBase64: voiceString), modelType: String.self) {[weak self] result in
            Hud.hideIndicator()
            switch result {
            case .success(let model):
                dlog("☁️🎤:\(String(describing: model))")
                if let string = model, string.count > 0{
                    let msg = IMMessageMaker.msgWithText(string)
                    self?.util.sendMessage(message: msg)
                }
            case .failure:
                break
            }
        }
    }
    
    private func asrWay2(url: URL?){
        guard let pathInSandbox = url else{
            return
        }
        guard let aiId = aiId else {return}
        
        do {
           
            let data = try Data(contentsOf: pathInSandbox)
            // ✅ data 就是文件的二进制数据
            let model = UploadModel()
            model.addThisItemTimeStamp = Date().timeStamp
            model.fileData = data
            Hud.showIndicator()
            CloudStorage.shared.s3AddUploadAudio(model) { uploadResult in
                if uploadResult{
                    guard let remoteFullPath = model.remoteFullPath else{
                        assert(false)
                        return
                    }
                    AICowProvider.request(.voiceAsr2(url: remoteFullPath, aiId: aiId), modelType: AudioAsrResponse.self) {[weak self] result in
                        Hud.hideIndicator()
                        switch result {
                        case .success(let model):
                            if let response = model, let string = response.content, string.count > 0{
                                let msg = IMMessageMaker.msgWithText(string)
                                self?.util.sendMessage(message: msg)
                            }
                        case .failure:
                            break
                        }
                    }
                }else{
                    Hud.hideIndicator()
                }
            }
        } catch {
            print("❌读取文件audio mp3失败: \(error)")
        }
    }
    
    
    func dealWillSendMessage(message: V2NIMMessage) -> Bool {
        return IMManager.dealWillSendMessage(message: message)
    }
}

// MARK: - SessionInputOperateViewDelegate
extension SessionController: SessionInputOperateViewDelegate{
    func operateTapGiftAction() {

        view.endEditing(true)
        
        if giftSendView.isHidden{
            hideAllBottomViews(except: [inputEntrance, giftSendView])
            giftSendView.targetHeartbeatValue = aiInfo?.aiUserHeartbeatRelation?.heartbeatVal ?? 0
        }else{
            hideAllBottomViews(except: [inputEntrance])
        }
        
    }
    
    func operateVoiceAction(on: Bool){
        guard AudioRecordTool.audioAuth(showAlert: on) else{
            return
        }
        
        voiceHoldView.isHidden = !on
        voiceHoldView.record(on: on)
    }
    
    func operateTapMoreAction() {
        view.endEditing(true)
        
        if moreView.isHidden{
            hideAllBottomViews(except: [inputEntrance, moreView])
        }else{
            hideAllBottomViews(except: [inputEntrance])
        }
    }
    
    func operateTapHelpAction(){
        view.endEditing(true)
        
        if textSuggestionsView.isHidden == true{
            hideAllBottomViews(except: [inputEntrance, textSuggestionsView])
            textSuggestionsView.show(id: aiId)
        }else{
            hideAllBottomViews(except: [inputEntrance])
        }
        // bottomViewsStackV.layoutIfNeeded()
    }
    
    func operateTapInputFieldAction(){
        inputBar.becomeFirstResponder()
        
        hideAllBottomViews(except: [inputBar])
        // scrollToBottom(tableView, delay: 0.35, animated: true)
    }
}

// MARK: - IMInputBarDelegate

extension SessionController: IMInputBarDelegate {
    
    func albumTapAction(){
        doPickSendImage()
    }
    
    func giftTapAction() {
        operateTapGiftAction()
    }
    
    func helpTapAction(){
        operateTapHelpAction()
    }

    
    func sendTapAction(mesgStr: String, photo: UploadPhotoM? = nil) {
        if let photoModel = photo{
            
            var attachment = IMCustomAttachment()
            attachment.type = .IMAGE
            attachment.url = photoModel.remoteFullPath
            attachment.width = FlexibleCGFloat(photoModel.imageSize.width)
            attachment.height = FlexibleCGFloat(photoModel.imageSize.height)
            
            guard let jsonString = CodableHelper.encodeToJSONString(attachment) else{
                assert(false)
                return
            }
            // dlog("当前json:\(String(describing: jsonString))")
            
            let message = IMMessageMaker.msgWithCustom(mesgStr, attachMent: jsonString)
            util.sendMessage(message: message)
        }else{
            if mesgStr.trimmed.isEmpty {
                assert(false)
                return
            }
            let message = IMMessageMaker.msgWithText(mesgStr)
            let canSend = dealWillSendMessage(message: message)
            if canSend {
                util.sendMessage(message: message)
            }
        }
        
        inputBar.clearInputDatas()
    }
    
    func moreTapAction(){
        operateTapMoreAction()
    }

}

extension SessionController : IMMoreItemViewDelegate{
    func imMoreItemView(view: IMMoreItemView, tapType: IMMoreMenuType) {
        switch tapType {
        case .picture:
            doPickSendImage()
        case .phone:
            tryStartCall()
        case .share:
            tapShare()
        }
    }
    
    private func doPickSendImage(){
        guard let picker = ImagePicker(maxImagesCount: 1, delegate: self) else { return }
        present(picker, animated: true, completion: nil)
    }
    
    private func tryStartCall(){
        guard AudioRecordTool.audioAuth() else{
            return
        }
        
        guard let user = aiInfo, let levelNow = user.aiUserHeartbeatRelation?.heartbeatLevel else {
            AppRouter.goAIHeartBeatLevelPage(aiId: aiId)
            return
        }
        if levelNow.isGreaterOrEqual(to: .level4){
            doStartCall()
        }else{
            AppRouter.goAIHeartBeatLevelPage(aiId: aiId)
        }
    }
    
    private func doStartCall(){
        let vc = PhoneCallController()
        presentNaviRootVc(vc: vc)
        vc.callEventAction = {[weak self] callType, durationInMinistamp in
            guard let self = self else{return}
            switch callType{
            case .CALL_CANCEL:
                var model = IMCustomAttachment()
                model.type = .CALL
                model.callType = .CALL_CANCEL
                let msg = IMMessageMaker.msgWithCustom(attachment: model)
                util.sendMessage(message: msg)
            case .CALL_END:
                /*
                var model = IMCustomAttachment()
                model.type = .CALL
                model.callType = .CALL_END
                model.duration = durationInMinistamp
                let msg = IMMessageMaker.msgWithCustom(attachment: model)
                util.sendMessage(message: msg)
                 */
                // 此消息改为由后端发送
                break
            }
        }
    }
    
    private func doShare(){
        Hud.comingsoon()
    }
}

// MARK: - GiftGridSendViewDelegate
extension SessionController: GiftGridSendViewDelegate{
    func giftSend(giftId: Int,gift: GiftDictModel, num: Int) {
        guard let aiId = aiId else{
            return
        }
        var params = [String: Any]()
        
        params.updateValue(aiId, forKey: "aiId")
        params.updateValue(giftId, forKey: "giftId")
        params.updateValue(num, forKey: "num")
        params.updateValue("IM", forKey: "scene")
        
        Hud.showIndicator()
        ChatProvider.request(.aiUserGiftSend(params: params), modelType: EmptyModel.self) {[weak self] result in
            Hud.hideIndicator()
            switch result {
            case .success:
                self?.giftSendView.reset()
                // self?.giftSendView.isHidden = true
                
                WalletCore.shared.refreshWallet()
            case .failure:
                break
            }
        }
    }
    
    func giftGoHeartbeatPage(){
        guard let aiId = aiId else{
            return
        }
        // hideAllBottomViews()
        AppRouter.goAIHeartBeatLevelPage(aiId: aiId)
    }
    
    func giftGoVIPCenter(){
        AppRouter.goVIPCenter()
    }
    
    func giftNumPick(num: Int) {
        guard let window = UIWindow.getTopDisplayWindow() else { return } // 🔥 Assuming topDisplayWindow is a custom UIView extension method
        
        let rect1 = giftSendView.countImg.convert(giftSendView.countImg.frame, from: giftSendView.countImg.superview)
        let rect2 = giftSendView.countImg.convert(rect1, to: window)
        
        let vc = GiftCountChooseController(sourceRect: rect2, selectedValue: "\(num)")
        
        vc.chooseBlock = { [weak self] count in
            // ... Handle count selection
            self?.giftSendView.num = Int(count) ?? 1
        }
        
        vc.popoverDismiss = { [weak self] in
            // ... Handle popover dismissal
            self?.giftSendView.countImg.transform = .identity
            
        }
        
        addChild(vc)
        view.addSubview(vc.view)
        
        UIView.animate(withDuration: 0.2) {
            self.giftSendView.countImg.transform = CGAffineTransform(rotationAngle: .pi)
        }
    }
    
    
}

extension SessionController : TZImagePickerControllerDelegate{
    func imagePickerController(_: TZImagePickerController!,
                               didFinishPickingPhotos photos: [UIImage]!,
                               sourceAssets _: [Any]!,
                               isSelectOriginalPhoto _: Bool,
                               infos _: [[AnyHashable: Any]]!)
    {
        guard let img = photos.first else {
            return
        }
        
        inputBar.becomeFirstResponder()
        inputBar.bindImage(img: img)
    }
}

