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

public class DataDownloader {

    private static readonly string WebServiceUrl = "https://script.google.com/macros/s/AKfycbyenMGJNEy3M_P37lWZavGe0gwLMI91qiew12XE6kmnsLdcwAI/exec";
    private static readonly string SpreadsheetId = "1z3jzHxHo9FPthm2K_cuL3lCZDfwTnbEjI0tG1D4YPPc";
    private static readonly string LangSpreadsheetId = "1Eq7VNB2MqzdotBwaf71dqZ1MIU_HrEjPxIfNBeFlTr8";
    private static readonly string Password = "hogehogehogeo";
    private static readonly string DirectoryPath = "Assets/MyGame/Resources/Data";
    
    // Googleに短時間アクセスで怒られるので仕方なくSleep
    private static readonly int SleepTime = 1000;

    [MenuItem("Tools/SpreadsheetTool/DataUpdate")]
    static void DataUpdate(){
        List<Tuple<string, string>> downloadedDataList = new List<Tuple<string, string>>();

        int count = Const.BaseSheetNameList.Length;
        bool isError = false;
        foreach(Const.SheetData baseNameData in Const.BaseSheetNameList){
            string fileName = baseNameData.name;
            string connectionString = CreateConnectionString(fileName);
            DataDownload(connectionString, fileName, (str, data) => {
                downloadedDataList.Add(Tuple.Create<string, string>(fileName, data));
                    if(--count <= 0){
                        if(!isError){
                            Debug.Log("DataDownload is Done!!");
                            int result = SaveDownloadedDataList(downloadedDataList, DirectoryPath);
                            if(result > 0){
                                File.WriteAllText(string.Format("{0}/DownloadDate.txt", DirectoryPath), AvoEx.AesEncryptor.Encrypt(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
                            }
                            AssetDatabase.Refresh();
                        } else{
                            Debug.LogError("エラーデータがダウンロードされたので、再度DataUpdateを行なって下さい。");
                        }
                    }
            });
            System.Threading.Thread.Sleep(SleepTime);
        }
    }

    [MenuItem("Tools/SpreadsheetTool/LanguageDataUpdate")]
    static void LanguageDataUpdate(){
        List<Tuple<string, string>> downloadedDataList = new List<Tuple<string, string>>();

        int count = Const.LanguageSheetNameList.Length;
        bool isError = false;

        foreach(Const.SheetData LanguageData in Const.LanguageSheetNameList){
            string fileName = LanguageData.name;
            string connectionString = CreateConnectionString(LangSpreadsheetId,fileName);
            DataDownload(connectionString, fileName, (str, data) => {
                downloadedDataList.Add(Tuple.Create<string, string>(fileName, data));
                    if(--count <= 0){
                        if(!isError){
                            Debug.Log("DataDownload is Done!!");
                            int result = SaveDownloadedDataList(downloadedDataList, DirectoryPath);
                            if(result > 0){
                                File.WriteAllText(string.Format("{0}/DownloadDate.txt", DirectoryPath), AvoEx.AesEncryptor.Encrypt(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
                            }
                            AssetDatabase.Refresh();
                        } else{
                            Debug.LogError("エラーデータがダウンロードされたので、再度DataUpdateを行なって下さい。");
                        }
                    }
            });
            System.Threading.Thread.Sleep(SleepTime);
        }
    }

    private static string CreateConnectionString(string sheetName){
        return CreateConnectionString(SpreadsheetId, sheetName);
    }

    private static string CreateConnectionString(string spreadsheetId, string sheetName){
        return WebServiceUrl + "?ssid=" + spreadsheetId + "&sheet=" + sheetName + "&pass=" + Password + "&action=GetData";
    }

    private static void DataDownload(string connectionString, string fileName, Action<string, string> callback){
        Debug.LogFormat ("BeginDataDownload {0}", fileName);
        WWW www = new WWW(connectionString);

        ContinuationManager.Add(() => www.isDone, () => {
            if(!string.IsNullOrEmpty(www.error)){
                Debug.Log("WWW failed: " + www.error);
            }
            Debug.LogFormat("EndDataDownload {0}", fileName);
            string result = www.text;
            // Keyが空白なセル情報を破棄
            while(result.Contains(",\"\":")){
                int begin = result.IndexOf(",\"\":");
                int end = result.IndexOf("}", begin);
                result = result.Remove(begin, end - begin);
            }
            while(result.Contains(",{\"\":")){
                int begin = result.IndexOf(",{\"\":");
                int end = result.IndexOf("}", begin) + 1;
                result = result.Remove(begin, end - begin);
            }
            Debug.Log(result);
            callback(result, AvoEx.AesEncryptor.Encrypt(result));
        });
    }

    private static int SaveDownloadedDataList(List<Tuple<string, string>> downloadedDataList, string directoryPath){
        if(!Directory.Exists(directoryPath)){
            Directory.CreateDirectory(directoryPath);
        }
        int updateCount = 0;
        Debug.Log("BeginDataUpdate");
        foreach(var data in downloadedDataList){
            string path = string.Format(directoryPath + "/{0}.txt", data.Item1);
            string newData = AvoEx.AesEncryptor.DecryptString(data.Item2);
            string oldData = "";
            try {
                oldData = AvoEx.AesEncryptor.DecryptString(File.ReadAllText(path));
            } catch(Exception){
            }
            if(newData != oldData){
                ++updateCount;
                Debug.Log("Update " + data.Item1);
                File.WriteAllText(path, data.Item2);
            }
        }
        Debug.Log("EndDataUpdate updateCount:" + updateCount);
        return updateCount;
    }
}
