using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Platform101XP.Editor.Settings;
using UnityEditor;
using UnityEngine;

namespace Platform101XP.Editor
{
    public sealed class P101XPPostImport : AssetPostprocessor
    {
        // Debounce key to avoid re-entrancy when our own generation triggers imports.
        private const string k_SessionDebounceKey = "P101XP.P101XPPostImport.Running";
        private const string k_PluginFolder = "Assets/Platform101XP";

        // Files we expecting to exist
        private static readonly string[] s_ExpectedSettingFiles =
        {
            "Assets/Plugins/Android/P101XP.androidlib/res/values/strings.xml",
            "Assets/Plugins/Android/P101XP.androidlib/AndroidManifest.xml",
            "Assets/Platform101XP/iOSConfig/P101XP-Info.plist",
        };

        // 1) Fires after any asset import/move/delete
        static void OnPostprocessAllAssets(
            string[] importedAssets,
            string[] deletedAssets,
            string[] movedAssets,
            string[] movedFromAssetPaths,
            bool didDomainReload)
        {
            PostImportAction();
        }

        // 2) Also run once on editor load/domain reload, handy on clean projects.
        [InitializeOnLoadMethod]
        private static void RunOnLoad()
        {
            PostImportAction();
        }

        private static void PostImportAction()
        {
            // Skip if runs on CI
            if (Application.isBatchMode) return;

            // If our own run is underway, skip (prevents loops).
            if (SessionState.GetBool(k_SessionDebounceKey, false)) return;

            // Slight delay batches multiple import waves into one run.
            EditorApplication.delayCall += ExecutePostImportActions;
        }

        private static void ExecutePostImportActions()
        {
            if (SessionState.GetBool(k_SessionDebounceKey, false)) return;
            if (!Directory.Exists(k_PluginFolder)) return; // case when plugin removed
            SessionState.SetBool(k_SessionDebounceKey, true);

            try
            {
                EnsureConfigFilesExists();
                EnsureSettingsExists();
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
            finally
            {
                SessionState.EraseBool(k_SessionDebounceKey);
            }
        }


        private static void EnsureConfigFilesExists()
        {
            Dictionary<string, string> sourceTargetDict = new()
            {
                {
                    "Assets/Platform101XP/Templates/Sample/GoogleService-Info-sample.plist",
                    "Assets/Platform101XP/iOSConfig/GoogleService-Info.plist"
                },
                {
                    "Assets/Platform101XP/Templates/Sample/P101XP-sample.entitlements",
                    "Assets/Platform101XP/iOSConfig/P101XP.entitlements"
                },
                {
                    "Assets/Platform101XP/Templates/Sample/google-services-sample.json",
                    "Assets/Platform101XP/AndroidConfig/google-services.json"
                }
            };

            foreach (var sourceTarget in sourceTargetDict)
            {
                if (!File.Exists(sourceTarget.Key))
                {
                    Debug.LogError("[P101XP] Source config file not found:" + sourceTarget.Key);
                    continue;
                }

                if (File.Exists(sourceTarget.Value))
                {
                    // Target file exists, skip
                    continue;
                }

                var targetDir = Path.GetDirectoryName(sourceTarget.Value);
                if (!Directory.Exists(targetDir))
                {
                    Directory.CreateDirectory(targetDir);
                }

                File.Copy(sourceTarget.Key, sourceTarget.Value);
                Debug.Log("[P101XP] Sample config file was created: " + sourceTarget.Value);
            }
        }

        private static void EnsureSettingsExists()
        {
            bool settingsApplyRequired = false;
            foreach (var file in s_ExpectedSettingFiles)
            {
                if (!FileExists(file))
                {
                    settingsApplyRequired = true;
                    break;
                }
            }

            if (settingsApplyRequired)
            {
                // Apply settings to generate required files
                SettingsManager.Instance.ExportAll();

                // Refresh so Unity picks up newly created files
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
            }
        }

        private static bool FileExists(string assetPath)
        {
            // Use AssetDatabase where possible (handles meta/virtualized assets)
            if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath) != null)
                return true;

            // Fallback to disk check (for plain text / non-Unity assets)
            var full = Path.GetFullPath(assetPath);
            return File.Exists(full);
        }
    }
}