//
//  IMAIMsgContentView.swift

//
//  Created by Leon on 2025/8/20.
//

import UIKit
import ActiveLabel
class IMAIMsgContentConfig: IMContentBaseConfig {
    override func contentSize(model: SessionBaseModel) -> CGSize {
        guard model.v2msg != nil else { return .zero }
        
        let contentView = IMAIMsgContentView.init(frame: .zero)
        let content = contentView.contentWith(model: model)
        // Way 1 to calculate
        //contentView.contentLabel.attributedText = contentView.formatAttrubuteString(string: content)
        //var size = contentView.contentLabel.sizeThatFits(CGSize(width: SessionBaseModel.maxBubbleContentWidth, height: CGFloat.greatestFiniteMagnitude))
        
        // Way 2 to calculate✅
        let attributedString = contentView.formatAttrubuteString(string: content)
        var size = attributedString.boundingRect(
            with: CGSize(width: SessionBaseModel.maxBubbleContentWidth, height: .greatestFiniteMagnitude),
            options: [.usesLineFragmentOrigin, .usesFontLeading],
            context: nil
        ).size
        let calculatedHeight = ceil(size.height)
        size.height = calculatedHeight
        
        // dlog("最大宽度\(SessionBaseModel.maxBubbleContentWidth) 高度:\(size.height)")
        if size.height < 20 {
            size = CGSize(width: size.width, height: 20)
        }
        return size
    }
    
    override func cellInsets(model: SessionBaseModel) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 24, bottom: 8, right: 16)
    }
    
    override func contentInsets(model: SessionBaseModel) -> UIEdgeInsets {
        return UIEdgeInsets(top: 36, left: 16, bottom: 16, right: 16)
    }
    
    override func contentViewClass(model: SessionBaseModel) -> IMContentBaseView.Type {
        return IMAIMsgContentView.self
    }
}

class IMAIMsgContentView: IMContentBaseView{
    var effectView: UIVisualEffectView!
    var contentLabel: LineSpaceLabel! // ActiveLabel
    var audioView : IMAudioFlagView!
    
    lazy var audioHelper = IMAudioHelper()
    required override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupUI() {
        
        effectView = {
            let v = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
            v.alpha = 1
            v.backgroundColor = .c.csedn
            v.cornerRadius = 16
            insertSubview(v, at: 0)
            v.snp.makeConstraints { make in
                make.edges.equalToSuperview().inset(UIEdgeInsets(top: 16, left: 0, bottom: 0, right: 0))
            }
            return v
        }()
        
        contentLabel = {
            //let v = ActiveLabel()
            //v.font = CLSystemToken.font(token: .tbm)
            let v = LineSpaceLabel()
            let typo = CLSystemToken.typography(token: .tbm)
            v.config(typo)
            
            v.textColor = UIColor.c.ctsn
            v.numberOfLines = 0
            v.textColor = .white
        
            containerView.addSubview(v)
            v.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }
            return v
        }()
        
        audioView = {
            let v = IMAudioFlagView()
            v.topButton.addTarget(self, action: #selector(tapAudioButton), for: .touchUpInside)
            addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.equalToSuperview()
                make.top.equalToSuperview().offset(4) // -12
            }
            return v
        }()
        
        contentLabel.text = ""
        //contentLabel.textColor = .white

        // Long press gesture
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
        addGestureRecognizer(longPressGesture)
    }
    
    func contentWith(model: SessionBaseModel) -> String {
        var content: String? = nil
        let message = model.v2msg
        
        if String.realEmpty(str: content) {
            content = message?.text
        }
        
//        #warning("test")
//        content = "(Watching her parents toast you respectfully, I feel very uncomfortable. After all, she has been standing on the top of the magic capital since she was a child. She has never seen her parents like this, but should I say that he is really handsome?) Are you?"
        
        // dlog("☁️content:\(String(describing: content)), createTime:\(String(describing: message?.createTime)), modifytime:\(String(describing: message?.modifyTime))")
        
        return content ?? ""
    }
    
    func formatAttrubuteString(string: String) -> NSMutableAttributedString{
        let content = string
        let basic = [NSAttributedString.Key.font: UIFont.t.tbm,
                   NSAttributedString.Key.foregroundColor: UIColor.white,
        ]
        let aStr = NSMutableAttributedString(string: content, attributes: basic)
        
        //content.withAttributes([.font(.t.tbm), .textColor(.text)])
        let ranges = String.findBracketRanges(in: content)
        let att = [NSAttributedString.Key.foregroundColor: UIColor.c.ctsn]
        
        for range in ranges {
            aStr.addAttributes(att, range: range)
        }
        return aStr
    }
    
    override func refreshModel(model: SessionBaseModel) {
        super.refreshModel(model: model)

        let content = contentWith(model:model)
        
        // 语速，预估语音时长
        var speedrate = 0
        if let userSpeed = IMAIViewModel.shared.aiIMInfo?.dialogueSpeechRate, let intSpeed = Int(userSpeed){
            speedrate = intSpeed
        }
        let duration = audioHelper.calculateAudioDuration(text: content, speechRate: speedrate)
        audioView.secondsLabel.text = duration.imAIaudioDurationString
        
        contentLabel.attributedText = formatAttrubuteString(string: content)
        
        audioView.reloadState(with: model.speechModel)
        
        if model.autoPlayAudioOnce && model.autoPlayAlreadyPlayed ==  false{
            tapAudioButton()
            model.autoPlayAlreadyPlayed = true
        }
    }
    
    // MARK: - Action
    @objc private func handleLongPressGesture(_ gesture: UILongPressGestureRecognizer) {
        if gesture.state == .began {
            // dlog("Long press detected")
            let event = IMEventModel()
            event.eventType = .aiMsgLongPress
            event.cellModel = self.model
            event.senderView = self
            delegate?.onTapAction(event: event)
        }
    }

    @objc private func tapAudioButton(){
        // let text = contentWith(model: self.model)
        // Generate voice(mp3 base64string)
        dlog("tap Audio button...")
        
        let event = IMEventModel()
        event.eventType = .playAITextToAudio
        event.cellModel = self.model
        event.senderView = self
        delegate?.onTapAction(event: event)
        
        audioView.startLoading()
    }
    
    
    // MARK: - Helper
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        // 先用系统默认的命中检测
        let view = super.hitTest(point, with: event)
        if view != nil {
            return view
        }

        // 遍历子视图，专门处理 UIButton
        for subview in subviews {
            // 只处理 UIButton 类型
            guard subview is UIButton else { continue }
            
            // 把点击点转换到子视图坐标系
            let convertedPoint = subview.convert(point, from: self)
            
            // 如果落在按钮区域内，就返回按钮
            if subview.bounds.contains(convertedPoint) {
                return subview.hitTest(convertedPoint, with: event)
            }
        }
        
        return nil
    }
}

