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

namespace mgaia.Utils
{
    /// <summary>
    /// Gerenciador de localização
    /// </summary>
    /// <owner>Victor</owner>
    public static class LocalizationManager
    {
        private static BaseLocalizationParser sFallbackLocalizationParser;
        private static BaseLocalizationParser sCurrentLocalizationParser;
        private static bool mHasCurrentLanguageTranslated;
        private static bool mUsesFallback;

#if UNITY_EDITOR
        /// <summary>
        /// Idioma para forçar, em caso de testes
        /// </summary>
        public static SystemLanguage? LanguageToForce
        {
            get;
            set;
        }
#endif

        public static SystemLanguage CurrentLanguage
        {
            get
            {
#if UNITY_EDITOR
                return LanguageToForce ?? Application.systemLanguage;
#else
                return Application.systemLanguage;
#endif
            }
        }

        /// <summary>
        /// Carrega o arquivo de localização em um idioma de fallback padrão e no idioma atual caso exista
        /// </summary>
        public static void Load<TLocalizationParser>(SystemLanguage fallbackLanguage = SystemLanguage.English) where TLocalizationParser : BaseLocalizationParser, new()
        {
            mUsesFallback = true;

            sFallbackLocalizationParser = new TLocalizationParser();
            sCurrentLocalizationParser = new TLocalizationParser();

            if (!sFallbackLocalizationParser.Load(fallbackLanguage))
            {
                throw new InvalidOperationException("A língua " + fallbackLanguage.ToString() + " é um fallback e precisa ter uma versão traduzida!");
            }

            SystemLanguage currentSystemLanguage = Application.systemLanguage;

#if UNITY_EDITOR
            currentSystemLanguage = LanguageToForce ?? currentSystemLanguage;
#endif

            mHasCurrentLanguageTranslated = sCurrentLocalizationParser.Load(currentSystemLanguage);
        }

        public static void LoadWithoutFallback<TLocalizationParser>() where TLocalizationParser : BaseLocalizationParser, new()
        {
            mUsesFallback = false;

            sCurrentLocalizationParser = new TLocalizationParser();

			SystemLanguage currentSystemLanguage = Application.systemLanguage;
			
			#if UNITY_EDITOR
			currentSystemLanguage = LanguageToForce ?? currentSystemLanguage;
			#endif

			bool success = sCurrentLocalizationParser.Load(currentSystemLanguage);
            Assert.AssertTrue(success, "Ocorreu algum problema ao carregar o language parser!");
        }

        /// <summary>
        /// Retorna um texto localizado na sessão e chave passados, caso ele não exista no idioma atual, é procurado no fallback
        /// </summary>
        public static string GetText(string session, string key)
        {
            LocalizedSessionHandle sessionHandle = GetSession(session);

            return sessionHandle.GetText(key);
        }

		/// <summary>
		/// Retorna um conjunto de strings concatenadas por line break
		/// </summary>
		public static string GetConcatenatedTexts(string session, params string[] keys)
		{
			string[] localizedValues = new string[keys.Length];

			for(int idx = 0; idx < keys.Length; idx++)
			{
				string localizedValue = GetText(session, keys[idx]);

				localizedValues[idx] = localizedValue;
			}

			return StringExtensions.ConcatenateWithLineBreaks(localizedValues);
		}

        /// <summary>
        /// Retorna um apontador para pegar todas as chaves pertencentes a sessão passada
        /// </summary>
        public static LocalizedSessionHandle GetSession(string session)
        {
            if (mUsesFallback)
            {
                return new LocalizedSessionHandle(session, sFallbackLocalizationParser, mHasCurrentLanguageTranslated ? sCurrentLocalizationParser : null);
            }
            else
            {
                return new LocalizedSessionHandle(session, sCurrentLocalizationParser);
            }
        }
    }
}