//
//  SessionController+Event.swift
//  LegendTeam
//
//  Created by 梁博 on 23/12/21.
//

import Foundation
import UIKit
import URLNavigator
import NIMSDK

extension SessionController: SessionCellDelegate {
    func setupEvent() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChanged(noti:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(menuHide(noti:)), name: UIMenuController.didHideMenuNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(notifyChatSettingUpdated), name: AppNotificationName.chatSettingUpdated.notificationName, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(notifiyRelationHiddenUpdate), name: AppNotificationName.heartbeatRelationHiddenUpdate.notificationName, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(notifiyRelationInfoUpdate), name: AppNotificationName.aiRoleRelationInfoUpdated.notificationName, object: nil)
        

        sessionNavigationView.navigationView.tapBackButtonAction = { [weak self] in
            self?.close()
        }
        sessionNavigationView.naviMoreButton.addTarget(self, action: #selector(tapNaviMore(sender:)), for: .touchUpInside)
        sessionNavigationView.likeView.likeButton.addTarget(self, action: #selector(tapLikeButton), for: .touchUpInside)
        sessionNavigationView.heartTopButton.addTarget(self, action: #selector(tapHeartBeatTop), for: .touchUpInside)
        sessionNavigationView.newPeopleAvatarTopButton.addTarget(self, action: #selector(tapAIHead), for: .touchUpInside)
        sessionNavigationView.aiAvatarTopButton.addTarget(self, action: #selector(tapAIHead), for: .touchUpInside)
        sessionNavigationView.mineAvatarTopButton.addTarget(self, action: #selector(tapMineHead), for: .touchUpInside)
        
        let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTapPureBg(_:)))
        doubleTap.numberOfTapsRequired = 2   // 双击
        doubleTap.numberOfTouchesRequired = 1 // 单指
        view.addGestureRecognizer(doubleTap)
    }
    
    func longPressAction(model: SessionBaseModel?, cell: SessionCell?) {
        guard let theCell = cell else { return }
        // 长按
        guard model?.cellType == .text else {
            return
        }
        becomeFirstResponder()

        showCopyItem(cell: theCell)
    }

    func showCopyItem(cell: SessionCell) {
        let copyItem = UIMenuItem(title: "Copy", action: #selector(copyAction))
        let menuVC = UIMenuController.shared
        menuVC.menuItems = [copyItem]
        menuVC.showMenu(from: cell.containerView, rect: cell.containerView.bounds)
        menuVC.setMenuVisible(true, animated: true)

        menuCell = cell
    }

    func retryAction(model: SessionBaseModel?) {
        guard let message = model?.v2msg else { return }
        
        if message.messageStatus.errorCode == 20000{
            if (WalletCore.shared.balance.balance ?? 0) < 100{
                //CLPurchase.shared.showIAPBuyCoinSheet()
                IMAIViewModel.shared.showChatModelInsufficentCoinSheet()
                return
            }
        }else if message.messageStatus.errorCode == 20001{
            if let heartbeatLevel = aiInfo?.aiUserHeartbeatRelation?.heartbeatLevel, heartbeatLevel.isGreaterOrEqual(to: HeartbeatLevel.level2){
                // Do nothing
            }else{
                AppRouter.goAIHeartBeatLevelPage(aiId: self.aiId)
                return
            }
        }
        
        if message.isSelf{
            util.sendMessage(message: message)
        }else{
            // Fetch?
        }
//
//        if let localExt = message.localExt as? [String: Any] {
//            if let code = localExt["code"] as? String {
//                if code == "20000" {
//                    // 发送上限
////                    return
//                }
//            }
//        }
//        if message.isReceivedMsg {
//            // 重新接收
//            try? NIMSDK.shared().chatManager.fetchMessageAttachment(message)
//        } else {
//            // 重新发送
//            try? NIMSDK.shared().chatManager.resend(message)
//        }
    }

    /// cell事件，可能是非点击
    func onTapCellAction(event: IMEventModel?) {
        guard let theEvent = event else { return }
        cancelEditing()

        switch theEvent.eventType {
        case .image:
            tapCellImage(event: theEvent)
        case .contentUrl:
            dealContentUrl(event: theEvent)
        case .contactUS:
            break
        case .phonecallTap:
            restartPhoneCall(event: theEvent)
        case .aiMsgLongPress:
            showAIMsgLongPressPopover(event: theEvent)
        case .playAITextToAudio:
            dealPlayAIMsgAudio(event: theEvent)
        default:
            break
        }
    }
}

extension SessionController {
    
    // MARK: - Functions
    func tapCellImage(event: IMEventModel) {
        guard let tagModel = event.cellModel else{
            return
        }
        guard let attchment = tagModel.baseRemoteInfo?.customAttachment else{
            showCellImage(tagModel: tagModel)
            return
        }
        // Tap the picture that need unlock!
        if let price = attchment.unlockPrice, price > 0{
            var params = [String: Any]()
            params.updateValue(aiId!, forKey: "aiId")
            if let albumId = attchment.albumId{
                params.updateValue(albumId, forKey: "albumId")
            }
            if let  messageServerId = tagModel.v2msg?.messageServerId{
                params.updateValue(messageServerId, forKey: "messageServerId")
            }
            Hud.showIndicator()
            ChatProvider.request(.viewAIUnlockAlbumImg(params: params), modelType: AIAlbumUnlockImages.self, autoShowErrMsg: false) {[weak self] result in
                Hud.hideIndicator()
                switch result {
                case .success(let model):
                    // 1. 正常查看图片。替换price
                    guard let img1 = model?.img1 else{
                        return
                    }
                    let photoModel = PhotoBrowserModel()
                    photoModel.imageUrl = img1
                    if let imageView = event.senderView as? UIImageView{
                        photoModel.placeHolder = imageView.image
                        photoModel.sourceRect = PhotoBrowserModel.getViewRectForScreen(with: imageView)
                    }
                    ImageBrowser.show(models: [photoModel], index: 0, type: .roleOthersInIm)
                    tagModel.baseRemoteInfo?.customAttachment?.url = img1
                    tagModel.baseRemoteInfo?.customAttachment?.unlockPrice = 0
                    self?.tableView.reloadData()

                case .failure(let error):
                    switch error {
                    case let .serviceError(code, _):
                        if code == .imageBrowseButUnlock{
                            // 大图浏览未解锁照片、去解锁
                            guard let self = self else {return}
                            let photoModel = PhotoBrowserModel()
                            photoModel.sessionModel = tagModel
                            photoModel.aiId = self.aiId!
                            photoModel.imageUrl = attchment.url
                            if let imageView = event.senderView as? UIImageView{
                                photoModel.placeHolder = imageView.image
                                photoModel.sourceRect = PhotoBrowserModel.getViewRectForScreen(with: imageView)
                            }
                            ImageBrowser.show(models: [photoModel], index: 0, type: .roleOthersInIm)

                            self.tableView.reloadData()
                        }
                    default:
                        break
                        
                    }
                }
            }
        }else{
            showCellImage(tagModel: tagModel)
        }
    }
    
    func showCellImage(tagModel: SessionBaseModel?) {
        
        var index: Int = 0
        var photoModels: [PhotoBrowserModel] = [PhotoBrowserModel]()
        for theCell in tableView.visibleCells {
            guard let cell = theCell as? SessionCell else { continue }
            let cellModel = cell.model
            guard let message = cellModel?.v2msg, tagModel === cellModel else {
                continue
            }
            // image类型
            if cellModel?.cellType == .image {
                let photoModel = PhotoBrowserModel()
                //photoModel.message = message
                
                let info = IMRemoteUtil.dealRemoteInfo(message: message)
                photoModel.imageUrl = info.customAttachment?.url
                if let contentView = cell.containerView as? IMImageContentView {
                    // 获取占位图片和区域
                    if let image = contentView.imageView.image {
                        photoModel.image = image
                        photoModel.placeHolder = image
                    }
                    photoModel.sourceRect = PhotoBrowserModel.getViewRectForScreen(with: contentView.imageView)
                }

                if tagModel === cellModel {
                    index = photoModels.count
                }
                photoModels.append(photoModel)
            }
        }

        ImageBrowser.show(models: photoModels, index: index, type: .roleOthersInIm)
    }

    func dealContentUrl(event: IMEventModel) {
        guard var urlString = event.linkData else { return }

        if urlString.hasPrefix(AppConst.schemePrefix) {
            navigator.open(urlString)
            return
        }

        if !urlString.contains("://") {
            urlString = "https://\(urlString)"
        }
        guard let url = URL(string: urlString) else { return }

        dlog("⚠️tap url: \(url)")
    }

    func restartPhoneCall(event: IMEventModel) {
//        let model = event.cellModel
//        headPhoneCallGuideTapCall()
    }
    
    func showAIMsgLongPressPopover(event: IMEventModel) {
        guard let sender = event.senderView else{
            return
        }
        guard let msg = event.cellModel?.v2msg else{
            return
        }
        
        let createTimestamp = msg.createTime
        let msgDate = Date(seconds: createTimestamp)
        var okToLikeOrDislike = true
        if Date().hours(from: msgDate) > 24 * 7{
            okToLikeOrDislike = false
        }
        
        let remoteInfo = IMRemoteUtil.dealRemoteInfo(message: msg)
        
        let pop = CLPopoverListView()
        let rect = view.convert(sender.frame, from: sender.superview)
        var items = [CLPopoverListTextItem]()
        do {
            let listItem = CLPopoverListTextItem()
            listItem.title = "Copy"
            listItem.image = MWIconFont.image(fromIcon: .copy, size: CGSize(width: 20, height: 20), color: .text)
            listItem.updateLayout()
            listItem.selectedHandler = { _ in
                guard let msg = event.cellModel?.v2msg else{
                    return
                }
                let string = msg.text ?? ""
                UIPasteboard.general.string = string
                Hud.toast(str:"Copy success")
            }
            items.append(listItem)
        }
        if okToLikeOrDislike {
            let listItem = CLPopoverListTextItem()
            listItem.title = "Like"
            if let optType = remoteInfo.optType, optType == .upvote{
                listItem.image = MWIconFont.image(fromIcon: .postRecommendFill, size: CGSize(width: 20, height: 20), color: .c.cpn)
            }else{
                listItem.image = MWIconFont.image(fromIcon: .iconPostRecommend, size: CGSize(width: 20, height: 20), color: .text)
            }
            listItem.updateLayout()
            listItem.selectedHandler = {[weak self] _ in
                self?.doLikeAIMessage(msg: msg)
            }
            items.append(listItem)
        }

        if okToLikeOrDislike {
            let listItem = CLPopoverListTextItem()
            listItem.title = "Dislike"
            if let optType = remoteInfo.optType, optType == .downvote{
                listItem.image = MWIconFont.image(fromIcon: .postNotrecommendFill, size: CGSize(width: 20, height: 20), color: .c.cpn)
            }else{
                listItem.image = MWIconFont.image(fromIcon: .iconPostNotrecommend, size: CGSize(width: 20, height: 20), color: .text)
            }
            listItem.updateLayout()
            listItem.selectedHandler = {[weak self] _ in
                self?.doDislikeAIMessage(msg: msg)
            }
            items.append(listItem)
        }
        pop.setupCommonPopover(rect, inView: view, items: items, block: nil)
    }
    
    private func doLikeAIMessage(msg: V2NIMMessage){
        let remoteInfo = IMRemoteUtil.dealRemoteInfo(message: msg)
        if let optType = remoteInfo.optType, optType == .upvote{
            doOptAIMessage(msg: msg, opt: .unknow)
            return
        }
        doOptAIMessage(msg: msg, opt: .upvote)
    }
    
    private func doDislikeAIMessage(msg: V2NIMMessage){
        let remoteInfo = IMRemoteUtil.dealRemoteInfo(message: msg)
        if let optType = remoteInfo.optType, optType == .downvote{
            doOptAIMessage(msg: msg, opt: .unknow)
            return
        }
        
        doOptAIMessage(msg: msg, opt: .downvote)
    }
    
    private func doOptAIMessage(msg: V2NIMMessage, opt: MsgOptType){
        var params = [String : Any]()
        
        let theAIId = aiId ?? 0
        
        params.updateValue(theAIId, forKey: "aiId")
        if let messageServerId  = msg.messageServerId, messageServerId.count > 0{
            params.updateValue(messageServerId, forKey: "messageId")
        }else{
            params.updateValue("prologue_\(theAIId)", forKey: "messageId")
        }
        params.updateValue(msg.text ?? "", forKey: "content")
        params.updateValue(opt.rawValue, forKey: "optType")
        Hud.showIndicator()
        IMProvider.request(.aiUserMsgFeedback(params: params), modelType: EmptyModel.self) { result in
            Hud.hideIndicator()
            switch result {
            case .success:
                break
            case .failure:
                break
            }
        }
    }
    
    private func dealPlayAIMsgAudio(event:IMEventModel){
        let model = event.cellModel
        model?.prepareAudio (info: aiInfo) { model in
            if let speechModel = model{
                if let view = event.senderView as? IMAIMsgContentView{
                    view.refreshModel(model: view.model) //refresh StateChange
                }
                SpeechManager.shared.startPlay(with: speechModel)
            }else{
                // Nothing
            }
        }
    }
    
    func letAISendPrologue(){
//        #warning("to do, 此处的相关逻辑，需要换成本地逻辑")
//        ChatProvider.request(.letAISendPrologue(aiId: userId!), modelType: EmptyModel.self) { _ in
//            
//        }
        guard let dialoguePrologue = aiInfo?.dialoguePrologue else {return}
        
        if aiInfo?.isDelChatted.boolValue == false{
            // 本地添加一条开场白消息
            let msg = IMMessageMaker.msgWithText(dialoguePrologue)
            util.appendWith(messages: [msg])
            tableView.reloadData()
        }
    }
    
    
    // MARK: - Action
    
    @objc func tapNaviMore(sender: UIButton) {
        // sessionNavigationView.upDownNoticeView.showUnlocked(string: "XY")
        inputEntrance.inputTextView.resignFirstResponder()
        
//        let vc = ChatSettingListController()
//        vc.aiId = aiId
//        navigationController?.pushViewController(vc, animated: true)
        UIView.animate(withDuration: 0.25) {
            self.swipeBgView.alpha = 1.0
            self.swipeView.snp.updateConstraints { make in
                make.left.equalToSuperview().offset(UIScreen.width * 0.16)
            }
            self.view.layoutIfNeeded()
        }
    }
    
    @objc func tapLikeButton(){
//        guard let user = userInfo else{return}
//        let liked = user.liked ?? false
//        let likedNum = user.likedNum ?? 0
//
        guard UserCore.shared.checkUserLoginIfNotPushUserToLogin() else{return}
        
        guard let likeView = sessionNavigationView.likeView else{return}
        // 防止重复点击
        guard !isRequesting else { return }
        guard let user = aiInfo, let aiId = user.aiId else { return }
        
        let isliked = user.liked.boolValue
        let likedCount = user.likedNum ?? 0
        
        isRequesting = true
        
        // 禁用按钮
        likeView.likeButton.isEnabled = false
        
        if isliked {
            // 取消点赞
            let likeNewStatus = LikeOrCancelStatus.cancel
            let newLikedCount = max(likedCount - 1, 0)
            
            // 立即更新UI状态
            aiInfo?.liked = false
            aiInfo?.likedNum = newLikedCount
            sessionNavigationView.config(user: aiInfo)
            likeView.isLike = false
            likeView.countLabel.text = String.displayNumber(NSNumber(value: newLikedCount), scale: 1)
            
            AIRoleProvider.request(.aiUserLikeOrCancel(aiId: aiId, likedStatus: likeNewStatus), modelType: EmptyModel.self) { [weak self] result in
                self?.handleLikeRequestResult(result: result, aiId: aiId, isLike: false, originalLikedCount: likedCount)
            }
        } else {
            // 点赞
            let likeNewStatus = LikeOrCancelStatus.liked
            let newLikedCount = likedCount + 1
            
            // 播放点赞动画
            likeView.playLotteLike { [weak self] completed in
                // 立即更新UI状态
                self?.aiInfo?.liked = true
                self?.aiInfo?.likedNum = newLikedCount
                self?.sessionNavigationView.config(user: self?.aiInfo)
                likeView.isLike = true
                likeView.countLabel.text = String.displayNumber(NSNumber(value: newLikedCount), scale: 1)
            }
            
            AIRoleProvider.request(.aiUserLikeOrCancel(aiId: aiId, likedStatus: likeNewStatus), modelType: EmptyModel.self) { [weak self] result in
                self?.handleLikeRequestResult(result: result, aiId: aiId, isLike: true, originalLikedCount: likedCount)
            }
        }
    }
    // 统一处理请求结果
    private func handleLikeRequestResult(result: Result<EmptyModel?, ResponseError>, aiId: Int, isLike: Bool, originalLikedCount: Int) {
        isRequesting = false
        guard let likeView = sessionNavigationView.likeView else{return}
        
        likeView.likeButton.isEnabled = true
        
        switch result {
        case .success:
            // 请求成功，无需额外处理
            break
        case .failure:
            // 请求失败，恢复状态
            if let currentAiId = self.aiInfo?.aiId, currentAiId == aiId {
                if isLike {
                    // 点赞失败，恢复为未点赞状态
                    aiInfo?.liked = false
                    aiInfo?.likedNum = originalLikedCount
                    likeView.isLike = false
                    likeView.countLabel.text = String.displayNumber(NSNumber(value: originalLikedCount), scale: 1)
                } else {
                    // 取消点赞失败，恢复为点赞状态
                    aiInfo?.liked = true
                    aiInfo?.likedNum = originalLikedCount
                    likeView.isLike = true
                    likeView.countLabel.text = String.displayNumber(NSNumber(value: originalLikedCount), scale: 1)
                }
            }
            sessionNavigationView.config(user: aiInfo)
        }
        // 刷新统计
        
    }

    @objc func tapHeartBeatTop() {
        let vc = HeartBeatLevelGridController()
        vc.aiId = aiId
        navigationController?.pushViewController(vc, animated: true)
    }

    @objc func tapAIHead() {
        AppRouter.goAIRoleHome(aiId: aiId)
    }

    @objc func tapMineHead() {
        AppRouter.goBackRootController(jumpIndex: .me)
    }
    
    @objc func handleDoubleTapPageBg(_ gesture: UITapGestureRecognizer) {
        let location = gesture.location(in: tableView)
        
        // 获取点击位置的 indexPath（如果点击在 cell 上）
        if let indexPath = tableView.indexPathForRow(at: location) {
            print("双击了第 \(indexPath.section) 组，第 \(indexPath.row) 行")
        } else {
            print("双击在空白区域")
        }
        
        doDoubleTabBg()
    }
    
    @objc private  func handleDoubleTapPureBg(_ gesture: UITapGestureRecognizer) {
        leavePureMode()
    }
    
    private func doDoubleTabBg(){
        if pureBgOperateView == nil{
            pureBgOperateView = {
                let v = SessionPureBgOperateView()
                view.addSubview(v)
                v.snp.makeConstraints { make in
                    make.leading.trailing.bottom.equalToSuperview()
                }
                v.isHidden = true
                return v
            }()
            pureBgOperateView.backButton.addTap {[weak self] _ in
                self?.doDoubleTabBg()
            }
            
            pureBgOperateView.shareButton.addTap {[weak self] _ in
                self?.tapShare()
            }
            
            pureBgOperateView.middleButton.addTap {[weak self] _ in
                self?.tapSetChatBackgroud()
            }
        }
        
        if pureBgOperateView.isHidden == true{
            enterPureMode()
        }else{
            leavePureMode()
        }
    }
    
    private func enterPureMode(){
        // 进入纯净模式
        pureBgOperateView.isHidden = false
        
        sessionNavigationView.isHidden = true
        bottomViewsStackV.isHidden = true
        tableView.isHidden = true
        
        view.endEditing(true)
        hideOperateView()
    }
    
    private func leavePureMode(){
        if pureBgOperateView != nil{
            pureBgOperateView.isHidden = true
        }
        
        sessionNavigationView.isHidden = false
        bottomViewsStackV.isHidden = false
        tableView.isHidden = false
    }
    
    func tapShare(){
        guard let aiId = aiId else{return}
        let content = "Come to Crushlevel for chat, Crush, and AI - chat."
        let urlString = "\(AppConst.h5urlRoot)/@\(aiId)"
        
        guard let url = URL(string: urlString) else { return }
        
        // 分享内容（文字 + 链接）
        let items: [Any] = [url, content]
        
        let activityVC = UIActivityViewController(activityItems: items,
                                                  applicationActivities: nil)
        
        // iPad 需要设置弹出位置，否则会崩溃
        if let popover = activityVC.popoverPresentationController {
            popover.sourceView = view
            popover.sourceRect = CGRect(x: view.bounds.midX,
                                        y: view.bounds.midY,
                                        width: 0, height: 0)
            popover.permittedArrowDirections = []
        }
        
        present(activityVC, animated: true, completion: nil)
    }
    
    private func tapSetChatBackgroud(){
        guard let aiId = aiId else{return}
        let vc = ChatBackgroundGridController()
        vc.aiId = aiId
        
        let navc = CLNavigationController(rootViewController: vc)
        navc.modalPresentationStyle = .fullScreen
        present(navc, animated: true)
        
        // 红点
        var config = AppCache.fetchCache(key: CacheKey.chatRedBadgeConfig.rawValue, type: ChatSettingCacheConfig.self) ?? ChatSettingCacheConfig()
        if !config.chatBackgroundTapped{
            config.chatBackgroundTapped = true
            AppCache.cache(key: CacheKey.chatRedBadgeConfig.rawValue, value: config)
            NotificationCenter.post(name: .chatNaviMoreRedDotChanged)
        }
    }
}

// 长安菜单
extension SessionController {
    override var canBecomeFirstResponder: Bool {
        return true
    }

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        guard let items = UIMenuController.shared.menuItems else { return false }
        for item in items {
            if action == item.action {
                return true
            }
        }
        return false
    }

    @objc func copyAction() {
        guard let cell = menuCell else { return }
        guard let contentView = cell.containerView as? IMTextContentView else { return }
        guard let text = contentView.contentLabel.text else { return }
        UIPasteboard.general.string = text
        Hud.toast(str: "Copy successful")
    }
}
