using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;

namespace RebootKit.Editor.Build {
    class BuildVersionBumper : IPostprocessBuildWithReport {
        public int callbackOrder => 0;

        public void OnPostprocessBuild(BuildReport report) {
            VersionUpdater.IncrementPatch();
        }
    }

    static class VersionUpdater {
        public static bool IncrementVersion(int incrementMajor = 0, int incrementMinor = 0, int incrementPatch = 0) {
            if (TryParseVersion(PlayerSettings.bundleVersion, out int major, out int minor, out int patch)) {
                major += incrementMajor;
                minor += incrementMinor;
                patch += incrementPatch;
                string newVersion = $"{major}.{minor}.{patch}";

                if (SetVersion(newVersion)) {
                    Debug.Log($"Updated version to: {newVersion}");
                } else {
                    Debug.LogError($"Failed to update version to: {newVersion}");
                    return false;
                }
            } else {
                Debug.LogError($"Failed to parse current version: {PlayerSettings.bundleVersion}");
                return false;
            }

            return true;
        }

        public static bool IncrementMajor() => IncrementVersion(incrementMajor: 1);
        public static bool IncrementMinor() => IncrementVersion(incrementMinor: 1);
        public static bool IncrementPatch() => IncrementVersion(incrementPatch: 1);

        static bool SetVersion(string newVersion) {
            if (!IsValidVersionFormat(newVersion)) {
                Debug.LogError($"Invalid version format: {newVersion}. Expected format: maj.min.ver");
                return false;
            }

            PlayerSettings.bundleVersion = newVersion;
            Debug.Log($"Application version updated to: {newVersion}");
            return true;
        }

        static bool IsValidVersionFormat(string version) {
            string[] parts = version.Split('.');
            return parts.Length == 3 && int.TryParse(parts[0], out _) && int.TryParse(parts[1], out _) && int.TryParse(parts[2], out _);
        }

        static bool TryParseVersion(string version, out int major, out int minor, out int patch) {
            major = -1;
            minor = -1;
            patch = -1;

            string[] parts = version.Split('.');
            if (parts.Length != 3) {
                return false;
            }

            return int.TryParse(parts[0], out major) &&
                   int.TryParse(parts[1], out minor) &&
                   int.TryParse(parts[2], out patch);
        }
    }
}