using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace Sud.UnityExporter
{
    public static class SudTemplateConverter
    {
        private static readonly string TemplateSourceDir = Path.Combine(Application.dataPath, "sud-unity-plugin", "Runtime");

        public static void ConvertWebGLToMinigameUsingTemplate(string webglDir, string minigameDir, bool developmentBuild = false)
        {
            if (string.IsNullOrEmpty(webglDir) || string.IsNullOrEmpty(minigameDir))
            {
                throw new ArgumentException("Invalid path");
            }

            if (!Directory.Exists(webglDir))
            {
                throw new DirectoryNotFoundException($"WebGL directory not found: {webglDir}");
            }

            if (Directory.Exists(minigameDir))
            {
                FileUtil.DeleteFileOrDirectory(minigameDir);
            }

            Debug.Log($"[SudTemplateConverter] Starting conversion...");
            Debug.Log($"[SudTemplateConverter] Template source: {TemplateSourceDir}");
            Debug.Log($"[SudTemplateConverter] WebGL source: {webglDir}");
            Debug.Log($"[SudTemplateConverter] Minigame target: {minigameDir}");

            // Step 1: Copy template files
            CopyTemplateFiles(minigameDir);

            // Step 2: Find WebGL build artifacts
            string dataFileName, frameworkJsFileName, loaderJsFileName, wasmFileName;
            FindBuildArtifacts(webglDir, out dataFileName, out frameworkJsFileName, out loaderJsFileName, out wasmFileName);

            // Step 3: Replace placeholders in main.js
            ReplaceMainJsPlaceholders(minigameDir, developmentBuild, dataFileName, frameworkJsFileName, loaderJsFileName, wasmFileName);

            // Step 4: Copy Build files
            CopyBuildFiles(webglDir, minigameDir, developmentBuild);

            // Step 5: Copy StreamingAssets if exists
            var streamingAssetsSrc = Path.Combine(webglDir, "StreamingAssets");
            var streamingAssetsDst = Path.Combine(minigameDir, "StreamingAssets");
            if (Directory.Exists(streamingAssetsSrc))
            {
                CopyDirectory(streamingAssetsSrc, streamingAssetsDst);
                Debug.Log($"[SudTemplateConverter] Copied StreamingAssets");
            }

            Debug.Log($"[SudTemplateConverter] ✅ Conversion completed successfully!");
            Debug.Log($"[SudTemplateConverter] Output: {minigameDir}");
            Debug.Log($"[SudTemplateConverter] Entry: main.js");
        }

        private static void CopyTemplateFiles(string targetDir)
        {
            Debug.Log($"[SudTemplateConverter] Step 1: Copying template files from sud-default/");

            if (!Directory.Exists(TemplateSourceDir))
            {
                throw new DirectoryNotFoundException($"Template directory not found: {TemplateSourceDir}");
            }

            Directory.CreateDirectory(targetDir);

            var mainJsSrc = Path.Combine(TemplateSourceDir, "main.js");
            var mainJsDst = Path.Combine(targetDir, "main.js");
            if (File.Exists(mainJsSrc))
            {
                File.Copy(mainJsSrc, mainJsDst, true);
                Debug.Log($"[SudTemplateConverter] ✅ Copied main.js");
            }
            else
            {
                throw new FileNotFoundException($"main.js not found in template: {mainJsSrc}");
            }
        }

        private static void ReplaceMainJsPlaceholders(string targetDir, bool developmentBuild,
            string dataFileName, string frameworkJsFileName, string loaderJsFileName, string wasmFileName)
        {
            Debug.Log($"[SudTemplateConverter] Step 3: Replacing placeholders in main.js");

            var mainJsPath = Path.Combine(targetDir, "main.js");
            if (!File.Exists(mainJsPath))
            {
                throw new FileNotFoundException($"main.js not found: {mainJsPath}");
            }

            var content = File.ReadAllText(mainJsPath, Encoding.UTF8);
            var originalLength = content.Length;

            content = content.Replace("$LOADER_FILENAME", loaderJsFileName ?? "");
            content = content.Replace("$DATA_FILENAME", dataFileName ?? "");
            content = content.Replace("$FRAMEWORK_FILENAME", frameworkJsFileName ?? "");
            content = content.Replace("$CODE_FILENAME", wasmFileName ?? "");

            File.WriteAllText(mainJsPath, content, Encoding.UTF8);

            Debug.Log($"[SudTemplateConverter] ✅ Placeholders replaced. Size: {originalLength} -> {content.Length}");
        }

        private static void CopyBuildFiles(string webglDir, string minigameDir, bool developmentBuild)
        {
            Debug.Log($"[SudTemplateConverter] Step 4: Copying Build files");

            var buildSrc = Path.Combine(webglDir, "Build");
            var buildDst = Path.Combine(minigameDir, "Build");

            if (!Directory.Exists(buildSrc))
            {
                throw new DirectoryNotFoundException($"Build directory not found: {buildSrc}");
            }

            CopyDirectory(buildSrc, buildDst);
            Debug.Log($"[SudTemplateConverter] ✅ Copied Build directory");

            CopyWebAdapterFiles(minigameDir, developmentBuild);
        }

        private static void FindBuildArtifacts(string webglDir, out string dataFileName, out string frameworkJsFileName, out string loaderJsFileName, out string wasmFileName)
        {
            dataFileName = frameworkJsFileName = loaderJsFileName = wasmFileName = null;

            var buildPath = Path.Combine(webglDir, "Build");
            if (!Directory.Exists(buildPath))
            {
                Debug.LogError($"[SudTemplateConverter] Build directory not found: {buildPath}");
                return;
            }

            var buildFiles = Directory.GetFiles(buildPath);
            foreach (var filePath in buildFiles)
            {
                var fileName = Path.GetFileName(filePath);

                if (fileName.Contains(".data"))
                    dataFileName = fileName;
                if (fileName.Contains(".framework.js"))
                    frameworkJsFileName = fileName;
                if (fileName.Contains(".loader.js"))
                    loaderJsFileName = fileName;
                if (fileName.Contains(".wasm"))
                    wasmFileName = fileName;
            }

            Debug.Log($"[SudTemplateConverter] Found artifacts: data={dataFileName}, framework={frameworkJsFileName}, loader={loaderJsFileName}, wasm={wasmFileName}");
        }

        private static void CopyDirectory(string sourceDir, string destDir)
        {
            if (!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }

            foreach (var file in Directory.GetFiles(sourceDir))
            {
                var fileName = Path.GetFileName(file);
                File.Copy(file, Path.Combine(destDir, fileName), true);
            }

            foreach (var subDir in Directory.GetDirectories(sourceDir))
            {
                var dirName = Path.GetFileName(subDir);
                CopyDirectory(subDir, Path.Combine(destDir, dirName));
            }
        }

        private static void CopyWebAdapterFiles(string targetDir, bool developmentBuild)
        {
            var adapterSrcDir = Path.Combine(Application.dataPath, "sud-unity-plugin", "Runtime");

            if (!Directory.Exists(adapterSrcDir))
            {
                Debug.LogWarning($"[SudTemplateConverter] Adapter directory not found: {adapterSrcDir}");
                return;
            }

            var adapterSrc = Path.Combine(adapterSrcDir, "unity_adapter.js");
            var adapterDst = Path.Combine(targetDir, "unity_adapter.js");
            if (File.Exists(adapterSrc))
            {
                File.Copy(adapterSrc, adapterDst, true);
                Debug.Log($"[SudTemplateConverter] ✅ Copied unity_adapter.js");
            }
            else
            {
                Debug.LogWarning($"[SudTemplateConverter] ⚠️ unity_adapter.js not found: {adapterSrc}");
            }
        }
    }
}
