using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;

/// <summary>
/// Custom build script for CI that ensures Addressables are built before the player.
/// </summary>
public static class BuildScript {
    /// <summary>
    /// Builds Addressables content. Call via: -executeMethod BuildScript.BuildAddressables
    /// </summary>
    public static void BuildAddressables() {
        Debug.Log("Building Addressables content...");

        AddressableAssetSettings.BuildPlayerContent(out var result);

        if (!string.IsNullOrEmpty(result.Error)) {
            Debug.LogError($"Addressables build failed: {result.Error}");
            EditorApplication.Exit(1);
        }

        Debug.Log($"Addressables build completed. Duration: {result.Duration}s");

        // Log the output location for remote bundles
        var settings = AddressableAssetSettingsDefaultObject.Settings;
        if (settings != null) {
            var profileId = settings.activeProfileId;
            var buildPath = settings.profileSettings.GetValueByName(profileId, "Remote.BuildPath");
            var buildTarget = EditorUserBuildSettings.activeBuildTarget.ToString();
            var resolvedPath = buildPath?.Replace("[BuildTarget]", buildTarget);
            Debug.Log($"Addressables bundles built to: {resolvedPath}");
            Debug.Log("Upload these bundles to your CDN at the configured Remote.LoadPath");
        }
    }

    /// <summary>
    /// Builds Addressables and then the Windows player.
    /// Call via: -executeMethod BuildScript.BuildWindowsPlayer
    /// </summary>
    public static void BuildWindowsPlayer() {
        BuildAddressables();

        string buildPath = GetBuildPathArg();
        if (string.IsNullOrEmpty(buildPath)) {
            Debug.LogError("No build path specified. Use -buildPath <path>");
            EditorApplication.Exit(1);
            return;
        }

        Debug.Log($"Building Windows player to: {buildPath}");

        var options = new BuildPlayerOptions {
            scenes = GetEnabledScenes(),
            locationPathName = buildPath,
            target = BuildTarget.StandaloneWindows64,
            options = BuildOptions.None
        };

        var report = BuildPipeline.BuildPlayer(options);

        if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded) {
            Debug.LogError($"Build failed: {report.summary.result}");
            EditorApplication.Exit(1);
        }

        Debug.Log("Build completed successfully!");
    }

    /// <summary>
    /// Builds Addressables and then the macOS player (Intel).
    /// Call via: -executeMethod BuildScript.BuildMacPlayer
    /// </summary>
    public static void BuildMacPlayer() {
        BuildAddressables();

        string buildPath = GetBuildPathArg();
        if (string.IsNullOrEmpty(buildPath)) {
            Debug.LogError("No build path specified. Use -buildPath <path>");
            EditorApplication.Exit(1);
            return;
        }

        Debug.Log($"Building macOS player to: {buildPath}");

        // Set architecture to Intel + Apple Silicon (Universal)
        EditorUserBuildSettings.SetPlatformSettings(
                BuildPipeline.GetBuildTargetName(BuildTarget.StandaloneOSX),
                "Architecture",
                ((int)UnityEditor.Build.OSArchitecture.x64ARM64).ToString());

        var options = new BuildPlayerOptions {
            scenes = GetEnabledScenes(),
            locationPathName = buildPath,
            target = BuildTarget.StandaloneOSX,
            options = BuildOptions.None
        };

        var report = BuildPipeline.BuildPlayer(options);

        if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded) {
            Debug.LogError($"Build failed: {report.summary.result}");
            EditorApplication.Exit(1);
        }

        Debug.Log("Build completed successfully!");
    }

    /// <summary>
    /// Builds Addressables only for iOS (no player build).
    /// Explicitly switches to iOS build target first.
    /// Call via: -executeMethod BuildScript.BuildiOSAddressables
    /// </summary>
    public static void BuildiOSAddressables() {
        Debug.Log("Switching to iOS build target...");

        if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.iOS) {
            bool success = EditorUserBuildSettings.SwitchActiveBuildTarget(
                    BuildTargetGroup.iOS,
                    BuildTarget.iOS);
            if (!success) {
                Debug.LogError(
                        "Failed to switch to iOS build target. Is iOS Build Support installed?");
                EditorApplication.Exit(1);
                return;
            }
            Debug.Log("Successfully switched to iOS build target");
        }

        BuildAddressables();
    }

    /// <summary>
    /// Builds Addressables and then the iOS player.
    /// Call via: -executeMethod BuildScript.BuildiOSPlayer
    /// Optional: -buildNumber <number> to set CFBundleVersion
    /// </summary>
    public static void BuildiOSPlayer() {
        BuildiOSAddressables();

        string buildPath = GetBuildPathArg();
        if (string.IsNullOrEmpty(buildPath)) {
            Debug.LogError("No build path specified. Use -buildPath <path>");
            EditorApplication.Exit(1);
            return;
        }

        // Set build number if provided (required for unique TestFlight uploads)
        string buildNumber = GetBuildNumberArg();
        if (!string.IsNullOrEmpty(buildNumber)) {
            PlayerSettings.iOS.buildNumber = buildNumber;
            Debug.Log($"Set iOS build number to: {buildNumber}");
        } else {
            Debug.Log($"Using existing iOS build number: {PlayerSettings.iOS.buildNumber}");
        }

        Debug.Log($"Building iOS player to: {buildPath}");

        var options = new BuildPlayerOptions {
            scenes = GetEnabledScenes(),
            locationPathName = buildPath,
            target = BuildTarget.iOS,
            options = BuildOptions.None
        };

        var report = BuildPipeline.BuildPlayer(options);

        if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded) {
            Debug.LogError($"Build failed: {report.summary.result}");
            EditorApplication.Exit(1);
        }

        Debug.Log("iOS build completed successfully!");
        Debug.Log("Open the Xcode project in the output folder to build and deploy to device.");
    }

    private static string[] GetEnabledScenes() {
        var scenes = new System.Collections.Generic.List<string>();
        foreach (var scene in EditorBuildSettings.scenes) {
            if (scene.enabled) { scenes.Add(scene.path); }
        }
        return scenes.ToArray();
    }

    private static string GetBuildPathArg() {
        var args = System.Environment.GetCommandLineArgs();
        for (int i = 0; i < args.Length - 1; i++) {
            if (args[i] == "-buildPath") { return args[i + 1]; }
        }
        return null;
    }

    private static string GetBuildNumberArg() {
        var args = System.Environment.GetCommandLineArgs();
        for (int i = 0; i < args.Length - 1; i++) {
            if (args[i] == "-buildNumber") { return args[i + 1]; }
        }
        return null;
    }
}
