//
//  SessionCell.swift
//  LegendTeam
//
//  Created by 梁博 on 17/12/21.
//

import UIKit
import Lottie
import NIMSDK
protocol SessionCellDelegate: NSObjectProtocol{
    func longPressAction(model: SessionBaseModel?, cell: SessionCell?)
    func retryAction(model: SessionBaseModel?)
    func onTapCellAction(event: IMEventModel?)
}

class SessionCell: UITableViewCell {
    var containerView: IMContentBaseView!
    var bubbleImageView: UIImageView!
    private var loadingView: LottieAnimationView?
    var retryButton: UIButton!

    weak var delegate: SessionCellDelegate?
    var model: SessionBaseModel?
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = .none
        self.backgroundColor = .clear
        
        let press = UILongPressGestureRecognizer(target: self, action: #selector(longPress(reco:)))
        addGestureRecognizer(press)
    }
    
    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 不规则corner
//        if self.containerView.bounds.size.height > 0 {
//            guard let cellModel = self.model else {
//                return
//            }
//            if cellModel.shouldShowCardView || cellModel.shouldShowTips {
//                // 不需要被裁减layer的情况
//                self.containerView.layer.mask = nil
//                return
//            }
//            // 添加圆角
//            var corner:UIRectCorner!
//            if cellModel.shouldShowLeft {
//                corner = [.topLeft, .topRight, .bottomRight]
//            } else {
//                corner = [.topLeft, .topRight, .bottomLeft]
//            }
//            
//            let maskPath = UIBezierPath(roundedRect: self.containerView.bounds, byRoundingCorners: corner, cornerRadii: CGSize(width: 20, height: 20))
//            let maskLayer = CAShapeLayer()
//            maskLayer.masksToBounds = true
//            maskLayer.frame = self.containerView.bounds
//            maskLayer.path = maskPath.cgPath
//            self.containerView.layer.mask = maskLayer
//        }
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        endLodingAnimation()
    }
    
    func setupUI() {
        guard let model = model else { return }
        
        let type = model.config.contentViewClass(model: model)
        containerView = type.init()
        contentView.addSubview(containerView)
        containerView.delegate = self
        containerView.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        retryButton = UIButton(type: .custom)
        contentView.addSubview(retryButton)
        retryButton.isHidden = true
        retryButton.touchAreaInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        retryButton.setImage(UIImage(named: "icon_im_notice"), for: .normal)
        retryButton.addTarget(self, action: #selector(retryAction), for: .touchUpInside)
        retryButton.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        bubbleImageView = UIImageView()
        bubbleImageView.contentMode = .scaleToFill
        containerView.addSubview(bubbleImageView)
        containerView.sendSubviewToBack(bubbleImageView)
        bubbleImageView.isHidden = true
        bubbleImageView.snp.makeConstraints { make in
            make.leading.equalTo(self.containerView.snp.leading)
            make.trailing.equalTo(self.containerView.snp.trailing)
            make.top.equalTo(self.containerView.snp.top)
            make.bottom.equalTo(self.containerView.snp.bottom)
        }
    }
    
    private func reloadViews(model: SessionBaseModel) {
        if containerView == nil {
            setupUI()
        }
        
        let onlyShowContent = model.config.onlyShowContent(model: model)
        let insets = model.config.cellInsets(model: model)
        let size = model.config.contentSize(model: model)
        let contentInets = model.config.contentInsets(model: model)
        // 内容view 大小
        let contentSize = CGSize(width: size.width + contentInets.left + contentInets.right, height: size.height + contentInets.top + contentInets.bottom)
        
//        dLog("contentSize___\(contentSize)___size___\(size)__type__\(model.cellType)")
        
        if onlyShowContent {
            containerView.snp.remakeConstraints { make in
                make.center.equalToSuperview()
                make.size.equalTo(contentSize)
            }
        } else {
            if model.shouldShowLeft {
                containerView.snp.remakeConstraints { make in
                    make.leading.equalToSuperview().offset(insets.left)
                    make.top.equalToSuperview().offset(insets.top)
                    make.size.equalTo(contentSize)
                }
                
                retryButton.snp.remakeConstraints { make in
                    make.leading.equalTo(containerView.snp.trailing).offset(8)
                    make.centerY.equalTo(containerView)
                    make.size.equalTo(CGSize(width: 16, height: 16))
                }
                
                loadingView?.snp.remakeConstraints { make in
                    make.leading.equalTo(containerView.snp.trailing).offset(8)
                    make.centerY.equalTo(containerView)
                    make.size.equalTo(CGSize(width: 16, height: 16))
                }
            } else {
                containerView.snp.remakeConstraints { make in
                    make.trailing.equalToSuperview().offset(-insets.right)
                    make.top.equalToSuperview().offset(insets.top)
                    make.size.equalTo(contentSize)
                }
                
                retryButton.snp.remakeConstraints { make in
                    make.trailing.equalTo(containerView.snp.leading).offset(-8)
                    make.centerY.equalTo(containerView)
                    make.size.equalTo(CGSize(width: 16, height: 16))
                }
                
                loadingView?.snp.remakeConstraints { make in
                    make.trailing.equalTo(containerView.snp.leading).offset(-8)
                    make.centerY.equalTo(containerView)
                    make.size.equalTo(CGSize(width: 16, height: 16))
                }
            }
        }
        
        contentView.layoutIfNeeded()
    }
    
    private func startLoadingAnimation() {
        if self.loadingView == nil {
            let animation = LottieAnimation.named("single_ring")
            let animationView = LottieAnimationView(animation: animation)
            animationView.contentMode = .scaleAspectFit
            animationView.loopMode = .loop
            animationView.backgroundBehavior = .pauseAndRestore
            animationView.backgroundColor = .clear
            addSubview(animationView)
            self.loadingView = animationView
        }
        self.loadingView?.isHidden = false
        self.loadingView?.play(completion: { _ in
        })
        reloadLoadingLayout()
    }
    
    private func endLodingAnimation() {
        self.loadingView?.isHidden = true
        self.loadingView?.stop()
    }
    
    func reloadLoadingLayout() {
        guard let theModel = model else { return }
        if (theModel.shouldShowLeft) {
            loadingView?.snp.remakeConstraints { make in
                make.leading.equalTo(containerView.snp.trailing).offset(8)
                make.centerY.equalTo(containerView)
                make.size.equalTo(CGSize(width: 16, height: 16))
            }
        } else {
            loadingView?.snp.remakeConstraints { make in
                make.trailing.equalTo(containerView.snp.leading).offset(-8)
                make.centerY.equalTo(containerView)
                make.size.equalTo(CGSize(width: 16, height: 16))
            }
        }
    }
}

//
extension SessionCell {
    public func bindCell(model: SessionBaseModel) {
        self.model = model
        
        reloadViews(model: model)
        containerView.refreshModel(model: model)
        
        bubbleImageView.isHidden = !model.shouldShowBubble
        if model.shouldShowLeft {
            bubbleImageView.backgroundColor = .clear
        } else {
            if let bubble = IMAIViewModel.shared.aiIMInfo?.chatBubble{// , bubble.isDefault.boolValue == false
                // Kinfinser load image
                ImageDownloader.downloadImage(from: bubble.webImgUrl) {[weak self] image in
                    guard let downloadBubble = image else{
                        self?.useDefaultBubbleStyle()
                        return
                    }
                    // ⚠️拉伸图片不能比实际最小的高度还高
                    let scaleImage = downloadBubble.scaled(toHeight: 68)
                    let stretchedImage = scaleImage!.stretchableImage(horizontalRatio: 0.5, verticalRatio: 0.5)
                    self?.bubbleImageView.image = stretchedImage
                }
            }else{
                useDefaultBubbleStyle()
            }
            
        }
        
        // loading hidden
        if activityLoadingHidden() || model.isDeriveModel || model.config.onlyShowContent(model: model) {
            endLodingAnimation()
        } else {
            startLoadingAnimation()
        }
        
        dealRetryButton()
    }
    
    private func useDefaultBubbleStyle(){
        let image = UIImage(named: "chat_bubble_default")!
        let scaleImage = image.scaled(toHeight: 44)
        let stretchedImage = scaleImage!.stretchableImage(horizontalRatio: 0.5, verticalRatio: 0.5)
        bubbleImageView.image = stretchedImage
    }
    
    /// 消息体左边的指示
    func dealRetryButton() {
        
        // 初始设置为retry按钮，初始Hidden
        retryButton.isHidden = disableRetryButton()
        retryButton.isUserInteractionEnabled = true
        let retryIcon = UIImage(named: "icon_im_retry")
        retryButton.setImage(retryIcon, for: .normal)
        
        guard let model = self.model else { return }
        guard let message = model.v2msg else { return }
        
        // 初始预定状态下，必定会被隐藏的
        let mustHide = model.isDeriveModel || model.shouldShowCardView
        
        let info = IMRemoteUtil.dealRemoteInfo(message: message)
        if info.cellType == .keyword , model.shouldShowBubble {
            retryButton.isHidden = false || mustHide
            retryButton.isUserInteractionEnabled = false
            retryButton.setImage(UIImage(named: "icon_im_notice"), for: .normal)
        }
        
        if message.sendingState == .MESSAGE_SENDING_STATE_FAILED{
            if message.messageStatus.errorCode == 20001{
                // 没业务权限发送照片
                retryButton.isHidden = false
                retryButton.setImage(UIImage(named: "icon_im_notice"), for: .normal)
            } else if message.messageStatus.errorCode == 20000{
                // 余额不足
                retryButton.isHidden = false
                retryButton.setImage(UIImage(named: "icon_im_notice"), for: .normal)
            }
        }
    }
    
    func activityLoadingHidden() -> Bool {
        guard let message = model?.v2msg else{
            return true
        }
        
        if message.isSelf{
            return message.sendingState != .MESSAGE_SENDING_STATE_SENDING
        }else{
            return true
        }
        
//        guard let message = model?.message else { return true }
//        if !message.isReceivedMsg {
//            return message.deliveryState != .delivering
//        } else {
//            return message.attachmentDownloadState != .downloading
//        }
    }
    
    func disableRetryButton() -> Bool {
        guard let cellModel = model else { return true }
        guard let message = cellModel.v2msg else { return true }
        
        if message.messageType == .MESSAGE_TYPE_TIP {
            return true
        }
//        if cellModel.isDeriveModel || cellModel.shouldShowCardView {
//            return true
//        }
//        if !message.isReceivedMsg {
//            return message.deliveryState != .failed
//        } else if message.from == NIMSDK.shared().loginManager.currentAccount() {
//            return !message.isBlackListed
//        } else {
//            return message.attachmentDownloadState != .failed
//        }
        return true
    }
}

// MARK: Action

extension SessionCell {
    @objc func retryAction() {
        delegate?.retryAction(model: self.model)
    }
    
    @objc func longPress(reco: UIGestureRecognizer) {
        if reco.state == .began {
            delegate?.longPressAction(model: self.model, cell:self)
        }
    }
    
}

extension SessionCell: IMContentViewDelegate {
    func onTapAction(event: IMEventModel) {
        delegate?.onTapCellAction(event: event)
    }
}
