/**
 * Builds the initial prompt handed to each orchestrator agent run.
 *
 * The agent runs inside an isolated git worktree with pi's built-in coding
 * tools (read/bash/edit/write/…). It reaches this server over loopback to read
 * context (the kanban board + documentation) and to record its work (card
 * moves, comments, references, and documentation updates). The documentation is
 * the central store of truth: the agent reads it to learn how things should
 * work and updates it when it makes design decisions or completes work.
 */

import type { Card } from '../types.js';
import { API_BASE } from './config.js';

export interface PromptContext {
  /** Secret token authorising this run's internal API calls. */
  token: string;
  /** This run's id (used in some callbacks). */
  runId: string;
}

/** A compact, LLM-readable snapshot of the card being worked. */
function describeCard(card: Card): string {
  const refs = card.references.length
    ? card.references.map((r) => `- [${r.type}] ${r.label} → ${r.href}`).join('\n')
    : '(none)';
  const tags = card.tags.length ? card.tags.join(', ') : '(none)';
  const comments = card.comments.length
    ? card.comments
        .map((c) => `- ${c.author}: ${c.text}`)
        .join('\n')
    : '(none)';
  return [
    `card_id: ${card.id}`,
    `title: ${card.title}`,
    `category: ${card.category}`,
    `status: ${card.status}`,
    `description: ${card.description}`,
    `details: ${card.details}`,
    `files: ${card.files ?? '(unspecified)'}`,
    `notes: ${card.notes ?? '(none)'}`,
    `references:\n${refs}`,
    `tags: ${tags}`,
    `existing comments:\n${comments}`,
  ].join('\n');
}

/** The full agent contract: how to read state and record work via HTTP. */
function apiContract(ctx: PromptContext): string {
  const auth = `-H "x-agent-token: ${ctx.token}"`;
  return `
## API contract (this server, over loopback)

All endpoints are relative to \`${API_BASE}\`. GET/read endpoints are public; the
**mutation** endpoints require the header \`x-agent-token: ${ctx.token}\`. Use \`curl\`.

### Read context (the store of truth)
- \`GET /api/kanban/board\`        — every card, its status, references, comments.
- \`GET /api/kanban/pages\`        — registry of static design doc pages (path/title/blurb).
- \`GET /api/pages\`               — all custom (dynamic) documentation pages.
- \`GET /api/pages/:slug\`         — one custom page (its \`content\` + rendered \`html\`).

### Record your work (token required)
- Post a progress/decision note onto the card:
  \`\`\`bash
  curl -sX POST ${API_BASE}/api/internal/cards/<card_id>/comments ${auth} \\
    -H 'Content-Type: application/json' \\
    -d '{"text":"..."}'
  \`\`\`
- Move the card between \`backlog\`|\`todo\`|\`in-progress\` as its status changes.
  **NEVER move a card to \`done\` — that returns \`403\`; only a human may complete a
  card.** When you finish, leave the card \`in-progress\` and post a summary
  comment so the operator can review and complete it:
  \`\`\`bash
  curl -sX PATCH ${API_BASE}/api/internal/cards/<card_id> ${auth} \\
    -H 'Content-Type: application/json' -d '{"status":"in-progress"}'
  \`\`\`
- Link the card to a doc page (existing or one you just created):
  \`\`\`bash
  curl -sX POST ${API_BASE}/api/internal/cards/<card_id>/references ${auth} \\
    -H 'Content-Type: application/json' \\
    -d '{"label":"Decision Log","type":"custom","href":"/docs/custom/decision-log"}'
  \`\`\`
- Create or update a custom documentation page (upsert by slug). Use this to log
  design decisions, architecture, or completed-work summaries — the docs are the
  store of truth, so persist important decisions here, not just in chat:
  \`\`\`bash
  curl -sX POST ${API_BASE}/api/internal/pages ${auth} \\
    -H 'Content-Type: application/json' -d '{
      "title":"Combat Resolution — Decision Log",
      "icon":"⚔",
      "blurb":"How damage and hit resolution were implemented.",
      "content":"# Combat resolution\\n\\n...markdown or HTML..."
    }'
  \`\`\`
  If a page with the same slug (derived from the title) already exists it is updated.
`;
}

/**
 * Compose the initial user prompt for a run.
 *
 * @param card the card to implement
 * @param ctx run credentials
 * @param userPrompt optional extra instructions from the human (steer the run)
 */
export function buildPrompt(card: Card, ctx: PromptContext, userPrompt?: string): string {
  return `You are the autonomous engineering agent for VOID::NAV, a single-player
narrative space-exploration RPG. You are working one item from the implementation
board. You operate inside an isolated git worktree that is ALREADY checked out on
a dedicated branch — commit your work there.

## Repository layout
- \`apps/game\` — the playable client (Rust + Bevy 0.16). READ \`apps/game/AGENTS.md\`
  and the root \`AGENTS.md\` for conventions. CRITICAL: never suppress compiler
  warnings/errors (no \`#[allow(...)]\`, no \`_unused\` prefixes) — fix the cause.
- \`apps/docs\` — the living design docs (Vite + React). The documentation is the
  central store of truth for HOW the game should work.
- \`apps/api\` — this backend (Hono + SQLite): kanban board + documentation store.

## Documentation is the store of truth
- READ the docs first to understand intent. Update them when you make a design
  decision or finish work — persist decisions as custom pages (see API contract)
  and link the card to them. Do not leave important decisions only in chat.
- Prefer small, focused doc pages with clear titles.

## Workflow
1. Read the card below and any referenced design docs.
2. Explore the relevant code (use \`read\`/\`grep\`/\`find\`/\`ls\`).
3. Plan briefly, then implement on this branch. Keep changes scoped to the card.
4. Verify: in \`apps/game\` run \`cargo check\` (and \`cargo clippy\` if relevant); in
   the TS apps run \`pnpm --filter @void-nav/<pkg> check\` from the repo root.
5. Commit your work with a clear message.
6. Record outcomes: post a concise summary comment on the card, create/update the
   relevant documentation page(s), and link them to the card. Leave the card in
   \`in-progress\` when your work is ready for review — you may NEVER mark a card
   \`done\`; only a human completes cards. (Moving it to \`done\` is rejected by the
   API.) Move it to \`todo\`/\`backlog\` only if you determine it is not yet ready.
7. Stop when your work for this card is finished or genuinely blocked. Leave the
   card in \`in-progress\` either way (with a comment explaining any blocker); a
   human reviews and marks it \`done\`.

Be autonomous and thorough, but keep each run focused on THIS card.
${apiContract(ctx)}

${userPrompt?.trim() ? `## Additional instructions from the operator\n${userPrompt.trim()}\n` : ''}
## Your card

\`\`\`
${describeCard(card)}
\`\`\`

Begin now. Start by reading the relevant docs and code, then implement.
`;
}

/**
 * Prompt for a conflict-resolution agent run. A batch merge of `branch` into
 * `target` stopped with conflicts; the merge is mid-progress in the main
 * checkout, so the agent resolves the conflicted files, verifies, and commits
 * to complete the merge.
 */
export function buildConflictResolutionPrompt(
  target: string,
  branch: string,
  conflictedPaths: string[],
): string {
  const fileList = conflictedPaths.map((p) => `- ${p}`).join('\n');
  return `You are resolving git merge conflicts in the VOID::NAV repo. A batch merge of
the agent branch \`${branch}\` into \`${target}\` stopped with conflicts. The merge
is IN PROGRESS in this working tree (the main checkout) — conflict markers are
present in the files below.

## Your job
1. For each conflicted file, read BOTH sides (the markers show ${target} vs ${branch})
   and resolve them, preserving the intent of each change. Do not simply discard
   one side unless it is genuinely obsolete.
2. Honor repo conventions: in \`apps/game\` (Rust + Bevy) NEVER suppress compiler
   warnings/errors (no \`#[allow(...)]\`, no \`_unused\` prefixes) — fix the cause.
   Keep TS types clean in the TS apps.
3. Verify your resolution builds: in \`apps/game\` run \`cargo check\` (and
   \`cargo clippy\` if you touched Rust); for TS apps run
   \`pnpm --filter @void-nav/<pkg> check\` from the repo root. Fix anything your
   resolution broke.
4. Stage every resolved file and COMPLETE THE MERGE with a commit:
   \`git add -A\` then \`git commit --no-edit\` (a merge is in progress, so this
   finalizes the merge commit). Do NOT push.
5. Stop once the merge commit is made and the working tree is clean.

## Conflicted files
${fileList || '(none listed — run \\`git status\\` to find them)'}

Resolve the conflicts now, verify, and commit to complete the merge.
`;
}

