using System;
using System.Collections.Generic;
using Games.ChatHistory;
using Games.GlobeDefine;
using GCGame;
using GCGame.Table;
using Module.Log;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class ChatInputLogic : UIControllerBase<ChatInputLogic>
{
    public int _SelectedCannel;

    private ulong m_FriendChatReceiverGuid = GlobeVar.INVALID_GUID; // 好友聊天对象GUID

    private string m_FriendChatReceiverName = "";

    public ulong FriendChatReceiverGuid
    {
        get { return m_FriendChatReceiverGuid; }
        set { m_FriendChatReceiverGuid = value; }
    }

    public string FriendChatReceiverName
    {
        get { return m_FriendChatReceiverName; }
        set { m_FriendChatReceiverName = value; }
    }

    private void Start()
    {
        _InputText.onValueChanged.AddListener(OnInputChange);
    }

    private void OnEnable()
    {
        SetInstance(this);
    }

    private void OnDisable()
    {
        SetInstance(null);

        if (ChatEmojiLogic.Instance()) ChatEmojiLogic.Instance().CloseWindow();
    }

    public int GetCurChannelType()
    {
        return _SelectedCannel;
    }

    public void SetCurChannelType(int cannel)
    {
        _SelectedCannel = cannel;
    }

    #region chat input

    //public UIStateBtn _InputState;
    public InputField _InputText;
    //public UIButtonTime _BtnTime;

    [Serializable]
    public class BtnSendCallBack : UnityEvent<string>
    {
    }

    [SerializeField] public BtnSendCallBack _BtnSendCallBack;

//    private bool _IsSoundOn;
//    public void OnSoundState(int state)
//    {
//        _IsSoundOn = state != 0;
//    }
    public void OnBtnSend()
    {
        if (_BtnSendCallBack.GetPersistentEventCount() != 0)
        {
            var modifyText = ModifyItemText(_InputText.text);
            //modifyText = Utils.StrFilter_Chat(modifyText);
            _BtnSendCallBack.Invoke(modifyText);
            if (!Utils.IsStrFilter_Chat(modifyText)) _InputText.text = string.Empty;
            Debug.LogWarning("On Submit To Persist!");
        }
        else
        {
            if (string.IsNullOrEmpty(_InputText.text) && _ChatLinks.Count == 0)
                return;
            // 发布成功就清空对话
            if (OnSubmit())
                _InputText.text = string.Empty;
        }

        _ChatLinks.Clear();
    }

    private string _LastInput = "";

    public void OnInputChange(string newInput)
    {
        if (newInput.Length == 0) _ChatLinks.Clear();
    }

    public bool OnSubmit()
    {
        var text = _InputText.text;
        // 判定是否Gm指令
        if (SdkControl.instance.useGm &&
            text.StartsWith(GameDefines.GMCMD_BEGINORDER, StringComparison.OrdinalIgnoreCase))
        {
            var subString = text.Substring(2);
            if (subString.StartsWith("gm"))
                UIManager.ShowUI(UIInfo.GMWnd);
            else if (subString.StartsWith("ma"))
                Singleton<ObjManager>.GetInstance().MainPlayer.GetOffWeddingCar();
            else
                Utils.SendGMCommand(text.Substring(2, text.Length - 2));
            return true;
        }

        if (!IsCanChat())
            return false;
        var textCopy = text;
        if (GetCurChannelType() == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_TELL ||
            GetCurChannelType() == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_FRIEND)
            textCopy = textCopy.Replace("/" + FriendChatReceiverName + " ", "");
        if (!string.IsNullOrEmpty(textCopy))
        {
            var item = new ChatHistoryItem();
            item.CleanUp();
            item.EChannel = (GC_CHAT.CHATTYPE) GetCurChannelType();
            item.ReceiverGuid = FriendChatReceiverGuid;
            item.ReceiverName = FriendChatReceiverName;

            if (_UsingHistory == null)
            {
                var modifyText = ModifyItemText(text);
                modifyText = Utils.StrFilter_Chat(modifyText);
                item.ChatInfo = modifyText;
                if (m_FriendChatReceiverGuid != GlobeVar.INVALID_GUID)
                    if (GameManager.gameManager.PlayerDataPool.ChatHistory.IsNeedInsertTime(FriendChatReceiverGuid))
                        item.SetSendMsgTime();
                Utils.SendCGChatPak(item.ChatInfo, item);

                AddInputHistory(text, modifyText);
            }
            else
            {
                var modifyText = ModifyHistoryInput(text);
                modifyText = Utils.StrFilter_Chat(modifyText);
                item.ChatInfo = modifyText;
                if (m_FriendChatReceiverGuid != GlobeVar.INVALID_GUID)
                    if (GameManager.gameManager.PlayerDataPool.ChatHistory.IsNeedInsertTime(FriendChatReceiverGuid))
                        item.SetSendMsgTime();
                Utils.SendCGChatPak(item.ChatInfo, item);
            }
        }
        return true;
    }

    public static int WORLD_CHAT_LEVEL = -1;
    public static int FRIEND_CHAT_LEVEL = -1;
    public static int WORLD_CHAT_CD = -1;
    public static int WORLD_NORMAL_CD = -1;
    private static int _LastWorldChatTime;
    private static int _LastNormalChatTime;

    public bool IsCanChat(bool setChatTime = true)
    {
        return IsCanChat(GetCurChannelType(), setChatTime);
    }

    public static bool IsCanChat(int chatType, bool setChatTime = true, bool checkLevel = true)
    {
        if (chatType == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_WORLD)
        {
            if (WORLD_CHAT_LEVEL < 0) WORLD_CHAT_LEVEL = SystemParam.GetSystemParam_INT(14);
            if (WORLD_CHAT_CD < 0) WORLD_CHAT_CD = SystemParam.GetSystemParam_INT(28);
            if (checkLevel)
                if (GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Level < WORLD_CHAT_LEVEL)
                {
                    GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4902}"));
                    return false;
                }

            if (_LastWorldChatTime > 0)
            {
                var cdTime = WORLD_CHAT_CD - ((int) Time.time - _LastWorldChatTime);
                LogModule.DebugLog("cdTime:" + cdTime);
                if (cdTime > 0)
                {
                    GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4907}", cdTime));
                    return false;
                }
            }

            if (setChatTime) _LastWorldChatTime = (int) Time.time;
        }
        else if (chatType == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_NORMAL)
        {
            if (WORLD_NORMAL_CD < 0) WORLD_NORMAL_CD = SystemParam.GetSystemParam_INT(29);
            if (_LastNormalChatTime > 0)
            {
                var cdTime = WORLD_NORMAL_CD - ((int) Time.time - _LastNormalChatTime);
                if (cdTime > 0)
                {
                    GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4903}", cdTime));
                    return false;
                }
            }

            if (setChatTime) _LastNormalChatTime = (int) Time.time;
        }
        else if (chatType == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_GUILD)
        {
            if (!GameManager.gameManager.PlayerDataPool.IsHaveGuild())
            {
                GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4909}"));
                return false;
            }
        }
        else if (chatType == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_TEAM)
        {
            if (!GameManager.gameManager.PlayerDataPool.IsHaveTeam())
            {
                GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4910}"));
                return false;
            }
        }
        else if (chatType == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_FRIEND ||
                 chatType == (int) CG_CHAT.CHATTYPE.CHAT_TYPE_TELL)
        {
            if (FRIEND_CHAT_LEVEL < 0) FRIEND_CHAT_LEVEL = SystemParam.GetSystemParam_INT(16);

            if (GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Level < FRIEND_CHAT_LEVEL)
            {
                GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4935}"));
                return false;
            }
        }

        return true;
    }

    #endregion

    #region chat insert

//    private const int MAX_TEXTNUM = 128;

    public float _RectLeft;
    public bool _ShowHideBtn = true;

    private readonly List<ChatLinkBase> _ChatLinks = new List<ChatLinkBase>();

    public void OnShowEmojiPanel()
    {
        if (ChatEmojiLogic.Instance())
            ChatEmojiLogic.Instance().CloseWindow();
        else
            ChatEmojiLogic.ShowChatEmoji(_InputText, _ChatLinks, OnShowPos, OnHideEmojiPanel, _RectLeft, _ShowHideBtn);
    }

    public void OnHideEmojiPanel()
    {
//        Invoke("HideEmojiInner", 0.0f);
        //HideEmojiInner();
    }

//    private void HideEmojiInner()
//    {
//    }

    private string ModifyItemText(string inputText)
    {
        var newInputText = inputText;
        var replaceIdx = 0;
        for (var i = 0; i < _ChatLinks.Count; ++i)
        {
            if (replaceIdx < 0 || replaceIdx >= newInputText.Length) continue;
            replaceIdx = newInputText.IndexOf(_ChatLinks[i].StrInput, replaceIdx);
            if (replaceIdx < 0 || replaceIdx >= newInputText.Length) continue;
            newInputText = newInputText.Remove(replaceIdx, _ChatLinks[i].StrInput.Length);
            newInputText = newInputText.Insert(replaceIdx, _ChatLinks[i].StrSend);
            //newInputText = newInputText.Replace(_ChatLinks[i].StrInput, _ChatLinks[i].StrSend);
        }
        //newInputText += inputText.Substring(newInputEnd, inputText.Length - newInputEnd);

        return newInputText;
    }

    public void OnShowPos(string posStr)
    {
        if (!IsCanChat(GetCurChannelType()))
            return;

        var item = new ChatHistoryItem();
        item.CleanUp();
        item.EChannel = (GC_CHAT.CHATTYPE) GetCurChannelType();
        item.ReceiverGuid = FriendChatReceiverGuid;
        item.ReceiverName = FriendChatReceiverName;

        Utils.SendCGChatPak(posStr, item);

        OnHideEmojiPanel();
        UIManager.CloseUI(UIInfo.ChatEmojiRoot);
    }

    #endregion

    #region input history

    public class InputHistoryInfo
    {
        public string _StrSend;
        public string _StrShow;
    }

    public GameObject _InputHistoryGO;
    public UIContainerBase _InputHistoryContainer;

    private readonly List<InputHistoryInfo> _InputHistoryList = new List<InputHistoryInfo>();
    private InputHistoryInfo _UsingHistory;
    private const int _MAX_INPUT_HISTORY_COUNT = 5;

    public void OnBtnInputHistoryClick()
    {
        _InputHistoryGO.SetActive(true);
        InitInputHistory();
    }

    public void HideInputHistory()
    {
        _InputHistoryGO.SetActive(false);
    }

    private void InitInputHistory()
    {
        _InputHistoryContainer.InitContentItem(_InputHistoryList, OnHistoryItemClick);
    }

    private void OnHistoryItemClick(object historyObj)
    {
        _UsingHistory = historyObj as InputHistoryInfo;
        _InputHistoryGO.SetActive(false);
        _InputText.text = _UsingHistory._StrShow;
    }

    private void AddInputHistory(string before, string after)
    {
        var historyInfo = new InputHistoryInfo {_StrShow = before, _StrSend = after};

        _InputHistoryList.Add(historyInfo);
        if (_InputHistoryList.Count > _MAX_INPUT_HISTORY_COUNT) _InputHistoryList.RemoveAt(0);
    }

    private string ModifyHistoryInput(string inputStr)
    {
        var modifiedStr = inputStr;
        if (_UsingHistory != null) modifiedStr = inputStr.Replace(_UsingHistory._StrShow, _UsingHistory._StrSend);

        _UsingHistory = null;
        return modifiedStr;
    }

    #endregion
}