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

public class GlobalVariables : MonoBehaviour
{
    public double gameTime = 0.0;
    public int saveGameId = 0;
    public int[] variables = new int[2048];
    public bool[] switches = new bool[2048];
    public static GlobalVariables main;
    public string place = "";
    public string mission = "";
    public ObjectiveType objectiveType = ObjectiveType.none;
    public Vector3 objectivePosition = Vector3.zero;
    public string objectiveScene;
    public float objectiveRadius = 0.0f;
    public int credits = 0;
    public List<Entity> party;
    public Dictionary<string, Entity.Parameters> savedEntities = new Dictionary<string, Entity.Parameters>();
    public Vector2 cameraRotation = Vector2.zero;

    //Not SaveGame related
    public AudioClip genericSwordSound;
    public string nextLevel = "";
    public string localizzation = "English";
    public bool canSave = true;
    public string saveDeactivationScene;
    public Dictionary<string,string> translationMap;
    private List<string> notTranslatedKeys;

    public enum ObjectiveType {
        none = 0,
        position = 1,
        area = 2,
    }

    private void Awake() {
        main = this;
        //DEBUG
        /*WeaponContainer[] wc = Resources.LoadAll<WeaponContainer>("Weapons");
        int r = Random.Range(4, 21);
        for (int i = 0; i < r; i++) {
            freeWeapons.Add(new Weapon(wc[Random.Range(0, wc.Length)]));
        }*/
    }

    // Start is called before the first frame update
    void Start() {
    }

    // Update is called once per frame
    void Update() {
        gameTime += Time.deltaTime;
        //InputSystem.Update();
    }

    void OnDestroy() {
        main = null;
    }

    public void New() {
        gameTime = 0.0;
        saveGameId = 0;
        variables = new int[2048];
        switches = new bool[2048];
        nextLevel = "";
        place = "";
        mission = "";
        ResetObjective();
        credits = 0;
        savedEntities.Clear();
        party.Clear();
    }

    public void ResetObjective() {
        objectiveType = ObjectiveType.none;
        objectivePosition = Vector3.zero;
        objectiveRadius = 0.0f;
        objectiveScene = SceneManager.GetActiveScene().name;
    }

    /*public void Load(string fileName) {
        SaveLoadManager.CallLoad(fileName);
    }

    public void Save(string fileName, bool keepPositions, bool automatic) {
        SaveLoadManager.CallSave(fileName, keepPositions, automatic);
    }*/

    public string ReturnTraduction(string input) {
        if (translationMap == null) {
            ReadTranslations();
        }
        string output = input;
        string clearInput = ClearTranslationKey(input);
        if (translationMap.ContainsKey(clearInput)) {
            output = translationMap[clearInput];
        }
        else if (!localizzation.Equals("English") || input.Contains("&")) {
#if UNITY_EDITOR
            Debug.Log(localizzation+" translation not found for string \"" + input + "\"");
#endif
            if (notTranslatedKeys == null) {
                notTranslatedKeys = new List<string>();
                string notTranslatedFile = NotTranslatedFile();
                if (System.IO.File.Exists(notTranslatedFile)) {
                    StreamReader sr = new StreamReader(notTranslatedFile);
                    string ntf = sr.ReadToEnd();
                    Dictionary<string, string> ntkd = ReadTranslationJson(ntf);
                    foreach (KeyValuePair<string, string> values in ntkd) {
                        notTranslatedKeys.Add(values.Key);
                    }
                }
            }
            if (!notTranslatedKeys.Contains(input) && !string.IsNullOrWhiteSpace(input)) {
                notTranslatedKeys.Add(input);
                WriteNotTranslatedKeys();
            }
        }
        return output;
    }

    public string NotTranslatedFile() {
        return Application.dataPath + "/Locale/Dictionary/" + localizzation + "_untranslated.json";
    }

    public string ClearTranslationKey(string input) {
        string output = input;
        if (input != null && input.Length > 0) {
            output = output.Replace(" ", string.Empty);
            output = output.Replace(",", string.Empty);
            output = output.Replace(".", string.Empty);
            output = output.Replace("\n", string.Empty);
            output = output.ToLower();
        }
        return output;
    }

    public void SetLocalization(string loc) {
        localizzation = loc;
        ReadTranslations();
    }

    public void ReadTranslations() {
        if (translationMap == null) {
            translationMap = new Dictionary<string, string>();
        }
        else {
            translationMap.Clear();
        }
        TextAsset ta = Resources.Load<TextAsset>("Text/Dictionary/" + localizzation);
        if (ta != null) {
            Dictionary<string, string> rt = ReadTranslationJson(ta.text);
            foreach (KeyValuePair<string, string> values in rt) {
                translationMap[ClearTranslationKey(values.Key)] = values.Value;
            }
        }
    }

    public Dictionary<string, string> ReadTranslationJson(string input) {
        Dictionary<string, string> res = new Dictionary<string, string>();
        string[] l1 = input.Split('\n');
        for (int i=0; i<l1.Length; i++){
            if (l1[i].Contains(":")) {
                string[] l2 = l1[i].Split('"');
                if (l2.Length > 3 && !string.IsNullOrWhiteSpace(l2[1])) {
                    string key = l2[1];
                    string translatedText = l2[3];
                    translatedText = translatedText.Replace("<br>", "\n");
                    res.Add(key, translatedText);
                    //Debug.Log(l2[1] + " -> " + l2[3]);
                }
            }
        }
        return res;
    }

    public void WriteNotTranslatedKeys() {
        try {
            string output = NotTranslatedFile();
            string directory = Application.dataPath + "/Locale/Dictionary";
            if (!Directory.Exists(directory)) {
                Directory.CreateDirectory(directory);
            }
            if (!System.IO.File.Exists(output)) {
                System.IO.File.Delete(output);
            }
            StreamWriter sw = new StreamWriter(output, false);
            sw.WriteLine("{");
            for (int i = 0; i < notTranslatedKeys.Count; i++) {
                if (localizzation.Equals("English")) {  // Nel caso si volesse gestire anche questo
                    sw.WriteLine(" \"" + notTranslatedKeys[i] + "\":\"" + notTranslatedKeys[i] + "\",");
                }
                else {
                    sw.WriteLine(" \"" + notTranslatedKeys[i] + "\":\"\",");
                }
            }
            sw.WriteLine("}");
            sw.Close();
        }
        catch {

        }
    }

    static public string Translate(string input) {
        string output = input;
        if (main != null && !string.IsNullOrEmpty(input)) {
            output = main.ReturnTraduction(input);
        }
        return output;
    }

    public void UpdateParty() {
        Entity[] entities = FindObjectsOfType<Entity>();
        if (party == null) {
            party = new List<Entity>();
        }
        else {
            party.Clear();
        }
        for (int i = 0; i < entities.Length; i++) {
            if (entities[i].team == "A") {
                party.Add(entities[i]);
            }
        }
    }
    
    public Entity NextCompanion(bool next, Entity selected) {
        Entity res = null;
        if (party == null || party.Count == 0) {
            UpdateParty();
        }
        List<Entity> p2 = new List<Entity>();
        for (int i = 0; i < party.Count; i++) {
            if (party[i].parameters.canUseHDev) {
                p2.Add(party[i]);
            }
        }
        if (p2.Count > 1) {
            int index = 0;
            for (int i = 0; i < p2.Count; i++) {
                if (selected == p2[i]) {
                    index = i;
                    break;
                }
            }
            if (next) {
                index++;
            }
            else {
                index--;
            }
            if (index < 0) {
                index = p2.Count - 1;
            }
            else if (index >= p2.Count) {
                index = 0;
            }
            res = p2[index];
        }
        return res;
    }
}
