using System;
using System.IO;
using Электронная_Фармация.Properties;

namespace Электронная_Фармация.Classes
{
    /// <summary>
    /// Shared application paths and API settings.
    /// </summary>
    public static class AppConfig
    {
        public const string DefaultApiBaseUrl = "https://24pharmdata.ru";
        public const string DefaultUpdateCheckBaseUrl = "https://git.24pharmdata.ru";
        public const string DefaultUpdateRepo = "pharmdata/elfisa-pharmacy";
        /// <summary>Публичная раздача установщика (корень CDN отдаёт Setup.exe).</summary>
        public const string DefaultInstallerCdnUrl = "https://cdn.24pharmdata.ru";
        public const string DefaultInstallerDownloadUrl = "https://cdn.24pharmdata.ru/ElfisaPharmacy-Setup.exe";
        private const string LegacyApiBaseUrl = "http://195.34.241.84:9988";
        private const string ApiBaseUrlEnvVar = "ELF_API_BASE_URL";
        /// <summary>ИИ-сервис отчётов (проксируется Caddy на Мак-мини). Можно переопределить
        /// переменной ELF_AI_BASE_URL, напр. http://192.168.95.116:8808 для теста по локальной сети.</summary>
        public const string DefaultAiBaseUrl = "https://24pharmdata.ru/ai";
        private const string AiBaseUrlEnvVar = "ELF_AI_BASE_URL";
        private static bool _sqliteInteropPrepared;
        private static readonly object _sqliteInteropLock = new object();

        public static string InstallerDownloadUrl
        {
            get
            {
                var fromEnv = Environment.GetEnvironmentVariable("ELF_INSTALLER_URL");
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return fromEnv.Trim();
                }

                return DefaultInstallerDownloadUrl;
            }
        }

        public static string InstallerCdnUrl
        {
            get
            {
                var fromEnv = Environment.GetEnvironmentVariable("ELF_CDN_URL");
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return fromEnv.Trim().TrimEnd('/');
                }

                return DefaultInstallerCdnUrl;
            }
        }

        /// <summary>
        /// Replaces known dead API URLs in saved user settings.
        /// </summary>
        /// <summary>
        /// Carries user settings across AssemblyVersion bumps (new user.config folder).
        /// </summary>
        public static void UpgradeUserSettingsIfNeeded()
        {
            try
            {
                if (Settings.Default.UpgradeSettings)
                {
                    Settings.Default.Upgrade();
                    Settings.Default.UpgradeSettings = false;
                    Settings.Default.Save();
                    AppDebugLog.Info("AppConfig", "User settings upgraded from previous version");
                }
            }
            catch (Exception ex)
            {
                AppDebugLog.Info("AppConfig", $"Upgrade settings skipped: {ex.Message}");
            }
        }

        public static void MigrateLegacySettings()
        {
            var current = Settings.Default.ApiBaseUrl;
            if (string.IsNullOrWhiteSpace(current))
            {
                return;
            }

            var normalized = NormalizeApiBaseUrl(current);
            if (string.Equals(normalized, LegacyApiBaseUrl, StringComparison.OrdinalIgnoreCase) ||
                string.Equals(normalized, "http://195.34.241.84:9988", StringComparison.OrdinalIgnoreCase))
            {
                Settings.Default.ApiBaseUrl = DefaultApiBaseUrl;
                Settings.Default.stringToken = string.Empty;
                Settings.Default.Save();
                AppDebugLog.Info("AppConfig", $"ApiBaseUrl мигрирован: {LegacyApiBaseUrl} -> {DefaultApiBaseUrl}");
            }
        }

        public static string ApiBaseUrl
        {
            get
            {
                var fromSettings = Settings.Default.ApiBaseUrl;
                if (!string.IsNullOrWhiteSpace(fromSettings))
                {
                    return NormalizeApiBaseUrl(fromSettings);
                }

                var fromEnv = Environment.GetEnvironmentVariable(ApiBaseUrlEnvVar);
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return NormalizeApiBaseUrl(fromEnv);
                }

                return DefaultApiBaseUrl;
            }
        }

        /// <summary>Базовый URL ИИ-сервиса отчётов.</summary>
        public static string AiBaseUrl
        {
            get
            {
                var fromEnv = Environment.GetEnvironmentVariable(AiBaseUrlEnvVar);
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return fromEnv.Trim().TrimEnd('/');
                }

                return DefaultAiBaseUrl;
            }
        }

        public static string NormalizeApiBaseUrl(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                return DefaultApiBaseUrl;
            }

            url = url.Trim().TrimEnd('/');
            if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
                !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
            {
                url = "http://" + url;
            }

            return url;
        }

        /// <summary>
        /// Writable per-user data (DB, logs). Program Files is read-only for normal users.
        /// </summary>
        public static string UserDataDirectory
        {
            get
            {
                var dir = Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                    "ЭльФиСА",
                    "Электронная Фармация");

                try
                {
                    Directory.CreateDirectory(dir);
                }
                catch
                {
                    // Caller will surface a clearer error when opening the DB.
                }

                return dir;
            }
        }

        public static string LogsDirectory => Path.Combine(UserDataDirectory, "Logs");

        public static string SqliteDbPath
        {
            get
            {
                MigrateLegacySqliteDatabaseIfNeeded();
                return Path.Combine(UserDataDirectory, "efClient.db");
            }
        }

        /// <summary>
        /// One-time copy from install folder (old portable layout) into LocalAppData.
        /// </summary>
        private static void MigrateLegacySqliteDatabaseIfNeeded()
        {
            try
            {
                var target = Path.Combine(UserDataDirectory, "efClient.db");
                if (File.Exists(target))
                {
                    return;
                }

                var baseDir = AppDomain.CurrentDomain.BaseDirectory;
                var candidates = new[]
                {
                    Path.Combine(baseDir, "efClient.db"),
                    Path.Combine(baseDir, "Data", "efClient.db")
                };

                foreach (var source in candidates)
                {
                    if (!File.Exists(source))
                    {
                        continue;
                    }

                    File.Copy(source, target, overwrite: false);
                    AppDebugLog.Info("AppConfig", $"SQLite DB migrated: {source} -> {target}");
                    return;
                }
            }
            catch (Exception ex)
            {
                AppDebugLog.Info("AppConfig", $"SQLite DB migrate skipped: {ex.Message}");
            }
        }

        public static string SqliteConnectionString
        {
            get
            {
                EnsureSQLiteInteropInBaseDir();
                return $"Data Source={SqliteDbPath};Version=3;New=False;";
            }
        }

        public static string LocationId
        {
            get { return Settings.Default.LocationId ?? string.Empty; }
        }

        public static void SetLocationId(string locationId)
        {
            Settings.Default.LocationId = (locationId ?? string.Empty).Trim();
            Settings.Default.Save();
        }

        public static string InvoiceExportPath
        {
            get { return Settings.Default.InvoiceExportPath ?? string.Empty; }
        }

        public static void SetInvoiceExportPath(string path)
        {
            Settings.Default.InvoiceExportPath = (path ?? string.Empty).Trim();
            Settings.Default.Save();
        }

        /// <summary>
        /// Gitea base URL for forced update checks (no trailing slash).
        /// </summary>
        public static string UpdateCheckBaseUrl
        {
            get
            {
                var fromEnv = Environment.GetEnvironmentVariable("ELF_UPDATE_CHECK_BASE_URL");
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return NormalizeApiBaseUrl(fromEnv);
                }

                var fromSettings = Settings.Default.UpdateCheckBaseUrl;
                if (!string.IsNullOrWhiteSpace(fromSettings))
                {
                    return NormalizeApiBaseUrl(fromSettings);
                }

                return DefaultUpdateCheckBaseUrl;
            }
        }

        /// <summary>
        /// owner/repo on Gitea, e.g. pharmdata/elfisa-pharmacy.
        /// </summary>
        public static string UpdateRepo
        {
            get
            {
                var fromEnv = Environment.GetEnvironmentVariable("ELF_UPDATE_REPO");
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return fromEnv.Trim().Trim('/');
                }

                var fromSettings = Settings.Default.UpdateRepo;
                if (!string.IsNullOrWhiteSpace(fromSettings))
                {
                    return fromSettings.Trim().Trim('/');
                }

                return DefaultUpdateRepo;
            }
        }

        /// <summary>
        /// Optional read-only Gitea token for private release repos.
        /// </summary>
        public static string UpdateApiToken
        {
            get
            {
                var fromEnv = Environment.GetEnvironmentVariable("ELF_UPDATE_API_TOKEN");
                if (!string.IsNullOrWhiteSpace(fromEnv))
                {
                    return fromEnv.Trim();
                }

                return Settings.Default.UpdateApiToken ?? string.Empty;
            }
        }

        private static void EnsureSQLiteInteropInBaseDir()
        {
            // System.Data.SQLite ожидает SQLite.Interop.dll рядом с exe.
            // Важно: разрядность DLL должна совпадать с процессом (Prefer32Bit => x86).
            if (_sqliteInteropPrepared)
            {
                return;
            }

            lock (_sqliteInteropLock)
            {
                if (_sqliteInteropPrepared)
                {
                    return;
                }

                var baseDir = AppDomain.CurrentDomain.BaseDirectory;
                var targetDll = Path.Combine(baseDir, "SQLite.Interop.dll");
                var archFolder = Environment.Is64BitProcess ? "x64" : "x86";
                var sourceDll = Path.Combine(baseDir, archFolder, "SQLite.Interop.dll");
                var sourcePdb = Path.Combine(baseDir, archFolder, "SQLite.Interop.pdb");

                try
                {
                    if (File.Exists(sourceDll))
                    {
                        // Всегда подкладываем DLL нужной разрядности (даже если в корне уже лежит "чужая").
                        File.Copy(sourceDll, targetDll, overwrite: true);

                        var targetPdb = Path.Combine(baseDir, "SQLite.Interop.pdb");
                        if (File.Exists(sourcePdb))
                        {
                            File.Copy(sourcePdb, targetPdb, overwrite: true);
                        }
                    }
                }
                catch
                {
                    // Если копирование не удалось (права/readonly/и т.п.), дальше будет явное исключение от SQLite.
                }

                _sqliteInteropPrepared = true;
            }
        }
    }
}
