#!/usr/bin/env node

import { readFileSync } from "node:fs";

const eventName = process.argv[2] ?? "";

const readInput = () => {
  const raw = readFileSync(0, "utf8");
  try {
    return JSON.parse(raw || "{}");
  } catch {
    console.error("invalid hook JSON");
    process.exit(1);
  }
};

const hookEventNames = {
  "session-start": "SessionStart",
  "user-prompt-submit": "UserPromptSubmit",
  "post-tool-use": "PostToolUse",
  "post-compact": "PostCompact",
};

const writeContext = (additionalContext, systemMessage) => {
  const payload = {
    continue: true,
    hookSpecificOutput: {
      hookEventName: hookEventNames[eventName],
      additionalContext,
    },
  };
  if (systemMessage) {
    payload.systemMessage = systemMessage;
  }
  console.log(
    JSON.stringify(payload),
  );
};

const workflowTriggers = [
  { pattern: /(?:^|\s)(?:\$|\/(?:lazyclaude:)?)ulw-plan(?=$|[^\w-])/u, command: "/lazyclaude:ulw-plan", skill: "Skill(ulw-plan)", discipline: "ulw-plan" },
  { pattern: /(?:^|\s)(?:\$|\/(?:lazyclaude:)?)ulw-loop(?=$|[^\w-])/u, command: "/lazyclaude:ulw-loop", skill: "Skill(ulw-loop)", discipline: "ulw-loop" },
  { pattern: /(?:^|\s)(?:\$|\/(?:lazyclaude:)?)start-work(?=$|[^\w-])/u, command: "/lazyclaude:start-work", skill: "Skill(start-work)", discipline: "start-work" },
  { pattern: /(?:^|\s)(?:ultrawork|ulw)(?=$|[^\w-])/u, command: "/lazyclaude:ulw-loop", skill: "Skill(ulw-loop)", discipline: "ulw-loop" },
];

const findWorkflowTrigger = (prompt) => workflowTriggers.find((trigger) => trigger.pattern.test(prompt));

const ultraworkContext = ({ command, skill, discipline }) => [
  "ULTRAWORK MODE ENABLED.",
  `Treat this prompt as an explicit request to use LazyClaude ${discipline} discipline now; load or follow ${command} / ${skill} semantics before ordinary task execution.`,
  "Use evidence-bound planning, tests, manual QA, and cleanup receipts.",
  "Native goal tool integration: only when Claude Code exposes model-facing goal tools, first inspect get_goal, call create_goal with an objective-only payload when no matching goal is active, and reserve update_goal for verified completion or a genuine blocker.",
  "Native /goal fallback: if model-facing goal tools are unavailable or not exposed, say so explicitly and ask the user to bind the native Claude Code goal with /goal <completion condition>; continue with the LazyClaude ledger fallback when they decline or the surface is absent.",
  "Do not auto-type or inject the user's slash commands; treat /goal as Claude Code's native goal surface, not as prompt text for this hook to send.",
  "Dynamic workflow integration: when Claude Code exposes the Workflow tool and the task is broad, risky, parallel, or long-running, call the Workflow tool before serial execution and bind each lane to explicit criteria, artifacts, and cleanup receipts.",
  "Dynamic worktree integration: when Claude Code exposes EnterWorktree and isolated edits are needed, use EnterWorktree for the selected lane; otherwise use or recommend claude --worktree <short-name> --tmux. Never mutate unrelated user state.",
].join(" ");

const input = readInput();

switch (eventName) {
  case "session-start": {
    const cwd = typeof input.cwd === "string" ? input.cwd : "unknown workspace";
    writeContext(`LazyClaude rules loaded for ${cwd}. Read CLAUDE.md, AGENTS.md, .claude/rules/**/*.md, .github/instructions/**/*.md, and named plan or handoff files before edits.`);
    break;
  }
  case "user-prompt-submit": {
    const prompt = typeof input.prompt === "string" ? input.prompt : "";
    const trigger = findWorkflowTrigger(prompt);
    if (trigger) {
      writeContext(ultraworkContext(trigger), `LazyClaude ULW hook active: ${trigger.discipline} guidance injected.`);
    } else {
      writeContext("LazyClaude prompt hook checked: no workflow activation.");
    }
    break;
  }
  case "post-tool-use": {
    const toolName = typeof input.tool_name === "string" ? input.tool_name : "unknown";
    const filePath = typeof input.tool_input?.file_path === "string" ? input.tool_input.file_path : "the edited surface";
    writeContext(`LazyClaude post-edit checks queued for ${toolName} on ${filePath}: inspect comments, run focused tests, and request LSP diagnostics when the edited language has a configured server.`);
    break;
  }
  case "post-compact": {
    writeContext("LazyClaude rule cache reset after compaction.");
    break;
  }
  default: {
    console.error(`unknown hook event: ${eventName || "(missing)"}`);
    process.exit(64);
  }
}
