//
//  YHMessageInputViewController.swift
//  galaxy
//
//  Created by alexzzw on 2024/11/26.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//

import UIKit
import IQKeyboardManagerSwift

class YHMessageInputViewController: UIViewController {
    private let maxCount = 40
    private var overMaxCountTips: String {
        return "评论字数限制\(maxCount)字以下"
    }
    private let nullInputTips = "请输入内容"
    private var keyboardHeight = 0.0
    private let textContainerToTop = 8.0
    private var lastMessage: String = ""
    private let textViewMinHeight: CGFloat = 18
    private let textViewMaxHeight: CGFloat = 54

    var inputCallback: ((YHMessageInputViewController, String) -> Void)?
    var closeCallback: (() -> Void)?
    
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }
    private lazy var inputMainView: UIView = {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: KScreenWidth, height: 54))
        view.backgroundColor = .white
        return view
    }()

    private lazy var textContainer: YHBaseDynamicCornerRadiusView = {
        let view = YHBaseDynamicCornerRadiusView(cornerRadius: 2, corner: .allCorners)
        view.backgroundColor = .contentBkgColor
        return view
    }()

    private lazy var textView: UITextView = {
        let view = UITextView()
        view.backgroundColor = .clear
        view.textColor = .mainTextColor
        view.tintColor = .brandMainColor
        view.font = .PFSC_R(ofSize: 13)
        view.returnKeyType = .send
        view.enablesReturnKeyAutomatically = true
        view.delegate = self
        view.textContainerInset = .zero
        view.textContainer.lineFragmentPadding = 0
        return view
    }()

    private lazy var editTipsLabel: UILabel = {
        let label = UILabel()
        label.isHidden = true
        label.text = "说点什么..."
        label.font = .PFSC_R(ofSize: 13)
        label.textColor = UIColor(hexString: "#8993A2")
        return label
    }()

    private lazy var sendButton: UIButton = {
        let button = UIButton(type: .custom)
        button.setTitle("发送", for: .normal)
        button.titleLabel?.font = .PFSC_M(ofSize: 12)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .brandMainColor
        button.layer.cornerRadius = 3
        button.clipsToBounds = true
        button.addTarget(self, action: #selector(sendButtonTapped), for: .touchUpInside)
        return button
    }()

    init() {
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
        modalTransitionStyle = .crossDissolve
    }

    @MainActor required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        addObserver()
        // 关闭点击事件
        let ges = UITapGestureRecognizer(target: self, action: #selector(closeKeyboard(_:)))
        view.addGestureRecognizer(ges)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        IQKeyboardManager.shared.isEnabled = false
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        IQKeyboardManager.shared.isEnabled = true
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // 显示上次编辑记录
        showLastRecord()
        guard textView.canBecomeFirstResponder else {
            return
        }
        textView.becomeFirstResponder()
    }

    func updateText(_ text: String) {
        textView.text = text
        textViewDidChange(textView)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

extension YHMessageInputViewController {
    // MARK: - Actions

    @objc func keyboardWillShow(_ sender: Notification) {
        guard let userInfo = sender.userInfo else {
            return
        }
        guard let keyboardRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
            return
        }
        // 获取动画执行的时间
        var duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double ?? 0.25
        if duration == 0 {
            duration = 0.25
        }

        // 获取键盘弹起的高度
        let keyboardHeight = keyboardRect.height
        self.keyboardHeight = keyboardHeight
        self.inputMainView.snp.remakeConstraints { make in
            make.bottom.equalToSuperview().offset(-keyboardHeight)
            make.left.right.equalToSuperview()
        }
        UIView.animateKeyframes(withDuration: duration, delay: 0, options: UIView.KeyframeAnimationOptions(rawValue: 0)) {
            self.view.layoutIfNeeded()
        }
    }

    @objc func keyboardWillHide(_ sender: Notification) {
        guard let userInfo = sender.userInfo else {
            return
        }
        // 获取动画执行的时间
        let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double ?? 0.25
        let height = self.inputMainView.bounds.height
        self.inputMainView.snp.remakeConstraints { make in
            make.left.right.equalToSuperview()
            make.bottom.equalToSuperview().offset(height)
        }
        UIView.animateKeyframes(withDuration: duration, delay: 0, options: UIView.KeyframeAnimationOptions(rawValue: 0)) {
            self.view.layoutIfNeeded()
        }
    }

    @objc private func sendButtonTapped() {
        // 禁用按钮
        sendButton.isEnabled = false
        let text = textView.text ?? ""
        let currentText = text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        guard currentText.count > 0 else {
            YHHUD.flash(message: nullInputTips)
            sendButton.isEnabled = true
            return
        }
        inputCallback?(self, currentText)
        // 延迟启用按钮
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            self.sendButton.isEnabled = true
        }
    }

    @objc func closeKeyboard(_ sender: UIGestureRecognizer?) {
        DispatchQueue.main.async {
            // 保存这次编辑的内容
            self.lastMessage = self.textView.text
            self.textView.snp.updateConstraints { make in
                make.height.equalTo(self.textViewMinHeight)
            }
            self.textView.endEditing(true)
            self.dismiss(animated: false) { [weak self] in
                self?.closeCallback?()
            }
        }
    }

    // 显示上次编辑记录
    private func showLastRecord() {
        guard lastMessage.count > 0 else {
            return
        }
        textView.text = lastMessage
        textViewDidChange(textView)
    }

    private func setupUI() {
        view.backgroundColor = .black.withAlphaComponent(0.1)
        view.addSubview(inputMainView)
        inputMainView.addSubview(textContainer)
        textContainer.addSubview(textView)
        textContainer.addSubview(editTipsLabel)
        inputMainView.addSubview(sendButton)

        inputMainView.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.bottom.equalToSuperview().offset(54)
        }
        textContainer.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(16)
            make.top.equalToSuperview().offset(textContainerToTop)
            make.bottom.equalToSuperview().offset(-textContainerToTop)
        }
        sendButton.snp.makeConstraints { make in
            make.left.equalTo(textContainer.snp.right).offset(16)
            make.right.equalToSuperview().offset(-16)
            make.centerY.equalTo(textContainer)
            make.height.equalTo(32)
            make.width.equalTo(56)
        }
        textView.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(12)
            make.right.equalToSuperview().offset(-12)
            make.top.equalToSuperview().offset(10)
            make.bottom.equalToSuperview().offset(-10)
            make.height.equalTo(textViewMinHeight)
        }
        editTipsLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
        }
    }

    /// 事件监听
    private func addObserver() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
}

extension YHMessageInputViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        editTipsLabel.isHidden = textView.text.count > 0
        var text = textView.text.replacingOccurrences(of: " ", with: "")
        text = text.replacingOccurrences(of: "\n", with: "")
        // 储存原textView的大小
        let oldSize = textView.frame.size
        // 预设textView的大小，宽度设为固定宽度，高度设为CGFloat的最大值
        let presetSize = CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude)
        // 重新计算textView的实际大小
        let newSize = textView.sizeThatFits(presetSize)
        // 当高度变化时，刷新tableview（beginUpdates和endUpdates必须成对使用）
        if newSize.height != oldSize.height {
            var height = newSize.height >= textViewMaxHeight ? textViewMaxHeight : newSize.height
            height = height < textViewMinHeight ? textViewMinHeight : height
            self.textView.snp.updateConstraints { make in
                make.height.equalTo(height)
            }
        }
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        guard textView == self.textView else {
            return true
        }
        /// 输入删除
        if text == "" {
            return true
        }
        if text == "\n" { // 检测回车键
            sendButtonTapped()
            return false // 不插入换行符
        }
        let count = (textView.text?.utf16.count ?? 0) - range.length + text.utf16.count
        if count > maxCount {
            YHHUD.flash(message: overMaxCountTips)
            return false
        }
        return true
    }
}
