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

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Build;


#if UNITY_2018_1_OR_NEWER
using UnityEditor.Build.Reporting;
class BuildVersionDisplayProcessor : IPreprocessBuildWithReport {
    public int callbackOrder { get { return 0; } }
    public void OnPreprocessBuild(BuildReport report) {
        Debug.Log("MyCustomBuildProcessor.OnPreprocessBuild for target " + report.summary.platform + " at path " + report.summary.outputPath);

        BuildVersionDisplay.UpdateDateTimeFile();
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
    }
}
#elif UNITY_2017
class BuildVersionDisplayProcessor : IPreprocessBuild {
    public int callbackOrder { get { return 0; } }
    public void OnPreprocessBuild(BuildTarget target, string path) {
        Debug.Log("MyCustomBuildProcessor.OnPreprocessBuild");

        BuildVersionDisplay.UpdateDateTimeFile();
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
    }
}
#endif

[CustomEditor(typeof(BuildVersionDisplay))]
public class BuildVersionInspector : Editor {
    public override void OnInspectorGUI() {
        BuildVersionDisplay myTarget = (BuildVersionDisplay)target;
        if (GUILayout.Button("Update DateTime File")) {
            // myTarget.UpdateDateTimeFile();
            BuildVersionDisplay.UpdateDateTimeFile();
        }
        DrawDefaultInspector();
    }
}
#endif

public class BuildVersionDisplay : MonoBehaviour {
    public TMPro.TextMeshPro tmProTextMesh;
    public UnityEngine.UI.Text uiText;
    public TextAsset buildVersionTextFile;
    static System.DateTime buildDateTime;

    public float UiTextUpdateRate = 1f;
    public float ConsoleTextUpdateRate = 10f;

    // Start is called before the first frame update
    void Awake() {
        Setup();

        InvokeRepeating("UpdateUiText", 0.0f, UiTextUpdateRate);
        InvokeRepeating("UpdateConsoleText", 0.0f, ConsoleTextUpdateRate);
    }

    public void Setup () {
        buildVersionTextFile = Resources.Load<TextAsset>("BuildDateTime");
        tmProTextMesh = GetComponent<TMPro.TextMeshPro>();
        uiText = GetComponent<UnityEngine.UI.Text>();

        SetDummyUiText();

        buildVersionTextFile = Resources.Load<TextAsset>("BuildDateTime");
        buildDateTime = System.DateTime.Parse(buildVersionTextFile.text);
    }

    public static void UpdateDateTimeFile () {
#if UNITY_EDITOR
        if (!AssetDatabase.IsValidFolder("Assets/Resources")) {
            AssetDatabase.CreateFolder("Assets", "Resources");
        }
#endif
        using (StreamWriter Writer = new StreamWriter(File.Create("Assets/Resources/BuildDateTime.txt"))) {
            Writer.Write(DateTime.UtcNow.ToString("o"));
        }
#if UNITY_EDITOR
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
#endif

        foreach (BuildVersionDisplay bvd in GameObject.FindObjectsOfType<BuildVersionDisplay>()) {
            bvd.Setup();
        }
    }

    void UpdateUiText () {
        if (tmProTextMesh != null) {
            tmProTextMesh.text = GetCurrentLabel();
        }
        if (uiText != null) {
            uiText.text = GetCurrentLabel();
        }
   }

    void UpdateConsoleText () {
        Debug.Log(GetCurrentLabel().Replace('\n', ' '));
    }


    void SetDummyUiText () {
        if (tmProTextMesh != null) {
            tmProTextMesh.text = GetDummyLabel();
        }
        if (uiText != null) {
            uiText.text = GetDummyLabel();
        }
    }

    string GetCurrentLabel () {
        System.TimeSpan timeSinceBuild = System.DateTime.Now.Subtract( buildDateTime );
        return GenerateText(timeSinceBuild, buildDateTime);
    }

    string GetDummyLabel () {
        System.TimeSpan timeSinceBuild = new System.TimeSpan(0,0,0,0);
        buildDateTime = new System.DateTime(1,1,1,1,0,0);
        return GenerateText(timeSinceBuild, buildDateTime);
    }

    string GenerateText (System.TimeSpan timeSpan, System.DateTime dateTime) {
        string datetimeString = dateTime.ToString("u");
        string timespanString = timeSpan.ToString("dd\\d\\ hh\\h\\:mm\\m\\:ss\\s");
        return ($"BuildDateTime: {datetimeString} TimeSinceBuild: {timespanString}");
    }
}