import { NextResponse } from 'next/server';
import { getFixedSession, setFixedSession, clearFixedSession, getAllFixedSessions } from '@/lib/project-sessions';
import { loadSettings } from '@/lib/settings';
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
import { join } from 'node:path';

// GET: get fixed session for a project, or all bindings
export async function GET(req: Request) {
  const url = new URL(req.url);
  const projectPath = url.searchParams.get('projectPath');
  if (projectPath) {
    // Also ensure mcp.json exists when querying
    ensureMcpConfig(projectPath);
    return NextResponse.json({ projectPath, fixedSessionId: getFixedSession(projectPath) || null });
  }
  return NextResponse.json(getAllFixedSessions());
}

// POST: set fixed session or ensure MCP config
export async function POST(req: Request) {
  const body = await req.json();
  const { projectPath, fixedSessionId, action } = body;
  if (!projectPath) return NextResponse.json({ error: 'projectPath required' }, { status: 400 });

  // Ensure MCP config action
  if (action === 'ensure_mcp') {
    ensureMcpConfig(projectPath);
    return NextResponse.json({ ok: true });
  }

  if (!fixedSessionId) {
    clearFixedSession(projectPath);
    return NextResponse.json({ ok: true, cleared: true });
  }
  setFixedSession(projectPath, fixedSessionId);
  return NextResponse.json({ ok: true, projectPath, fixedSessionId });
}

/**
 * Generate the project's MCP config. Two locations:
 *   1. <project>/.forge/mcp.json  — Forge-internal copy, referenced by workspace
 *      orchestrator's --mcp-config flag when it launches agent terminals.
 *   2. <project>/.mcp.json        — picked up automatically by `claude` (and
 *      most other Claude Code-compatible CLIs) when launched at the project
 *      root, so users get Forge MCP tools without needing --mcp-config.
 * Both files have identical content; (1) is authoritative — (2) is a mirror
 * that's only written if it doesn't already exist OR is also a Forge-managed
 * copy (to avoid stomping a user's hand-rolled .mcp.json).
 */
function ensureMcpConfig(projectPath: string): void {
  try {
    const forgeDir = join(projectPath, '.forge');
    const forgeConfigPath = join(forgeDir, 'mcp.json');
    const rootConfigPath = join(projectPath, '.mcp.json');
    const mcpPort = Number(process.env.MCP_PORT) || 8406;

    let wsParam = '';
    try {
      const { findWorkspaceByProject } = require('@/lib/workspace');
      const ws = findWorkspaceByProject(projectPath);
      if (ws) wsParam = `?workspaceId=${ws.id}`;
    } catch {}

    // Built-in Forge MCP server (agent bus, workspace ops)
    const forgeEntry = { type: 'sse', url: `http://localhost:${mcpPort}/sse${wsParam}` };

    // User-managed external MCP servers — chrome-devtools-mcp etc.
    let userServers: Record<string, any> = {};
    try {
      const settings = loadSettings();
      userServers = settings.mcpServers || {};
    } catch {}

    // Forge owns the `forge` key; users can shadow other keys here.
    const config = {
      mcpServers: { forge: forgeEntry, ...userServers },
    };
    const serialized = JSON.stringify(config, null, 2);
    const forgeManagedKeys = new Set(Object.keys(config.mcpServers));

    mkdirSync(forgeDir, { recursive: true });
    writeFileSync(forgeConfigPath, serialized);

    // Mirror to root .mcp.json so plain `claude` in the project picks up
    // Forge's MCP servers. Two policies:
    //   - Don't CREATE the root file. Users who delete it want it gone;
    //     auto-recreating broke that expectation (and pulled global
    //     mcp servers into pipeline worktrees where they don't belong).
    //   - DO update an existing root file IF every server in it is one
    //     we manage — keeps the convenience for users who chose to have it,
    //     without stomping a hand-rolled one.
    if (existsSync(rootConfigPath)) {
      try {
        const existing = JSON.parse(readFileSync(rootConfigPath, 'utf8'));
        const existingKeys = Object.keys(existing?.mcpServers ?? {});
        const allForgeManaged = existingKeys.length > 0 && existingKeys.every(k => forgeManagedKeys.has(k));
        if (allForgeManaged) writeFileSync(rootConfigPath, serialized);
      } catch { /* malformed user file — leave alone */ }
    }
  } catch {}
}
