#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System.Diagnostics;
using System.IO;
using Debug = UnityEngine.Debug;

/// <summary>
/// GitAutoSync — Unity Editor 자동 git sync (BurningTimes BT5-Dev C안, 2026-04-23 PD 승인)
///
/// 구조: Unity Editor(본 스크립트) = trigger 전용. 실제 git 작업은
///       BT 본 레포 scripts/unity_auto_sync.sh (bash) 가 수행.
///       이 분리로 스크립트 컴파일 오류가 git 기능을 마비시키는 리스크 차단.
///
/// 동작:
///   - Unity Editor 시작 시: 자동 pull (EditorPrefs 토글 가능)
///   - Unity Editor 종료 시: 자동 push (add + commit + push 일괄)
///   - Menu: Tools/Git/Pull Now·Push Now·Status·토글 옵션
///
/// 의존:
///   - Git for Windows (bash.exe) — PD 실증 환경
///   - BURNINGTIMES_ROOT 환경변수 또는 기본 E:/BurningTimes
///   - paths.local.json 의 UNITY_PROJECT_ROOT · UNITY_GIT_REMOTE 설정
/// </summary>
[InitializeOnLoad]
public static class GitAutoSync
{
    private const string BT_ROOT_ENV = "BURNINGTIMES_ROOT";
    private const string BT_ROOT_FALLBACK = "E:/BurningTimes";
    private const string SYNC_SCRIPT_REL = "scripts/unity_auto_sync.sh";

    private const string PREF_PULL_ON_LOAD = "GitAutoSync.PullOnLoad";
    private const string PREF_PUSH_ON_QUIT = "GitAutoSync.PushOnQuit";

    private const string GIT_BASH_FALLBACK = @"C:\Program Files\Git\bin\bash.exe";

    static GitAutoSync()
    {
        // Unity Editor 시작 시 컴파일 안정화 후 pull (delayCall은 프레임 지연)
        EditorApplication.delayCall += OnEditorStart;
        EditorApplication.quitting += OnEditorQuit;
    }

    // ─────────────────────────────────────────────────────────
    // 경로·bash 해결
    // ─────────────────────────────────────────────────────────
    private static string GetBTRoot()
    {
        string envRoot = System.Environment.GetEnvironmentVariable(BT_ROOT_ENV);
        return string.IsNullOrEmpty(envRoot) ? BT_ROOT_FALLBACK : envRoot;
    }

    private static string GetSyncScriptPath()
    {
        return Path.Combine(GetBTRoot(), SYNC_SCRIPT_REL).Replace('\\', '/');
    }

    private static string GetBashPath()
    {
        // Windows Git Bash 우선 (PD 환경 실증)
        if (File.Exists(GIT_BASH_FALLBACK)) return GIT_BASH_FALLBACK;
        // PATH 검색 fallback (macOS/Linux 포함)
        return "bash";
    }

    // ─────────────────────────────────────────────────────────
    // bash 스크립트 호출
    // ─────────────────────────────────────────────────────────
    private static int RunSync(string action)
    {
        string scriptPath = GetSyncScriptPath();
        if (!File.Exists(scriptPath))
        {
            Debug.LogWarning($"[GitAutoSync] 스크립트 부재: {scriptPath}\n" +
                             $"BT 본 레포 확인 필요 (환경변수 {BT_ROOT_ENV} 또는 {BT_ROOT_FALLBACK})");
            return -1;
        }

        var psi = new ProcessStartInfo
        {
            FileName = GetBashPath(),
            Arguments = $"\"{scriptPath}\" {action}",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };

        try
        {
            using (var proc = Process.Start(psi))
            {
                string stdout = proc.StandardOutput.ReadToEnd();
                string stderr = proc.StandardError.ReadToEnd();
                proc.WaitForExit();

                string combined = stdout + (string.IsNullOrEmpty(stderr) ? "" : "\n[stderr]\n" + stderr);

                if (proc.ExitCode == 0)
                {
                    Debug.Log($"[GitAutoSync] {action} 성공\n{combined}");
                }
                else
                {
                    Debug.LogError($"[GitAutoSync] {action} 실패 (exit {proc.ExitCode})\n{combined}");
                    // 수동 개입 필요한 케이스 (충돌 등)는 Dialog로 PD 알림
                    if (action == "pull" || action == "push")
                    {
                        EditorApplication.delayCall += () =>
                            EditorUtility.DisplayDialog(
                                "GitAutoSync 실패",
                                $"{action} 실패 (exit {proc.ExitCode}).\n\nConsole 로그 확인 후 수동 해결 필요.",
                                "확인");
                    }
                }
                return proc.ExitCode;
            }
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"[GitAutoSync] {action} 예외: {ex.Message}\n{ex.StackTrace}");
            return -2;
        }
    }

    // ─────────────────────────────────────────────────────────
    // 자동 hook
    // ─────────────────────────────────────────────────────────
    private static void OnEditorStart()
    {
        if (EditorPrefs.GetBool(PREF_PULL_ON_LOAD, true))
        {
            Debug.Log("[GitAutoSync] Unity Editor 시작 — auto pull");
            RunSync("pull");
        }
    }

    private static void OnEditorQuit()
    {
        if (EditorPrefs.GetBool(PREF_PUSH_ON_QUIT, true))
        {
            Debug.Log("[GitAutoSync] Unity Editor 종료 — auto push");
            RunSync("push");
        }
    }

    // ─────────────────────────────────────────────────────────
    // Menu 수동 발동
    // ─────────────────────────────────────────────────────────
    [MenuItem("Tools/Git/Pull Now %#g")]
    private static void MenuPull()   { RunSync("pull"); }

    [MenuItem("Tools/Git/Push Now %#p")]
    private static void MenuPush()   { RunSync("push"); }

    [MenuItem("Tools/Git/Status")]
    private static void MenuStatus() { RunSync("status"); }

    [MenuItem("Tools/Git/Init Repo (최초 1회)")]
    private static void MenuInit()
    {
        if (EditorUtility.DisplayDialog(
            "Unity 프로젝트 git 초기화",
            "Unity 프로젝트 경로에 git 레포를 초기화합니다. 최초 1회만 수행하세요.\n\nGitea 레포 생성은 별도로 수동 집행 필요.",
            "진행", "취소"))
        {
            RunSync("init");
        }
    }

    [MenuItem("Tools/Git/Toggle Auto Pull On Load")]
    private static void TogglePull()
    {
        bool next = !EditorPrefs.GetBool(PREF_PULL_ON_LOAD, true);
        EditorPrefs.SetBool(PREF_PULL_ON_LOAD, next);
        Debug.Log($"[GitAutoSync] Auto Pull On Load: {next}");
    }

    [MenuItem("Tools/Git/Toggle Auto Push On Quit")]
    private static void TogglePush()
    {
        bool next = !EditorPrefs.GetBool(PREF_PUSH_ON_QUIT, true);
        EditorPrefs.SetBool(PREF_PUSH_ON_QUIT, next);
        Debug.Log($"[GitAutoSync] Auto Push On Quit: {next}");
    }
}
#endif
