using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
using System.IO;
using System.Linq;

// only for eqipptable items
public class SceneEquippableItemManager : MonoBehaviour
{
    private const string GameObjectLocalization = "Items/";
    
    private const string AssetLocalization = "Items/";

    private const string DYNAMIC_ELEMENT = "/DynamicElements/";
    private const string STATIC_ELEMENT = "/StaticElements/";

    // content skrzyni (docelowo skrzynia + jej content)

    /// <Summary>
    /// Handle manually setuped object properties
    /// eg. npc, minions, chest content
    /// </Summary>
    [SerializeField]
    public List<EquippableItemPrefabAsset> StaticElements;

    /// <Summary>
    /// Handle dynamic object properties
    /// eg. dropped items
    /// </Summary>
    // PrefarbAsset
    [SerializeField]
    public List<EquippableItemPrefabAsset> DynamicElements;

    public string MapName;
    public string ElementFolderName = "EquippableItem";
    public string ItemsListName = "EquippableItemList";

    public static SceneEquippableItemManager Instance;

    public void Awake()
    {
        if(Instance == null)
        {
            this.MapName = SceneManager.GetActiveScene().name;

            if(OnMapAppearanceMethod.IsNewGame())   // in new game dynamicItemsList is defaulty empty
            {
                BuildItems(StaticElements);
            
            }else
            {
                LoadEquippableItems();
                
                BuildItems(DynamicElements);
            }

            Instance = this;


        }else if (Instance != this)
        {
            Destroy(gameObject);
        }


    }

    public void Start()
    {
       // BuildDynamicItems();
        //SaveEquippableItems();

        //LoadEquippableItems();
        //BuildItems(StaticElements);
        //BuildItems(DynamicElements);

    }

    // public void AddDynamicItem(GameObject object) {
    //     //EquippableItem item = object.GetComponent<PickableController>().Item;
    //     //EquippableItemPrefabAsset equippableItemPrefarbAsset = new EquippableItemPrefabAsset(item.name, object.name, object.transform.position, item);
    //     //this.dynamicItems.Add(equippableItemPrefarbAsset);
    // }

    public int AddDynamicItem(GameObject dynamicObject)
    {
        EquippableItem item = new EquippableItem(dynamicObject.GetComponent<PickableController>().item);
        EquippableItemPrefabAsset equippableItemPrefarbAsset = new EquippableItemPrefabAsset(item.name, dynamicObject.name, dynamicObject.transform.position, item);
       
        this.DynamicElements.Add(equippableItemPrefarbAsset);

        return this.DynamicElements.Count - 1;
    }
    
    public void RemoveDynamicItem(string name)
    {
        // 1. Fetch all matched items
        List<EquippableItemPrefabAsset> equippableItemPrefarbAssetList = this.DynamicElements.Where(eqItemAss => eqItemAss.Name == name).ToList();

        // 2. Remove them
        this.DynamicElements.RemoveAll(eqItemAss => eqItemAss.Name == name);
    }

    public void RemoveDynamicEquippableItem(EquippableItemPrefabAsset equippableItemPrefarbAsset)    
    {
    }
    
    public void BuildItems(List<EquippableItemPrefabAsset> equippableItemPrefarbAssetList)
    {
        foreach(EquippableItemPrefabAsset equippableItemPrefarbAsset in equippableItemPrefarbAssetList)
        {
            

            GameObject newEquippableItemObject = Resources.Load<GameObject>(GameObjectLocalization + equippableItemPrefarbAsset.PrefabAssetName);

            if (!newEquippableItemObject)
            {
                Debug.Log("Can't find prefarb by name " + equippableItemPrefarbAsset.PrefabAssetName);
                break;
            }


            GameObject globalGUI =  GameObject.FindGameObjectsWithTag("GUI")[0];

            if(globalGUI)
            {
                // 1. Create gameObject by handled prefarb
                // 2. SetUp
                // 2.1 Set position
                GameObject equippableItem = Instantiate(newEquippableItemObject, equippableItemPrefarbAsset.Position, Quaternion.identity, globalGUI.transform);
            
                // 2.2 Set name
                equippableItem.name = equippableItemPrefarbAsset.Name;

                equippableItem.transform.SetParent(globalGUI.transform);
                // 2.3 Set pransform
                //equippableItem.transform.localScale = new Vector3(0.4f, 0.4f, 1);
                // Debug.Log(equippableItemPrefarbAsset.position);
                //equippableItem.transform.localPosition = equippableItemPrefarbAsset.position;

                // 3. SetUp object properties
                // 3.1 find object

                // 3.2 set EquippableItem object
                equippableItem.GetComponent<PickableController>().item = Resources.Load<EquippableItem>("Items/"+equippableItemPrefarbAsset.PrefabAssetName);



            } else {
                Debug.Log("Can't find global GUI object!!!");
                break;
            }
        }
    }

    /// Save both list of EquippableItems
    public void SaveEquippableItems()
    {
        // 1. staticElements
        this.SaveStaticEquippableItemsList();

        // 2. dynamicItems
        this.SaveDynamicEquippableItemsList();

        /// Load One element example
        // foreach(EquippableItemPrefabAsset equippableItemPrefarbAsset in equippableItemPrefarbAssetList)
        // {
        //     SaveEquippableItemSystem.SaveEquitableItem(equippableItemPrefarbAsset, this.MapName + "/" + this.ElementFolderName); // change to SaveEquippableItemSystem for EquippableItemPrefabAsset
        // }

    }

    #region Static list of EquippableItem Save 
    private void SaveStaticEquippableItemsList()
    {
        // Case I - if we remember all list
        //      1) if after removed item form DynamicList is empty - remove all file
        //      2) if after removed item form DynamciList there are another one - save updated list again
        if(this.StaticElements.Count > 0) {
            SaveEquippableItemSystem.SaveEquitableItemList(this.StaticElements, this.MapName + STATIC_ELEMENT, this.ItemsListName); // change to SaveEquippableItemSystem for EquippableItemPrefabAsset
        } else {
            string _path = SaveSystem.GetSavePath(this.MapName + STATIC_ELEMENT) + "/" + this.ItemsListName + ".fun";
            
            try    
            {    
                Debug.Log("File to remove: " + _path);

                if(File.Exists(_path))
                {
                    File.Delete(_path);
                }    
            }    
            catch (IOException ioExp)    
            {    
                Debug.LogError(ioExp.Message);    
            }
        }

        // Case II - if we rememenber object per file 
        //      1) remove specyfic file
        //
        // Unfortunatelly we don't use this way of saving items yet :D
    }
    #endregion

    #region Dynamic list of EquippableItem Save 
    private void SaveDynamicEquippableItemsList()
    {
        // Case I - if we remember all list
        //      1) if after removed item form DynamicList is empty - remove all file
        //      2) if after removed item form DynamciList there are another one - save updated list again
        if(this.DynamicElements.Count > 0) {
            SaveEquippableItemSystem.SaveEquitableItemList(this.DynamicElements, this.MapName + DYNAMIC_ELEMENT, this.ItemsListName); // change to SaveEquippableItemSystem for EquippableItemPrefabAsset
        } else {
            string _path = SaveSystem.GetSavePath(this.MapName + DYNAMIC_ELEMENT) + "/" + this.ItemsListName + ".fun";
            
            try    
            {    
                Debug.Log("File to remove: " + _path);

                if(File.Exists(_path))
                {
                    File.Delete(_path);
                }    
            }    
            catch (IOException ioExp)    
            {    
                Debug.LogError(ioExp.Message);    
            }
        }

        // Case II - if we rememenber object per file 
        //      1) remove specyfic file
        //
        // Unfortunatelly we don't use this way of saving items yet :D
    }
    #endregion

    public void LoadEquippableItems()
    {
        // if continue -> search files with content in save path

        // if new game -> build objects from default configuration

        this.LoadDynamicEquippableItemsList();

        /// <summary>
        /// DID WE REALLY NEED TO LOAD (or even remembered) THIS LIST????
        /// </summary>

        //this.LoadStaticEquippableItemsList();
    }


    #region Dynamic list of EquippableItem Loader
    public void LoadDynamicEquippableItem()
    {
        string path = SaveSystem.GetSavePath(this.MapName + DYNAMIC_ELEMENT + this.ElementFolderName);

        if (!Directory.Exists(path))    // if not exists thats mean there was nothing saved yet - nothing to load
            return;

        FileInfo[] fileInfo = new DirectoryInfo(path).GetFiles();

        foreach(FileInfo file in fileInfo)
        {
            Debug.Log(file.FullName);

            EquippableItemPrefabAssetData equippableItemPrefarbAssetData = SaveEquippableItemSystem.LoadEquitableItem(file.Name, this.MapName + DYNAMIC_ELEMENT + this.ElementFolderName);

            DynamicElements.Add((EquippableItemPrefabAsset)((EquippableItemPrefabAssetData)equippableItemPrefarbAssetData).MapDataToPrefabAssetModel());
        }
    }

    public void LoadDynamicEquippableItemsList()
    {
        string path = SaveSystem.GetSavePath(this.MapName + DYNAMIC_ELEMENT);

        if (!Directory.Exists(path))    // if not exists thats mean there was nothing saved yet - nothing to load
            return;

        FileInfo[] fileInfo = new DirectoryInfo(path).GetFiles();

        foreach(FileInfo file in fileInfo)
        {
            if(file.Name != this.ItemsListName + ".fun")
                continue;

            List<EquippableItemPrefabAssetData> equippableItemPrefarbAssetDataList = SaveEquippableItemSystem.LoadEquitableItemList(this.MapName + DYNAMIC_ELEMENT, this.ItemsListName);

            foreach(EquippableItemPrefabAssetData equippableItemPrefarbAssetData in equippableItemPrefarbAssetDataList)
                DynamicElements.Add((EquippableItemPrefabAsset)((EquippableItemPrefabAssetData)equippableItemPrefarbAssetData).MapDataToPrefabAssetModel());
        }
    }
    #endregion

    #region Static list of EquippableItem Loader
    public void LoadStaticEquippableItem()
    {
        string path = SaveSystem.GetSavePath(this.MapName + STATIC_ELEMENT + this.ElementFolderName);

        if (!Directory.Exists(path))    // if not exists thats mean there was nothing saved yet - nothing to load
            return;

        FileInfo[] fileInfo = new DirectoryInfo(path).GetFiles();

        foreach(FileInfo file in fileInfo)
        {
            Debug.Log(file.FullName);

            EquippableItemPrefabAssetData equippableItemPrefarbAssetData = SaveEquippableItemSystem.LoadEquitableItem(file.Name, this.MapName + STATIC_ELEMENT + this.ElementFolderName);

            StaticElements.Add((EquippableItemPrefabAsset)((EquippableItemPrefabAssetData)equippableItemPrefarbAssetData).MapDataToPrefabAssetModel());
        }
    }

    public void LoadStaticEquippableItemsList()
    {
        string path = SaveSystem.GetSavePath(this.MapName + STATIC_ELEMENT);

        if (!Directory.Exists(path))    // if not exists thats mean there was nothing saved yet - nothing to load
            return;

        FileInfo[] fileInfo = new DirectoryInfo(path).GetFiles();

        foreach(FileInfo file in fileInfo)
        {
            Debug.Log(file.FullName);

            List<EquippableItemPrefabAssetData> equippableItemPrefarbAssetDataList = SaveEquippableItemSystem.LoadEquitableItemList(this.MapName + STATIC_ELEMENT, this.ItemsListName);

            foreach(EquippableItemPrefabAssetData equippableItemPrefarbAssetData in equippableItemPrefarbAssetDataList)
                StaticElements.Add((EquippableItemPrefabAsset)((EquippableItemPrefabAssetData)equippableItemPrefarbAssetData).MapDataToPrefabAssetModel());
        }
    }
    #endregion
}