
import NIMSDK
import SnapKit
import TZImagePickerController
import UIKit
import Combine
class SessionController: CLBaseViewController {
    var sessionNavigationView: SessionNavigationView!
    var bgImageView: UIImageView!
    var overlay: GradientView!

    var tableView: UITableView!
    // var headView: SessionAIHeadView!
    
    var swipeView: ChatSettingSwipeView!
    var swipeBgView: UIView!
    
    // MARK: BottomViews
    var bottomViewsStackV : InputStackView!
    var toolView: UIView!
    var inputEntrance: SessionInputOperateView!
    var inputBar: SessionInputView!
    var moreView: IMMoreItemView!
    var giftSendView: GiftGridSendView!
    var textSuggestionsView : SessionInputSuggestionsView!
    
    var voiceHoldView: IMVoiceHoldView!
    var pureBgOperateView:SessionPureBgOperateView!

    var titleStr: String? = nil

    // 长按菜单响应的cell
    var menuCell: SessionCell?

    // IM user info
    var aiInfo: IMAIUserInfo?

    // -- Layout
    var bottomConstraintForInputBar: Constraint?

    // -- flag
    var firstLoadedUser = false;
    var isDisappearing = false// 是否正在消失
    var dealCancelEditing = false// 是否正在退出键盘输入
    var kuolieReportMatchedChatOnce = false // v1.6.0 kuolie
    var isRequesting = false
    var isPullingToAIHomePage = false

    // --- view model
    lazy var giftVM = GiftViewModel()
    
    /// 此版本也是aiId
    var aiId: Int!
    /// 439257063882753@r@t
    var accountId:String!
    /// eg: 439213911113729@u@t|1|439257063882753@r@t
    var conversationId: String!
    var conversation: V2NIMConversation!
    
    var util: SessionUtil! = SessionUtil()
    
    var cancellables = Set<AnyCancellable>()

    convenience init(accountID: String) {
        self.init()
        accountId = accountID
        
        let array = accountID.components(separatedBy: "@")
        if let number = Int(array.first ?? "0"){
            aiId = number
        }
        
        self.conversationId = V2NIMConversationIdUtil.p2pConversationId(accountID)
        if self.conversationId != nil{
            conversation = V2NIMConversation()
            NIMSDK.shared().v2ConversationService.getConversation(conversationId) {[weak self] conversation in
                self?.conversation = conversation
            } failure: { error in
                dlog("☁️❌get \(String(describing: self.conversationId)) conversation error:\(error)")
            }
        }else{
            dlog("❌p2pConversationId failed")
        }
    }
    
    convenience init(conversationId: String, title: String? = "") {
        self.init()
        self.conversationId = conversationId
        self.titleStr = title
        conversation = V2NIMConversation()
        
        let stings = conversationId.components(separatedBy: "|")
        guard let last = stings.last else{return}
        accountId = last
        let strings2 = last.components(separatedBy:"@")
        if let userIdStr = strings2.first {
            if let userid = Int(userIdStr) {
                aiId = userid
            }
        }
        
        NIMSDK.shared().v2ConversationService.getConversation(conversationId) {[weak self] conversation in
            self?.conversation = conversation
        } failure: { error in
            dlog("☁️❌get \(String(describing: self.conversationId)) conversation error:\(error)")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupData()
        setupEvent()

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        (navigationController as? CLNavigationController)?.disabledFullScreenPan()
        IMAIViewModel.shared.updateAI(aiInfo)
        IMManager.shared.addCache(sessionID: conversationId)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        isDisappearing = false
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        isDisappearing = true
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        isDisappearing = false
        (navigationController as? CLNavigationController)?.enabledFullScreenPan()
        cancelEditing()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        // 动态调整tableView的contentInset
        adjustTableViewContentInset()
    }

    deinit {
        IMManager.shared.deleteCache(sessionID: conversationId)
        IMManager.shared.clearUnreadCountBy(ids: [conversationId])
    }
}

// MARK: - Views

extension SessionController {
    func setupUI() {
        view.clipsToBounds = false  // 允许子视图绘制到框外，支持超框点击
        navigationView.backgroundColor = .clear
        navigationView.backButton.setImage(nil, for: .normal)
        
        sessionNavigationView = {
            let v = SessionNavigationView()
            v.navigationView.title = self.titleStr ?? ""
            v.navigationView.iconImgView.isHidden = false
            view.addSubview(v)
            v.snp.makeConstraints { make in
                make.top.leading.trailing.equalToSuperview()
            }
            return v
        }()

        bgImageView = {
            let v = UIImageView()
            v.contentMode = .scaleAspectFill
            view.addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.trailing.equalToSuperview()
                make.top.equalToSuperview()
                make.bottom.equalToSuperview() // 得加，不然图片高度不够撑满
            }
            return v
        }()
        // bgImageView.image = UIImage(named: "egpic")?.cropImageTop(with: 1 / UIScreen.aspectRatio)

        overlay = {
            let v = GradientView(colors: [UIColor.c.cbn.withAlphaComponent(1), UIColor.c.cbn.withAlphaComponent(0), UIColor.c.cbn.withAlphaComponent(0), UIColor.c.cbn.withAlphaComponent(1)], gradientType: .topToBottom)
            v.imBgOverlayMode = true
            view.addSubview(v)
            v.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }
            return v
        }()

        setupInputView()

        
        setupTableView()

        view.bringSubviewToFront(sessionNavigationView)
        view.bringSubviewToFront(bottomViewsStackV)
        
        swipeBgView = {
            let bgView = UIView()
            bgView.alpha = 0.0
            bgView.backgroundColor = UIColor.init(white: 0.0, alpha: 0.8)
            view.addSubview(bgView)
            bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(bgViewTap)))
            bgView.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }
            return bgView
        }()
        
        swipeView = {
            let v = ChatSettingSwipeView()
            v.closeAction = { [weak self] in
                self?.bgViewTap()
            }
            v.backgroundColor = .white
            view.addSubview(v)
            v.snp.makeConstraints { make in
                make.left.equalToSuperview().inset(UIScreen.width)
                make.top.bottom.equalToSuperview()
                make.width.equalTo(UIScreen.width * 0.84)
            }
            return v
        }()
        
    }

    func setupUserInfo() {
        
        let imUserInfo = IMUserKit.imUserKitWith(accId: accountId) {[weak self] kit in
            if self?.conversation.conversationId == kit?.accountId{
                self?.navigationView.titleLabel.text = kit?.nickname
            }
        }
        
        if let userId = imUserInfo.userId, userId > 0 {
            // titleView.titleLabel.text = kitInfo.showName
            Hud.showIndicator()
            requestUserInfo(userId: userId)
        } else if aiId > 0 {
            Hud.showIndicator()
            requestUserInfo(userId: aiId)
        }else{
            assert(false)
        }
    }

    func reloadViews() {
        guard let user = aiInfo else {
            return
        }
        
        bgImageView.loadImage(user.backgroundImg, completionBlock:  {[weak self] result in
            switch result {
            case let .success(imageResult):
                let image = imageResult.image
                self?.bgImageView.snp.makeConstraints { make in
                    make.width.equalTo((self?.bgImageView.snp.height)!).multipliedBy(image.size.width / image.size.height)
                }
                //self?.bgImageView.image = image.cropImageTop(with: 1/UIScreen.aspectRatio)
            case .failure:
                return
            }
        })
        
        sessionNavigationView.config(user: user)

        tableView.reloadData()
        // 刷新一些页面上的其他数据（通过UserInfo）
    }
}

// MARK: Datas & Events

extension SessionController {
    func setupData() {
        setupNIM()
        
        util.conversationId = conversationId
    
        setupUserInfo()
        
        WalletCore.shared.refreshWallet()
        // 进入页面需要标记已读
        markReadAll()
    }

    @objc func bgViewTap() {
        UIView.animate(withDuration: 0.25) {
            self.swipeBgView.alpha = 0.0
            self.swipeView.snp.updateConstraints { make in
                make.left.equalToSuperview().inset(UIScreen.width)
            }
            self.view.layoutIfNeeded()
        }
    }
   
}

// MARK: - Noti

extension SessionController {
    @objc func keyboardWillChanged(noti: Notification) {
//        guard tableView.window != nil else {
//            return
//        }
        if isDisappearing || isDisplaying == false {
            return
        }
        guard let userInfo = noti.userInfo else { return }

        // 获取参数
        let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! TimeInterval
        let curve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey]! as! Int
        let beginFrame = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

        var hideKeyboardFlag = false
        var showKeyboardFlag = false
        
        // dlog("⌨️duration:\(duration)")

        if beginFrame.origin.y < UIScreen.height, endFrame.origin.y >= UIScreen.height {
            // 收起键盘
            hideKeyboardFlag = true
            //dlog("⌨️close keyboard")
        } else if beginFrame.origin.y >= UIScreen.height, endFrame.origin.y < UIScreen.height {
            // 弹出键盘
            showKeyboardFlag = true
            //dlog("⌨️show keyboard")
        } else if beginFrame.size.height != endFrame.size.height {
            // 键盘高度变更
            //dlog("⌨️height of keyboard changed")
        }


        if hideKeyboardFlag{ // 将要关键盘
            self.doHideKeyBordActions()
        }else if showKeyboardFlag{ // 将要显示键盘
            self.doKeyboardShowActions()
            let offsetY = UIScreen.height - endFrame.origin.y// - UIWindow.safeAreaBottom
            self.updateInputEntrance(offsetY: offsetY, duration: duration, curve: curve)
        }
        else if !self.dealCancelEditing {
            let offsetY = UIScreen.height - endFrame.origin.y// - UIWindow.safeAreaBottom
            self.updateInputEntrance(offsetY: offsetY, duration: duration, curve: curve)
        }
        
        UIView.animate(withDuration: duration,
                       delay: 0,
                       options: UIView.AnimationOptions(rawValue: UInt(curve) << 16),
                       animations: {
            self.view.layoutIfNeeded()
            
            self.scrollToBottom(self.tableView, animated: true)
        })
        
    }

    @objc func menuHide(noti: Notification) {
        guard let menu = noti.object as? UIMenuController else { return }
        guard let menuItems = menu.menuItems else { return }
        guard let first = menuItems.first else { return }
        if first.action == Selector(("copyAction")) {
            UIMenuController.shared.menuItems = nil
        } else {
        }
    }
    
    @objc func notifyChatSettingUpdated(){
        requestUserInfo(userId: aiId)
    }
    
    @objc func notifiyRelationHiddenUpdate(){
        requestUserInfo(userId: aiId)
    }
    
    @objc func notifiyRelationInfoUpdate(){
        requestUserInfo(userId: aiId)
    }
}

// MARK: - Action

// BottomViews
extension SessionController {
    @objc func titleTapAction() {
        guard let user = aiInfo, let aiId = user.aiId else { return }
        AppRouter.goAIRoleHome(aiId: aiId)
    }



    /// 主动退出键盘
    @objc func cancelEditing() {
        dealCancelEditing = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.dealCancelEditing = false
        }
        
        if inputBar.textView.isFirstResponder{
            view.endEditing(true)
        }else{
            hideOperateView()
        }

    }
    
    func doKeyboardShowActions(){
        self.inputBar.isHidden = true

        self.inputEntrance.isHidden = false
        // self.moreView.isHidden = true
        //showMoreItems(show: false)
    }
    
    @objc func doHideKeyBordActions() {
        // showHeaderView(show: true, duration: 0.3)
       
        UIView.animate(withDuration: 0.1) {
            self.inputBar.alpha = 0
            self.inputBar.layoutIfNeeded()
        } completion: { finished in
            self.inputBar.isHidden = true
            self.inputBar.alpha = 1
        }

//        self.inputEntrance.isHidden = false
//        self.bottomViewsStackV.setNeedsDisplay()
//        self.bottomViewsStackV.layoutIfNeeded()
//        showMoreItems(show: false)
        hideAllBottomViews(except: [toolView, inputEntrance])
        updateInputEntrance(offsetY: 0, duration: 0, curve: UIView.AnimationCurve.easeOut.rawValue) // 0.3

    }
}


// MARK: - Session Audio Phone call delegaet.

//
// extension SessionController: SessionHeadPhoneCallGuideDelegate {
//    func headPhoneCallGuideTapCall() {
//        guard AudioRecordTool.audioAuth() else {
//            return
//        }
//
//        guard AudioPlayTool.audioChannelFreeToUse(), PhoneManager.isInPhoneChannel() == false else {
//            return
//        }
//
//        hideCallGuide()
//        phoneCallHandler.onSelectVoice(user: userInfo, session: session)
//    }
// }

// MARK: - Animation

extension SessionController {
//    func showMoreItem(show: Bool) {
//        if show {
//            UIView.animate(withDuration: 0.3) {
//                self.moreView.alpha = 1
//                self.moreView.snp.updateConstraints { make in
//                    make.top.equalTo(self.inputBar.snp.bottom).offset(-UIWindow.safeAreaBottom)
//                }
//                self.view.layoutIfNeeded()
//            } completion: { _ in
//            }
//        } else {
//            UIView.animate(withDuration: 0.3) {
//                self.moreView.alpha = 0
//                self.moreView.snp.updateConstraints { make in
//                    make.top.equalTo(self.inputBar.snp.bottom).offset(10)
//                }
//                self.view.layoutIfNeeded()
//            } completion: { _ in
//            }
//        }
//    }
    func updateInputEntrance(offsetY: CGFloat, duration: TimeInterval, curve: Int) {
        let offsetY = offsetY > 0 ? offsetY : (UIWindow.safeAreaBottom)

        self.bottomViewsStackV.snp.updateConstraints { make in
            make.bottom.equalTo(self.view).offset(-offsetY)
        }
//        self.bottomViewsStackV.setNeedsDisplay()
//        self.bottomViewsStackV.layoutIfNeeded()
//        
//        // 添加这行来动态调整tableView的contentInset
//        DispatchQueue.main.async { [weak self] in
//            self?.adjustTableViewContentInset()
//        }
    }
    
    func updateTableContentOffset(duration: TimeInterval){
        UIView.animate(withDuration: duration) {
            self.updateTableViewContentLayout()
            self.view.layoutIfNeeded()
        }
    }
}
