/**
 * MCPEngine Studio — Deploy API Route
 *
 * POST /api/deploy
 * Accepts { projectId, target, config }
 * Loads project bundle from DB, runs deploy pipeline,
 * streams progress via SSE, saves deployment record on completion.
 */

import { NextRequest, NextResponse } from 'next/server';
import { deploy } from '@/lib/deploy';
import type {
  DeployTarget,
  DeployConfig,
  ServerBundle,
} from '@mcpengine/ai-pipeline/types';

// ---------------------------------------------------------------------------
// POST /api/deploy — Start deployment (SSE stream)
// ---------------------------------------------------------------------------

export async function POST(req: NextRequest) {
  try {
    const body = await req.json();
    const { projectId, target, config } = body as {
      projectId: string;
      target: DeployTarget;
      config?: Partial<DeployConfig>;
    };

    if (!projectId) {
      return NextResponse.json(
        { error: 'projectId is required' },
        { status: 400 },
      );
    }

    if (!target) {
      return NextResponse.json(
        { error: 'target is required' },
        { status: 400 },
      );
    }

    // ── Load project from DB ─────────────────────────────────────────────
    // TODO: Replace with real DB query using drizzle
    // import { db } from '@/lib/db';
    // import { projects, deployments } from '@mcpengine/db/schema';
    // import { eq } from 'drizzle-orm';
    // const project = await db.query.projects.findFirst({
    //   where: eq(projects.id, projectId),
    // });

    // For now, create a mock bundle if no DB yet
    const bundle: ServerBundle = await loadProjectBundle(projectId);

    if (!bundle || !bundle.files.length) {
      return NextResponse.json(
        { error: 'Project has no server bundle. Generate code first.' },
        { status: 400 },
      );
    }

    // ── Build deploy config ──────────────────────────────────────────────
    const deployConfig: DeployConfig = {
      target,
      slug: config?.slug ?? projectId.slice(0, 12),
      envVars: config?.envVars ?? {},
      customDomain: config?.customDomain,
    };

    // ── Stream deploy events via SSE ─────────────────────────────────────
    const encoder = new TextEncoder();

    const stream = new ReadableStream({
      async start(controller) {
        try {
          const pipeline = deploy(bundle, deployConfig);
          let deployResult;

          for await (const event of pipeline) {
            const sseData = `data: ${JSON.stringify(event)}\n\n`;
            controller.enqueue(encoder.encode(sseData));

            if (event.type === 'complete' && event.result) {
              deployResult = event.result;
            }
          }

          // ── Save deployment record to DB ─────────────────────────────
          if (deployResult) {
            await saveDeploymentRecord(projectId, deployResult);

            // Send final event with saved record
            const finalEvent = {
              type: 'saved',
              message: 'Deployment record saved',
              percent: 100,
              level: 'success',
              timestamp: new Date().toISOString(),
              result: deployResult,
            };
            controller.enqueue(
              encoder.encode(`data: ${JSON.stringify(finalEvent)}\n\n`),
            );
          }

          controller.close();
        } catch (error) {
          const errMsg =
            error instanceof Error ? error.message : 'Unknown error';
          const errorEvent = {
            type: 'error',
            message: errMsg,
            percent: 0,
            level: 'error',
            timestamp: new Date().toISOString(),
          };
          controller.enqueue(
            encoder.encode(`data: ${JSON.stringify(errorEvent)}\n\n`),
          );
          controller.close();
        }
      },
    });

    return new Response(stream, {
      headers: {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        Connection: 'keep-alive',
        'X-Accel-Buffering': 'no',
      },
    });
  } catch (error) {
    console.error('Deploy route error:', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 },
    );
  }
}

// ---------------------------------------------------------------------------
// Helpers — TODO: Replace with real DB operations
// ---------------------------------------------------------------------------

async function loadProjectBundle(projectId: string): Promise<ServerBundle> {
  // TODO: Real implementation:
  // const project = await db.query.projects.findFirst({
  //   where: eq(projects.id, projectId),
  // });
  // return project?.serverBundle as ServerBundle;

  // Mock bundle for development
  return {
    files: [
      {
        path: 'index.ts',
        content: `
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server({ name: 'mcp-server', version: '1.0.0' }, {
  capabilities: { tools: {} },
});

export const listTools = () => [];
export const callTool = async (name, args) => ({ content: [{ type: 'text', text: 'OK' }] });
`,
        language: 'typescript',
      },
    ],
    packageJson: { name: 'mcp-server', version: '1.0.0' },
    tsConfig: {},
    entryPoint: 'index.ts',
    toolCount: 0,
  };
}

async function saveDeploymentRecord(
  projectId: string,
  result: any,
): Promise<void> {
  // TODO: Real implementation:
  // await db.insert(deployments).values({
  //   projectId,
  //   userId: currentUser.id,  // from auth context
  //   target: result.target,
  //   status: result.status,
  //   url: result.url,
  //   endpoint: result.endpoint,
  //   logs: result.logs,
  // });

  console.log('[deploy] Saved deployment record:', {
    projectId,
    deployId: result.id,
    target: result.target,
    status: result.status,
    url: result.url,
  });
}
