using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using AvoEx;

public sealed class SpreadsheetDataManager : SingletonMonoBehaviour<SpreadsheetDataManager> {

    private Dictionary<string, List<object>> dataDictionary = new Dictionary<string, List<object>>();

    private string downloadDate;
    public string DownloadDateString {
        get{ return downloadDate; }
    }

    void Awake(){
        if(CheckInstance()) return ;
        downloadDate = LoadData("DownloadDate");
    }

    public bool LoadAndCache<T>(string worksheetName){
        string typeName = typeof(T).ToString();
        string json = LoadData(worksheetName);
        dataDictionary[worksheetName] = JsonHelper.GetJsonArray(json, typeName).ToList();
        return dataDictionary.ContainsKey(worksheetName);
    }
    public bool ExistsDataList(string worksheetName){
        return dataDictionary.ContainsKey(worksheetName);
    }
    public List<T> GetBaseDataList<T>(string worksheetName){
        if(!ExistsDataList(worksheetName)) LoadAndCache<T>(worksheetName);
        // HACK
        return dataDictionary[worksheetName].Cast<T>().ToList();
    }
#if UNITY_EDITOR
    public static List<T> Load<T>(string worksheetName){
        string typeName = typeof(T).ToString();
        string json = LoadData(worksheetName);
        return JsonHelper.GetJsonArray(json, typeName).Cast<T>().ToList();
    }
    private static string LoadData(string assetName){
#else
    private string LoadData(string assetName){
#endif
        string path = "Data/" + assetName;
        TextAsset textAsset = Resources.Load<TextAsset>(path);
        return AesEncryptor.DecryptString(textAsset.text);
    }
}

public static class JsonHelper{
    public static object[] GetJsonArray(string json, string typeName){
        return GetJsonArray(json, Type.GetType(typeName));
    }
    public static object[] GetJsonArray(string json, Type type){
        // JsonHelper型
        Type jh = typeof(JsonHelper);
        // GetJsonArray Method
        MethodInfo mi = jh.GetMethod("JsonToArray");
        // GetJsonArray<Type> Method
        MethodInfo miConstructed = mi.MakeGenericMethod(type);

        string[] args = { json };
        object result = miConstructed.Invoke(null, args);

        return ((IEnumerable)result).Cast<object>().ToArray();
    }
    public static T[] JsonToArray<T>(string json){
        string newJson = "{ \"array\": " + json + "}";
        return JsonUtility.FromJson<Wrapper<T>>(newJson).array;
    }

    [Serializable]
    private class Wrapper<T>{
        public T[] array = null;
    }
}
