﻿using System.IO;
using System.Linq;
using System.Text;
using Platform101XP.Editor.Settings.Repositories;
using UnityEngine;

namespace Platform101XP.Editor.Settings.Export
{
    public sealed class IOSSettingsExporter : BaseSettingsExporter
    {
        private readonly IOSSettingsRepository iosSettings;

        public IOSSettingsExporter(BaseSettingsRepository baseSettings, IOSSettingsRepository iosSettings) 
            : base(baseSettings)
        {
            this.iosSettings = iosSettings;
        }

        public override void Export()
        {
            // Target path for IOS setting file.
            const string INFO_PLIST_TARGET_PATH = "Assets/Platform101XP/iOSConfig/P101XP-Info.plist";
            // Build settings file first.
            BuildPlistFile(INFO_PLIST_TARGET_PATH);
            // Write parameter into file by replacing of special placeholders.
            WriteParameterIntoFile(INFO_PLIST_TARGET_PATH);
        }

        // Generate settings file and save it on target path.
        private void BuildPlistFile(string targetPath)
        {
            // File paths of text components that used to build Info.plist file.
            const string BASE_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Root.plist";
            const string FACEBOOK_CF_BUNDLE_URL_TYPES_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Facebook/CFBundleURLTypes.plist";
            const string OK_ROOT_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Odnoklassniki/Odnoklassniki_root.plist";
            const string OK_CF_BUNDLE_URL_TYPES_ARRAY_DICT_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Odnoklassniki/Odnoklassniki_CFBundleURLTypes_array_dict.plist";
            const string OK_LS_APPLICATION_QUERIES_SCHEMES_ARRAY_STRING_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Odnoklassniki/Odnoklassniki_LSApplicationQueriesSchemes_array_string.plist";
            const string VK_ROOT_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Vk/Vk_root.plist";
            const string VK_CF_BUNDLE_URL_TYPES_ARRAY_DICT_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Vk/Vk_CFBundleURLTypes_array_dict.plist";
            const string VK_LS_APPLICATION_QUERIES_SCHEMES_ARRAY_STRING_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Vk/Vk_LSApplicationQueriesSchemes_array_string.plist";
            const string SKIN_ROOT_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Skin/Skin_root.plist";
            const string ADJUST_ROOT_TEMPLATE = "Assets/Platform101XP/Templates/InfoPlist/Adjust/Adjust_root.plist";

            // Special placeholders that used to build Info.plist file by replacing its text components.
            const string ROOT_PLACEHOLDER = "{root}";
            const string CF_BUNDLE_URL_TYPES_ARRAY_ROOT_PLACEHOLDER = "{CFBundleURLTypes_array_root}";
            const string LS_APPLICATION_QUERIES_SCHEMES_ARRAY_ROOT_PLACEHOLDER = "{LSApplicationQueriesSchemes_array_root}";

            // Asserts.
            if (!File.Exists(BASE_TEMPLATE) ||
                !File.Exists(FACEBOOK_CF_BUNDLE_URL_TYPES_TEMPLATE) ||
                !File.Exists(ADJUST_ROOT_TEMPLATE) ||
                !File.Exists(OK_ROOT_TEMPLATE) ||
                !File.Exists(OK_CF_BUNDLE_URL_TYPES_ARRAY_DICT_TEMPLATE) ||
                !File.Exists(OK_LS_APPLICATION_QUERIES_SCHEMES_ARRAY_STRING_TEMPLATE) ||
                !File.Exists(VK_ROOT_TEMPLATE) ||
                !File.Exists(VK_CF_BUNDLE_URL_TYPES_ARRAY_DICT_TEMPLATE) ||
                !File.Exists(VK_LS_APPLICATION_QUERIES_SCHEMES_ARRAY_STRING_TEMPLATE) ||
                !File.Exists(SKIN_ROOT_TEMPLATE))
            {
                Debug.LogError("[P101XP] Can't build Info.plist file!");
                return;
            }

            // Get base template.
            var baseTemplate = File.ReadAllText(BASE_TEMPLATE);

            // Build CFBundleURLTypes.array elements.
            var cfBundleUrlTypesArrayContent = new StringBuilder();
            if (iosSettings.FacebookEnabled)
            {
                var text = File.ReadAllText(FACEBOOK_CF_BUNDLE_URL_TYPES_TEMPLATE);
                cfBundleUrlTypesArrayContent.AppendLine(text);
            }

            if (iosSettings.OkEnabled)
            {
                var text = File.ReadAllText(OK_CF_BUNDLE_URL_TYPES_ARRAY_DICT_TEMPLATE);
                cfBundleUrlTypesArrayContent.AppendLine(text);
            }

            if (iosSettings.VkEnabled)
            {
                var text = File.ReadAllText(VK_CF_BUNDLE_URL_TYPES_ARRAY_DICT_TEMPLATE);
                cfBundleUrlTypesArrayContent.AppendLine(text);
            }

            baseTemplate = baseTemplate.Replace(CF_BUNDLE_URL_TYPES_ARRAY_ROOT_PLACEHOLDER, cfBundleUrlTypesArrayContent.ToString());

            // Build LSApplicationQueriesSchemes.array elements.
            var lsApplicationQueriesSchemesArrayContent = new StringBuilder();
            if (iosSettings.OkEnabled)
            {
                var text = File.ReadAllText(OK_LS_APPLICATION_QUERIES_SCHEMES_ARRAY_STRING_TEMPLATE);
                lsApplicationQueriesSchemesArrayContent.AppendLine(text);
            }

            if (iosSettings.VkEnabled)
            {
                var text = File.ReadAllText(VK_LS_APPLICATION_QUERIES_SCHEMES_ARRAY_STRING_TEMPLATE);
                lsApplicationQueriesSchemesArrayContent.AppendLine(text);
            }

            baseTemplate = baseTemplate.Replace(LS_APPLICATION_QUERIES_SCHEMES_ARRAY_ROOT_PLACEHOLDER, lsApplicationQueriesSchemesArrayContent.ToString());

            // Build root elements.
            var rootContent = new StringBuilder();
            if (iosSettings.OkEnabled)
            {
                var text = File.ReadAllText(OK_ROOT_TEMPLATE);
                rootContent.AppendLine(text);
            }

            if (iosSettings.VkEnabled)
            {
                var text = File.ReadAllText(VK_ROOT_TEMPLATE);
                rootContent.AppendLine(text);
            }

            if (iosSettings.SkinEnabled)
            {
                var text = File.ReadAllText(SKIN_ROOT_TEMPLATE);
                rootContent.AppendLine(text);
            }

            if (iosSettings.EnableAdjust)
            {
                var text = File.ReadAllText(ADJUST_ROOT_TEMPLATE);
                rootContent.AppendLine(text);
            }

            var infoPlistText = baseTemplate.Replace(ROOT_PLACEHOLDER, rootContent.ToString());

            // Create parent directory if not exists (shouldn't happen here)
            var directory = Path.GetDirectoryName(targetPath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            // Write file
            File.WriteAllText(targetPath, infoPlistText);
            Debug.Log($"[P101XP] The Info.plist file has been saved.\nPath: {targetPath}");
        }

        protected override string ReplaceParametersInText(string text)
        {
            // Base settings replacing.
            text = base.ReplaceParametersInText(text);

            // Base.
            text = text.Replace("{skin_name}", iosSettings.SkinName);

            // Odnoklassniki.
            text = text.Replace("{ok_app_id}", iosSettings.OkAppId);
            text = text.Replace("{ok_app_key}", iosSettings.OkAppKey);

            // Vk.
            text = text.Replace("{vk_app_id}", iosSettings.VkAppId);

            // Authorization Window.
            text = text.Replace("{authorization_window_screen_lock_horizontal}", iosSettings.ScreenLockHorizontal.ToString().ToLower());
            text = text.Replace("{authorization_window_screen_lock_vertical}", iosSettings.ScreenLockVertical.ToString().ToLower());

            text = text.Replace("{sn_extra_permission}", iosSettings.SnExtraPermission.ToString().ToLower());
            text = text.Replace("{billing_timeout}", iosSettings.BillingTimeout.ToString());
            text = text.Replace("{app_review_days_as_seconds_for_debug}", iosSettings.AppReviewDaysAsSeconsForDebug.ToString().ToLower());
            text = text.Replace("{guest_enabled}", BaseSettings.GuestEnabled ? "On" : "Off");
            text = text.Replace("{analytics_project_id}", iosSettings.AnalyticsProjectId);
            text = text.Replace("{analytics_project_dev_id}", iosSettings.AnalyticsProjectId);
            var skuStr = string.Empty;
            if (iosSettings.BillingSku != null)
            {
                var strings = iosSettings.BillingSku.Select(x => $"<string>{x}</string>").ToArray();
                skuStr = string.Join("\n\t\t\t", strings);
            }

            // Adjust
            text = text.Replace("{adjust_track_enabled}", iosSettings.EnableAdjustTrack.ToString().ToLower());
            text = text.Replace("{adjust_app_token}", iosSettings.AdjustAppToken);
            text = text.Replace("{adjust_event_map}", iosSettings.AdjustEventMap);

            // Facebook.
            if (iosSettings.FacebookEnabled)
            {
                text = text.Replace("{facebook_app_id}", BaseSettings.FacebookAppId);
                text = text.Replace("{facebook_client_token}", BaseSettings.FacebookClientToken);
                text = text.Replace("{facebook_invite_string}", BaseSettings.FacebookInviteString);
                text = text.Replace("{facebook_auth_enabled}", iosSettings.FacebookAuthEnabled.ToString().ToLower());
            }
            else
            {
                text = text.Replace("{facebook_app_id}", string.Empty);
                text = text.Replace("{facebook_client_token}", string.Empty);
                text = text.Replace("{facebook_invite_string}", string.Empty);
                text = text.Replace("{facebook_auth_enabled}", false.ToString().ToLower());
            }

            text = text.Replace("{billing_sku}", skuStr);

            // Sentry
            text = text.Replace("{sentry_dsn}", iosSettings.SentryDSN);
            text = text.Replace("{sentry_debug_mode}", iosSettings.SentryDebugMode.ToString().ToLower());
            return text;
        }
    }
}
