// Copyright © Selmo Technology GmbH. All Rights Reserved

using SelmoStudio.Hmi.Server.Languages.Models;
using SelmoStudio.Hmi.Server.SelmoHmi.Shared.WellKnownTypes;
using SelmoStudio.Hmi.Server.Service;
using System.Globalization;

namespace SelmoStudio.Hmi.Server.Languages.Service
{
    public class HmiLanguageService : IHmiLanguageService
    {
        private IReadOnlyList<HmiLanguage> _languages;
        private HmiLanguage _defaultLanguage;
        private HmiLanguage _currentLanguage;

        public void Init(IReadOnlyList<HmiLanguage> languages, HmiLanguage defaultLanguage)
        {
            _languages = languages;

            ThrowIfNull(defaultLanguage);
            ThrowIfNotSupported(defaultLanguage);

            _defaultLanguage = defaultLanguage;
        }

        public Action OnLanguageSet { get; set; }

        public HmiLanguage CurrentLanguage
        {
            get
            {
                if (_currentLanguage == null)
                {
                    Set(_defaultLanguage);
                }

                return _currentLanguage;
            }
        }

        public IReadOnlyList<HmiLanguage> SupportedLanguages => _languages;

        public void SetStartup()
        {
            Set(_defaultLanguage);
        }

        public HmiLanguage? Get(string cultureCode)
        {
            return _languages.FirstOrDefault(l => l.Lcid.Equals(cultureCode)
                    && l.Lcid.Equals(cultureCode));
        }

        public void Set(HmiLanguage hmiLanguage)
        {
            ThrowIfNull(hmiLanguage);
            ThrowIfNotSupported(hmiLanguage);

            if (_currentLanguage != null && hmiLanguage.Lcid.Equals(_currentLanguage.Lcid))
            {
                return;
            }

            _currentLanguage = hmiLanguage ?? _defaultLanguage;

            CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(int.Parse(_currentLanguage.Lcid));
            CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(int.Parse(_currentLanguage.Lcid));

            OnLanguageSet?.Invoke();
        }

        private void ThrowIfNull(HmiLanguage hmiLanguage)
        {
            ArgumentNullException.ThrowIfNull(hmiLanguage, nameof(hmiLanguage));
        }

        private void ThrowIfNotSupported(HmiLanguage language)
        {
            if (!language.Equals(WellKnownLanguages.FallbackLanguage) && !_languages.Contains(language))
            {
                throw new NotSupportedException($"The language {language.Name} is not supported!");
            }
        }
    }
}