using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

[Serializable]
// Can not be created from Editor
public class Progress
{
    [Serializable]
    // Helper class to serialize into byte[]
    protected class DataEntry
    {
        public string key;
        public List<byte> bytes = new List<byte>();

        public DataEntry(string key, byte[] data)
        {
            this.key = key;
            this.bytes = new List<byte>(data);
        }
    }

    [Header("Course or Minigame")]
    [SerializeField]
    // values belonging to a certain key, in List (which can be serialized)
    private List<DataEntry> entries = new List<DataEntry>();


    // Add new `key` := `value`, returns `true` if successful
    public bool AddOrUpdate<T>(string key, T data)
    {
        if (data == null)
            return false;

        DataEntry entry = entries.Find(x => x.key == key);

        // Hacky serialization stuff
        BinaryFormatter bf = new BinaryFormatter();
        using (MemoryStream ms = new MemoryStream())
        {
            bf.Serialize(ms, data);
            if (entry != null)
            {
                entry.bytes.Clear();
                entry.bytes.AddRange(ms.ToArray());
            }
            else
            {
                entries.Add(new DataEntry(key, ms.ToArray()));
            }
            return true;
        }
    }

    // Get the value of type `T` belonging to `key`
    public T Get<T>(string key)
    {
        BinaryFormatter bf = new BinaryFormatter();
        using (MemoryStream ms = new MemoryStream())
        {
            // Find the correct key
            foreach (DataEntry entry in entries)
            {
                if (entry.key == key)
                {
                    // Hacky serialization stuff
                    byte[] data = entry.bytes.ToArray();
                    ms.Write(data, 0, data.Length);
                    ms.Seek(0, SeekOrigin.Begin);
                    return (T)bf.Deserialize(ms);
                }
            }
        }
        // Raise an exception when key is not found
        throw new KeyNotFoundException();
    }
}
