using System.IO;

namespace AxCopilot.Services.Agent;

/// <summary>
/// Phase 17-C-EXT: 훅 환경변수 빌더.
/// 훅 실행 시 셸 환경변수를 자동 주입��니다.
/// Claude Code 호환 변수($CLAUDE_*)와 AX 전용 변수($AX_*)를 모두 제공합니다.
/// </summary>
public static class HookEnvironmentBuilder
{
    /// <summary>HookContext에서 셸 환경변수 딕셔너리를 생성합니다.</summary>
    public static Dictionary<string, string> Build(HookContext context)
    {
        var env = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

        // ── 공통 변수 ──
        env["AX_SESSION_ID"] = context.SessionId;
        env["AX_HOOK_EVENT"] = context.Event.ToString();
        env["AX_CWD"] = context.WorkFolder;

        // ── 도구 관련 (PreToolUse, PostToolUse, PostToolUseFailure) ──
        if (!string.IsNullOrEmpty(context.ToolName))
        {
            env["AX_TOOL_NAME"] = context.ToolName;
            env["CLAUDE_TOOL_NAME"] = context.ToolName; // CC 호환
        }

        if (!string.IsNullOrEmpty(context.ToolInput))
        {
            env["AX_TOOL_INPUT"] = context.ToolInput;
            env["CLAUDE_TOOL_INPUT"] = context.ToolInput; // CC 호환
        }

        if (!string.IsNullOrEmpty(context.ToolOutput))
        {
            env["AX_TOOL_OUTPUT"] = Truncate(context.ToolOutput, 4000);
        }

        // ── 파일 경로 (Write, Edit 도구 시 — ToolInput에서 추출) ──
        var filePath = ExtractFilePath(context.ToolName, context.ToolInput);
        if (!string.IsNullOrEmpty(filePath))
        {
            env["AX_FILE_PATH"] = filePath;
            env["CLAUDE_FILE_PATH"] = filePath; // CC 호환
        }

        // ── 파일 변경 (FileChanged 이벤트) ──
        if (!string.IsNullOrEmpty(context.ChangedFilePath))
        {
            env["AX_CHANGED_FILE"] = context.ChangedFilePath;
        }

        // ── CwdChanged 전용: CLAUDE_ENV_FILE ──
        if (context.Event == HookEventKind.CwdChanged)
        {
            var envFile = Path.Combine(Path.GetTempPath(), "AxCopilot",
                $"env_{context.SessionId}.txt");
            var envDir = Path.GetDirectoryName(envFile);
            if (!string.IsNullOrEmpty(envDir) && !Directory.Exists(envDir))
                Directory.CreateDirectory(envDir);

            env["CLAUDE_ENV_FILE"] = envFile;
            env["AX_ENV_FILE"] = envFile;
        }

        // ── 사용자 프롬프트 (UserPromptSubmit) ──
        if (!string.IsNullOrEmpty(context.UserMessage))
        {
            env["AX_USER_PROMPT"] = Truncate(context.UserMessage, 2000);
        }

        return env;
    }

    /// <summary>도구 입력에서 파일 경로를 추출합니다 (file_write, file_edit 도구).</summary>
    private static string? ExtractFilePath(string? toolName, string? toolInput)
    {
        if (string.IsNullOrEmpty(toolName) || string.IsNullOrEmpty(toolInput))
            return null;

        // file_write, file_edit, script_create 등에서 path/file_path 추출
        if (toolName is "file_write" or "file_edit" or "script_create"
            or "file_manage" or "file_read")
        {
            try
            {
                var doc = System.Text.Json.JsonDocument.Parse(toolInput);
                if (doc.RootElement.TryGetProperty("path", out var pathProp))
                    return pathProp.GetString();
                if (doc.RootElement.TryGetProperty("file_path", out var fp))
                    return fp.GetString();
            }
            catch (Exception) { }
        }

        return null;
    }

    private static string Truncate(string text, int maxLength)
        => text.Length <= maxLength ? text : text[..maxLength];
}
