/**
 * GET /api/workspaces/[slug]/bootstrap.sh
 *
 * One-shot installer. Intended usage inside a repo:
 *
 *   curl -sSfL -H "Authorization: Bearer $VIBN_API_KEY" \
 *     https://vibnai.com/api/workspaces/<slug>/bootstrap.sh | sh
 *
 * Writes three files into the cwd:
 *   - .cursor/rules/vibn-workspace.mdc   (system prompt for AI agents)
 *   - .cursor/mcp.json                   (registers /api/mcp as an MCP server)
 *   - .env.local                         (appends VIBN_* envs; never overwrites)
 *
 * Auth: caller MUST already have a `vibn_sk_...` token. We embed the
 * same token in the generated mcp.json so Cursor agents can re-use it.
 * Session auth works too but then nothing is embedded (the user gets
 * placeholder strings to fill in themselves).
 */

import { NextResponse } from 'next/server';
import { requireWorkspacePrincipal } from '@/lib/auth/workspace-auth';

const APP_BASE = process.env.NEXT_PUBLIC_APP_URL?.replace(/\/$/, '') ?? 'https://vibnai.com';

export async function GET(
  request: Request,
  { params }: { params: Promise<{ slug: string }> }
) {
  const { slug } = await params;
  const principal = await requireWorkspacePrincipal(request, { targetSlug: slug });
  if (principal instanceof NextResponse) return principal;

  const ws = principal.workspace;
  const tokenFromHeader = extractBearer(request);
  // For API-key callers we can safely echo the token they sent us
  // back into the generated files. For session callers we emit a
  // placeholder — we don't want to re-issue long-lived tokens from
  // a cookie-authenticated browser request.
  const embedToken =
    principal.source === 'api_key' && tokenFromHeader
      ? tokenFromHeader
      : '<paste your vibn_sk_ token here>';

  const script = buildScript({
    slug: ws.slug,
    giteaOrg: ws.gitea_org ?? '(unprovisioned)',
    coolifyProjectUuid: ws.coolify_project_uuid ?? '(unprovisioned)',
    appBase: APP_BASE,
    token: embedToken,
  });

  return new NextResponse(script, {
    status: 200,
    headers: {
      'Content-Type': 'text/x-shellscript; charset=utf-8',
      'Cache-Control': 'no-store',
    },
  });
}

function extractBearer(request: Request): string | null {
  const a = request.headers.get('authorization');
  if (!a) return null;
  const m = /^Bearer\s+(vibn_sk_[A-Za-z0-9_-]+)/i.exec(a.trim());
  return m?.[1] ?? null;
}

function buildScript(opts: {
  slug: string;
  giteaOrg: string;
  coolifyProjectUuid: string;
  appBase: string;
  token: string;
}): string {
  const { slug, giteaOrg, coolifyProjectUuid, appBase, token } = opts;

  // Build the file bodies in TS so we can shell-escape them cleanly
  // using base64. The script itself does no string interpolation on
  // these payloads — it just decodes and writes.
  const rule = buildCursorRule({ slug, giteaOrg, coolifyProjectUuid, appBase });
  const mcp = JSON.stringify(
    {
      mcpServers: {
        [`vibn-${slug}`]: {
          url: `${appBase}/api/mcp`,
          headers: { Authorization: `Bearer ${token}` },
        },
      },
    },
    null,
    2
  );
  const env = `VIBN_API_BASE=${appBase}\nVIBN_WORKSPACE=${slug}\nVIBN_API_KEY=${token}\n`;

  const b64Rule = Buffer.from(rule, 'utf8').toString('base64');
  const b64Mcp = Buffer.from(mcp, 'utf8').toString('base64');
  const b64Env = Buffer.from(env, 'utf8').toString('base64');

  return `#!/usr/bin/env sh
# Vibn workspace bootstrap — generated ${new Date().toISOString()}
# Workspace: ${slug}
#
# Writes .cursor/rules/vibn-workspace.mdc, .cursor/mcp.json,
# and appends VIBN_* env vars to .env.local (never overwrites).
set -eu

mkdir -p .cursor/rules

echo "${b64Rule}" | base64 -d > .cursor/rules/vibn-workspace.mdc
echo "  wrote .cursor/rules/vibn-workspace.mdc"

echo "${b64Mcp}" | base64 -d > .cursor/mcp.json
echo "  wrote .cursor/mcp.json"

if [ -f .env.local ] && grep -q '^VIBN_API_BASE=' .env.local 2>/dev/null; then
  echo "  .env.local already has VIBN_* — skipping env append"
else
  printf '\\n# Vibn workspace ${slug}\\n' >> .env.local
  echo "${b64Env}" | base64 -d >> .env.local
  echo "  appended VIBN_* to .env.local"
fi

if [ -f .gitignore ] && ! grep -q '^.env.local$' .gitignore 2>/dev/null; then
  echo '.env.local' >> .gitignore
  echo "  added .env.local to .gitignore"
fi

echo ""
echo "Vibn workspace '${slug}' is wired up."
echo "Restart Cursor to pick up the new MCP server."
`;
}

function buildCursorRule(opts: {
  slug: string;
  giteaOrg: string;
  coolifyProjectUuid: string;
  appBase: string;
}): string {
  const { slug, giteaOrg, coolifyProjectUuid, appBase } = opts;
  return `---
description: Vibn workspace "${slug}" — one-shot setup for AI agents
alwaysApply: true
---

# Vibn workspace: ${slug}

You are acting on behalf of the Vibn workspace **${slug}**. All AI
integration with Gitea and Coolify happens through the Vibn REST API,
which enforces tenancy for you.

## How to act

1. Before any git or deploy work, call:
   \`GET ${appBase}/api/workspaces/${slug}/gitea-credentials\`
   with \`Authorization: Bearer $VIBN_API_KEY\` to get a
   workspace-scoped bot username, PAT, and clone URL template.

2. Use the returned \`cloneUrlTemplate\` (with \`{{repo}}\` substituted)
   as the git remote. Never pass the root admin token to git.

3. For deploys, logs, env vars, call the workspace-scoped Coolify
   endpoints under \`${appBase}/api/workspaces/${slug}/apps/...\`.
   Any cross-tenant attempt is rejected with HTTP 403.

## Identity

- Gitea org:               \`${giteaOrg}\`
- Coolify project uuid:    \`${coolifyProjectUuid}\`
- API base:                \`${appBase}\`

## Useful endpoints

| Method | Path                                                           |
|-------:|----------------------------------------------------------------|
| GET    | /api/workspaces/${slug}                                         |
| GET    | /api/workspaces/${slug}/gitea-credentials                       |
| GET    | /api/workspaces/${slug}/apps                                    |
| GET    | /api/workspaces/${slug}/apps/{uuid}                             |
| POST   | /api/workspaces/${slug}/apps/{uuid}/deploy                      |
| GET    | /api/workspaces/${slug}/apps/{uuid}/envs                        |
| PATCH  | /api/workspaces/${slug}/apps/{uuid}/envs                        |
| DELETE | /api/workspaces/${slug}/apps/{uuid}/envs?key=FOO                |
| POST   | /api/mcp     (JSON { tool, params } — see GET /api/mcp for list) |

## Rules

- Never print or commit \`$VIBN_API_KEY\`.
- Prefer PRs over force-pushing \`main\`.
- If you see HTTP 403 on Coolify ops, you're trying to touch an app
  outside this workspace — stop and ask the user.
- Re-run \`bootstrap.sh\` instead of hand-editing these files.
`;
}
