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

[Serializable]
public abstract class UIBaseManager<T> : MonoBehaviour, ManagerInterface<T>
{
    public static UIBaseManager<T> Instance { get; protected set; }


    [SerializeField] public GameObject DynamicPanel;

    [SerializeField] public KeyCode keyToOpen;

    /// <summary>
    /// Managed objects list - most important element in module
    /// </summary>
    [SerializeField] protected List<T> Elements = new List<T>(); // { get; set; } - this block inspector 

    public void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Debug.Log(gameObject);
            Debug.Log(Instance);
            Destroy(gameObject);
        }
    }

    public void Update()
    {
        if (Input.GetKeyDown(keyToOpen))
        {
            if (!DynamicPanel)
            {
                this.OpenPanel();
            }
            else
            {
                this.ClosePanel();
            }
        }
    }

    /// <summary>
    /// Function to fetch currently opened panel asociated with this UI manager
    /// </summary>
    /// <param name="panelConrtoller"></param>
    public void SetPanelController(GameObject panelConrtoller)
    {
        // ToDo change fetched types
        //DynamicPanel = dynamicPanelController;
    }
    
    public virtual bool OpenPanel()
    {
        Console.WriteLine("Panel opened");

        GameObject globalGUI = GameObject.FindGameObjectWithTag("GUI");
        
        if(!globalGUI)
            throw new Exception("Panel could not be opened - can't find global GUI object!!");

        GameObject uiPanelTemplate = GetTemplatePanel();
        
        DynamicPanel = GameObject.Instantiate(uiPanelTemplate, uiPanelTemplate.transform.position, Quaternion.identity, globalGUI.transform);   // 4'th arg allow set object as child

        DynamicPanel.transform.localPosition = uiPanelTemplate.transform.position;   // prevent overwritten position by... environment???

        SetupPanel();

        return true;
    }

    public virtual bool ClosePanel()
    {
        Console.WriteLine("Panel closed");

        try
        {
            Destroy(DynamicPanel);

            return true;
        } catch (Exception ex) { Debug.LogError(ex.Message); }

        return true;
    }

    public virtual void SetupPanel()
    {
        if(!DynamicPanel)
            throw new Exception("Panel not found - UIBaseManager don't have UI Panel instance!!");

        // bind this class instance
        //DynamicPanel.GetComponent<TaskPanelController>().Bind(this);
    }
    
    /// <summary>
    /// Function which return panel status
    /// True - if panel is opened and it's instance is handled
    /// false - if panel is closed and it's instance is not handled
    /// </summary>
    /// <returns></returns>
    public bool GetPanelStatus()
    {
        return DynamicPanel != null;
    }

    public List<T> GetList()
    {
        return Elements;
    }

    /// <summary>
    /// Function to setting list of elements - invoked once at the beginning
    /// Reset current content
    /// </summary>
    /// <param name="list"></param>
    /// <exception cref="NotImplementedException"></exception>
    public void SetList(List<T> list)
    {
        Elements = list;

        if(DynamicPanel != null)  // is null = is close - when we firstly init list content before open panel in SceneTaskDataManager file
            UpdateList();
    }

    /// <summary>
    /// Set of functions to synchronize local list with list from SystemManager
    /// </summary>
    public void Add(T model)
    {
        // throw new System.NotImplementedException();

        Elements.Add(model);

        UpdateList();

        // add to local list
        // and rebuild view - sync lists (this.UpdateList() ;) )
    }

    public abstract void UpdateList();

    public void Remove()
    {
        UpdateList();

        throw new System.NotImplementedException();
        
        // remove from local list
        // and rebuild view - sync lists (this.UpdateList() ;) )
    }

    /// <summary>
    /// Function to find saved template of created panel instance
    /// </summary>
    /// <returns></returns>
    protected abstract GameObject GetTemplatePanel();
}