using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;

namespace DialogueSystem
{
    public class GenericScriptableObjectArchive : MonoBehaviour
    {
        private static ArchiveData archiveData = new ArchiveData();
        private static string SavePath => Path.Combine(Application.persistentDataPath, "archive.json");
        
        private static GenericScriptableObjectArchive instance;

        private bool reset = false;

        private void Start()
        {
            if (instance == null)
            {
                instance = this;
                DontDestroyOnLoad(gameObject);
                LoadArchive();
                Debug.Log("Archive Manager created and persisted");
            }
            else
            {
                Debug.Log("Duplicate Archive Manager destroyed");
                Destroy(gameObject);
                return;
            }
        }

  
        private void OnApplicationQuit()
        {
            if(!reset)
                SaveArchive();
            reset = false;
        }

        public void SetReset()
        {
            reset = true;
        }
        
        // Add any ScriptableObject to archive
        public static void AddToArchive(ScriptableObject item, string category)
        {
            ArchivedEntry entry = new ArchivedEntry
            {
                assetName = item.name,
                category = category
            };
            
            // Check if already exists
            if (!archiveData.entries.Exists(e => e.assetName == item.name && e.category == category))
            {
                archiveData.entries.Add(entry);
                SaveArchive();
            }
        }

        // Overload to also accept positions for certain items
        public static void AddToArchive(ScriptableObject item, string category, Vector3 position)
        {
            ArchivedEntry entry = new ArchivedEntry
            {
                assetName = item.name,
                category = category,
                position = new Vector3(position.x, position.y, 0)
            };

            if (!archiveData.entries.Exists(e => e.assetName == item.name && e.category == category))
            {
                archiveData.entries.Add(entry);
                SaveArchive();
            }
            
        }
        
        private static void SaveArchive()
        {
            string json = JsonUtility.ToJson(archiveData, true);
            File.WriteAllText(SavePath, json);
        }
        
        private static void LoadArchive()
        {
            if (File.Exists(SavePath))
            {
                string json = File.ReadAllText(SavePath);
                archiveData = JsonUtility.FromJson<ArchiveData>(json);
            }
        }
        
        // Load all archived items of a specific type
        public static List<T> GetArchivedItems<T>(string category, string resourcePath) where T : ScriptableObject
        {
            List<T> items = new List<T>();
            T[] allAssets = Resources.LoadAll<T>(resourcePath);
            
            foreach (var entry in archiveData.entries)
            {
                if (entry.category == category)
                {
                    T asset = System.Array.Find(allAssets, a => a.name == entry.assetName);
                    if (asset != null)
                        items.Add(asset);
                }
            }
            
            return items;
        }
        
        public static List<ArchivedEntry> GetEntriesByCategory(string category)
        {
            return archiveData.entries.FindAll(e => e.category == category);
        }
    }
    
    [System.Serializable]
    public class ArchiveData
    {
        public List<ArchivedEntry> entries = new List<ArchivedEntry>();
    }
    
    [System.Serializable]
    public class ArchivedEntry
    {
        public string assetName;
        public string category;
        public Vector3 position;
    }
}
