using System;
using System.Collections.Generic;
using UnityEngine;

namespace BingoBrain.Core
{
    public sealed class ModuleBoardk : BaseInterfaceManager<ModuleBoardk>
    {
        private Dictionary<string, BaseModel> modelDict = new();
        private Dictionary<string, Type> uiTypeDict = new();
        private Dictionary<string, BaseCtrl> ctrlDict = new();
        private Dictionary<string, BaseUICtrl> uiCtrlDict = new();

        public override void Init()
        {
            base.Init();
            InitAllModule();
        }

        private void InitAllModule()
        {
            List<string> ctrlDisableList = BingoConst.CtrlDisableList;

            foreach (BaseModel model in modelDict.Values)
            {
                model.New();
            }

            foreach (BaseCtrl ctrl in ctrlDict.Values)
            {
                if (!ctrl.isEnable)
                {
                    continue;
                }

                if (ctrlDisableList.Contains(ctrl.ctrlName))
                {
                    ctrl.isEnable = false;
                    continue;
                }

                ctrl.isEnable = true;
                ctrl.New();
            }

            foreach (BaseUICtrl uiCtrl in uiCtrlDict.Values)
            {
                if (!uiCtrl.isEnable)
                {
                    continue;
                }

                if (ctrlDisableList.Contains(uiCtrl.ctrlName))
                {
                    uiCtrl.isEnable = false;
                    continue;
                }

                uiCtrl.isEnable = true;
                uiCtrl.New();
            }


            foreach (BaseModel model in modelDict.Values)
            {
                model.Init();
            }

            foreach (BaseCtrl ctrl in ctrlDict.Values)
            {
                ctrl.Init();
            }

            foreach (BaseUICtrl uiCtrl in uiCtrlDict.Values)
            {
                uiCtrl.Init();
            }

            Debug.Log("[ BingoBrain ] [ ModuleManager ] InitModule");
        }

        public void StartUpAllModule()
        {
            foreach (BaseModel model in modelDict.Values)
            {
                model.StartUp();
            }

            foreach (BaseCtrl ctrl in ctrlDict.Values)
            {
                ctrl.StartUp();
            }

            foreach (BaseUICtrl uiCtrl in uiCtrlDict.Values)
            {
                uiCtrl.StartUp();
            }

            Debug.Log("[ BingoBrain ] [ ModuleManager ] StartUpAllModule");
        }

        public void AllModuleReadData()
        {
            foreach (BaseModel model in modelDict.Values)
            {
                model.ReadData();
            }

            foreach (BaseCtrl ctrl in ctrlDict.Values)
            {
                ctrl.ReadData();
            }

            foreach (BaseUICtrl uiCtrl in uiCtrlDict.Values)
            {
                uiCtrl.ReadData();
            }

            Debug.Log("[ BingoBrain ] [ ModuleManager ] AllModuleReadData");
        }

        public void AllModuleGameStart()
        {
            foreach (BaseModel model in modelDict.Values)
            {
                model.GameStart();
            }

            foreach (BaseCtrl ctrl in ctrlDict.Values)
            {
                ctrl.GameStart();
            }

            foreach (BaseUICtrl uiCtrl in uiCtrlDict.Values)
            {
                uiCtrl.GameStart();
            }

        }

        public BaseModel GetModel(string modelName)
        {
            BaseModel model = null;
            if (!modelDict.TryGetValue(modelName, out model))
            {
                Debug.LogError("[ BingoBrain ] [ ModuleManager ] No Have This Model " + modelName);
            }

            return model;
        }

        public Type GetUIType(string uiName)
        {
            Type uitype = null;
            if (!uiTypeDict.TryGetValue(uiName, out uitype))
            {
                Debug.LogError("[ BingoBrain ] [ ModuleManager ]  No Have this UI " + uiName);
            }

            return uitype;
        }

        public BaseCtrl GetCtrl(string ctrlName)
        {
            BaseCtrl ctrl = null;
            if (!ctrlDict.TryGetValue(ctrlName, out ctrl))
            {
                Debug.LogError("[ BingoBrain ] [ ModuleManager ] No Have This Ctrl " + ctrlName);
            }

            return ctrl;
        }

        public BaseUICtrl GetUICtrl(string uiCtrlName)
        {
            BaseUICtrl uiCtrl = null;
            if (!uiCtrlDict.TryGetValue(uiCtrlName, out uiCtrl))
            {
                Debug.LogError("[ BingoBrain ] [ ModuleManager ] No Have This UICtrl " + uiCtrlName);
            }

            return uiCtrl;
        }

        public void SetActiveCtrl(string ctrlName, bool isEnable)
        {
            BaseCtrl ctrl = GetCtrl(ctrlName);
            if (isEnable)
            {
                if (!ctrl.isEnable && !ctrl.IsNew)
                {
                    ctrl.isEnable = true;
                    ctrl.New();
                    ctrl.Init();
                    ctrl.StartUp();
                }
            }
            else
            {
                if (ctrl.isEnable && ctrl.IsNew)
                {
                    ctrl.isEnable = false;
                    ctrl.Dispose();
                }
            }
        }

        public void SetActiveUICtrl(string uiCtrlName, bool isEnable)
        {
            BaseUICtrl uiCtrl = GetUICtrl(uiCtrlName);
            if (isEnable)
            {
                if (!uiCtrl.isEnable && !uiCtrl.IsNew)
                {
                    uiCtrl.isEnable = true;
                    uiCtrl.New();
                    uiCtrl.Init();
                    uiCtrl.StartUp();
                }
            }
            else
            {
                if (uiCtrl.isEnable && uiCtrl.IsNew)
                {
                    uiCtrl.isEnable = false;
                    uiCtrl.Dispose();
                }
            }
        }

        public void ResetModel(string modelName)
        {
            BaseModel model = GetModel(modelName);
            model.Reset();
        }

        public void AddModel(string modelName, BaseModel model)
        {
            model.modelName = modelName;
            modelDict[modelName] = model;
        }

        public void AddUIType(string uiName, Type uiType)
        {
            uiTypeDict[uiName] = uiType;
        }

        public void AddCtrl(string ctrlName, BaseCtrl ctrl)
        {
            ctrl.ctrlName = ctrlName;
            ctrlDict[ctrlName] = ctrl;
        }

        public void AddUICtrl(string ctrlName, BaseUICtrl uiCtrl)
        {
            uiCtrl.ctrlName = ctrlName;
            uiCtrlDict[ctrlName] = uiCtrl;
        }

        public void ResetAllModel()
        {
            foreach (BaseModel model in modelDict.Values)
            {
                model.Reset();
            }
        }

        public void DisposeAllModel()
        {
            foreach (BaseModel model in modelDict.Values)
            {
                model.Dispose();
            }

            modelDict.Clear();
        }

        public void DisposeAllCtrl()
        {
            foreach (BaseCtrl ctrl in ctrlDict.Values)
            {
                ctrl.Dispose();
            }

            foreach (BaseUICtrl uiCtrl in uiCtrlDict.Values)
            {
                uiCtrl.Dispose();
            }

            ctrlDict.Clear();
            uiCtrlDict.Clear();
        }

        public void DisposeAllModule()
        {
            DisposeAllModel();
            DisposeAllCtrl();
        }

        public override void Dispose()
        {
            base.Dispose();

            modelDict = null;
            uiTypeDict = null;
            ctrlDict = null;
            uiCtrlDict = null;
        }
    }
}