#if UNITY_ANDROID
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor.Android;
using UnityEngine;

namespace Dirichlet.Ad.Editor
{
    /// <summary>
    /// Post-processes the Gradle files to inject Dirichlet Ad SDK dependencies.
    /// 
    /// This approach allows coexistence with other SDKs (e.g., TapSDK) by injecting
    /// dependencies into Unity-generated Gradle files rather than shipping static templates.
    /// </summary>
    public class DirichletGradlePostProcessor : IPostGenerateGradleAndroidProject
    {
        private const string TAG = "[DirichletAd]";
        
        // Marker comments to identify our injected content
        private const string DIRICHLET_DEPS_START = "// Dirichlet Ad Dependencies Start";
        private const string DIRICHLET_DEPS_END = "// Dirichlet Ad Dependencies End";
        private const string DIRICHLET_REPOS_START = "// Dirichlet Ad Repositories Start";
        private const string DIRICHLET_REPOS_END = "// Dirichlet Ad Repositories End";
        
        public int callbackOrder => 100; // Run after EDM4U (which uses lower values)

        public void OnPostGenerateGradleAndroidProject(string path)
        {
            Debug.Log($"{TAG} Processing Gradle project at: {path}");

            ProcessBuildGradle(path);
            ProcessSettingsGradle(path);
        }

        private void ProcessBuildGradle(string projectPath)
        {
            // Unity 2019.3+: projectPath is unityLibrary folder, build.gradle is directly inside
            // Unity 2019.2 and below: projectPath might be the root, need to search
            var gradlePath = Path.Combine(projectPath, "build.gradle");
            
            if (!File.Exists(gradlePath))
            {
                // Fallback: try to find build.gradle in subdirectories
                var searchPaths = new[]
                {
                    Path.Combine(projectPath, "unityLibrary", "build.gradle"),
                    Path.Combine(projectPath, "src", "main", "build.gradle")
                };
                
                foreach (var path in searchPaths)
                {
                    if (File.Exists(path))
                    {
                        gradlePath = path;
                        break;
                    }
                }
            }
            
            if (!File.Exists(gradlePath))
            {
                Debug.LogWarning($"{TAG} Could not find build.gradle at {projectPath}");
                return;
            }
            
            Debug.Log($"{TAG} Found build.gradle at: {gradlePath}");

            var content = File.ReadAllText(gradlePath);
            Debug.Log($"{TAG} Original build.gradle length: {content.Length}");

            // Remove any previously injected content (for clean re-injection)
            content = RemoveInjectedContent(content, DIRICHLET_DEPS_START, DIRICHLET_DEPS_END);
            content = RemoveInjectedContent(content, DIRICHLET_REPOS_START, DIRICHLET_REPOS_END);

            // Inject repositories
            content = InjectRepositories(content);

            // Inject dependencies
            content = InjectDependencies(content);

            File.WriteAllText(gradlePath, content);
            Debug.Log($"{TAG} Updated build.gradle with Dirichlet Ad dependencies");
        }

        private string InjectRepositories(string content)
        {
            // Check if our repos are already injected
            if (content.Contains(DIRICHLET_REPOS_START))
            {
                return content;
            }
            
            var reposBlock = new StringBuilder();
            reposBlock.AppendLine(DIRICHLET_REPOS_START);
            reposBlock.AppendLine("    google()");
            reposBlock.AppendLine("    mavenCentral()");
            reposBlock.AppendLine("    flatDir {");
            reposBlock.AppendLine("        dirs 'DirichletAd/libs'");
            reposBlock.AppendLine("    }");
            reposBlock.AppendLine($"    {DIRICHLET_REPOS_END}");
            
            // Try to find repositories block and inject after opening brace
            var reposPattern = new Regex(@"(repositories\s*\{)");
            if (reposPattern.IsMatch(content))
            {
                // Insert after first repositories {
                content = reposPattern.Replace(content, m => 
                    m.Groups[1].Value + "\n    " + reposBlock.ToString(), 1);
                Debug.Log($"{TAG} Injected repositories block");
            }
            else
            {
                Debug.LogWarning($"{TAG} Could not find repositories block, adding one");
                // Add repositories block after apply plugin line
                var applyPattern = new Regex(@"(apply plugin:\s*'com\.android\.library'[^\n]*\n)");
                if (applyPattern.IsMatch(content))
                {
                    content = applyPattern.Replace(content, m =>
                        m.Groups[1].Value + "\nrepositories {\n    " + reposBlock.ToString() + "}\n", 1);
                }
            }
            
            return content;
        }

        private string InjectDependencies(string content)
        {
            // Check if our deps are already injected
            if (content.Contains(DIRICHLET_DEPS_START))
            {
                return content;
            }
            
            var depsBlock = new StringBuilder();
            depsBlock.AppendLine(DIRICHLET_DEPS_START);
            
            // Local AAR
            depsBlock.AppendLine("    implementation(name: 'dirichlet_ad_4.2.5.0', ext: 'aar')");
            
            // Maven dependencies (required for SDK functionality)
            depsBlock.AppendLine("    implementation 'com.android.support:recyclerview-v7:28.0.0'");
            depsBlock.AppendLine("    implementation 'com.github.bumptech.glide:glide:4.9.0'");
            depsBlock.AppendLine("    implementation 'com.android.support:support-v4:28.0.0'");
            depsBlock.AppendLine("    implementation 'com.android.support:support-annotations:28.0.0'");
            depsBlock.AppendLine("    implementation 'com.android.support:appcompat-v7:28.0.0'");
            depsBlock.AppendLine("    implementation 'com.squareup.okhttp3:okhttp:3.12.1'");
            
            depsBlock.AppendLine($"    {DIRICHLET_DEPS_END}");
            
            // Find dependencies block and inject after opening brace
            var depsPattern = new Regex(@"(dependencies\s*\{)");
            if (depsPattern.IsMatch(content))
            {
                content = depsPattern.Replace(content, m => 
                    m.Groups[1].Value + "\n    " + depsBlock.ToString(), 1);
                Debug.Log($"{TAG} Injected dependencies block");
            }
            else
            {
                Debug.LogWarning($"{TAG} Could not find dependencies block");
            }
            
            return content;
        }

        private void ProcessSettingsGradle(string projectPath)
        {
            // Navigate to parent directory to find settings.gradle
            var parentDir = Directory.GetParent(projectPath)?.FullName;
            if (string.IsNullOrEmpty(parentDir))
            {
                Debug.LogWarning($"{TAG} Could not get parent directory");
                return;
            }
            
            var settingsPath = Path.Combine(parentDir, "settings.gradle");
            if (!File.Exists(settingsPath))
            {
                Debug.LogWarning($"{TAG} Could not find settings.gradle at {settingsPath}");
                return;
            }

            var content = File.ReadAllText(settingsPath);
            
            // Check if already injected
            if (content.Contains(DIRICHLET_REPOS_START))
            {
                Debug.Log($"{TAG} settings.gradle already has Dirichlet repos");
                return;
            }
            
            // Remove any previously injected content
            content = RemoveInjectedContent(content, DIRICHLET_REPOS_START, DIRICHLET_REPOS_END);
            
            var reposBlock = new StringBuilder();
            reposBlock.AppendLine(DIRICHLET_REPOS_START);
            reposBlock.AppendLine("        google()");
            reposBlock.AppendLine("        mavenCentral()");
            reposBlock.AppendLine("        flatDir {");
            reposBlock.AppendLine("            dirs \"${project(':unityLibrary').projectDir}/DirichletAd/libs\"");
            reposBlock.AppendLine("        }");
            reposBlock.AppendLine($"        {DIRICHLET_REPOS_END}");
            
            // Find dependencyResolutionManagement repositories block
            var reposPattern = new Regex(@"(dependencyResolutionManagement\s*\{[\s\S]*?repositories\s*\{)");
            if (reposPattern.IsMatch(content))
            {
                content = reposPattern.Replace(content, m => 
                    m.Groups[1].Value + "\n        " + reposBlock.ToString(), 1);
                File.WriteAllText(settingsPath, content);
                Debug.Log($"{TAG} Updated settings.gradle with Dirichlet Ad repositories");
            }
            else
            {
                Debug.LogWarning($"{TAG} Could not find dependencyResolutionManagement repositories block in settings.gradle");
            }
        }

        private string RemoveInjectedContent(string content, string startMarker, string endMarker)
        {
            var pattern = new Regex($@"\s*{Regex.Escape(startMarker)}[\s\S]*?{Regex.Escape(endMarker)}\s*");
            return pattern.Replace(content, "\n");
        }
    }
}
#endif
