import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@clerk/nextjs/server';
import { db, projects, users, tools, apps, apiKeys, deployments } from '@mcpengine/db';
import { eq, and } from 'drizzle-orm';

type RouteContext = { params: Promise<{ id: string }> };

// ── GET /api/projects/[id] — project detail with tools + apps ───────────────

export async function GET(req: NextRequest, context: RouteContext) {
  try {
    const { userId: clerkId } = await auth();
    if (!clerkId) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const user = await db.query.users.findFirst({
      where: eq(users.clerkId, clerkId),
    });
    if (!user) {
      return NextResponse.json({ error: 'User not found' }, { status: 404 });
    }

    const { id } = await context.params;

    const project = await db.query.projects.findFirst({
      where: and(eq(projects.id, id), eq(projects.userId, user.id)),
      with: {
        tools: true,
        apps: true,
        deployments: {
          orderBy: (d: any, { desc }: any) => [desc(d.createdAt)],
          limit: 5,
        },
      },
    });

    if (!project) {
      return NextResponse.json({ error: 'Project not found' }, { status: 404 });
    }

    return NextResponse.json({ data: project });
  } catch (error) {
    console.error('[GET /api/projects/[id]]', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 },
    );
  }
}

// ── PATCH /api/projects/[id] — update project ──────────────────────────────

export async function PATCH(req: NextRequest, context: RouteContext) {
  try {
    const { userId: clerkId } = await auth();
    if (!clerkId) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const user = await db.query.users.findFirst({
      where: eq(users.clerkId, clerkId),
    });
    if (!user) {
      return NextResponse.json({ error: 'User not found' }, { status: 404 });
    }

    const { id } = await context.params;

    // Verify ownership
    const existing = await db.query.projects.findFirst({
      where: and(eq(projects.id, id), eq(projects.userId, user.id)),
    });
    if (!existing) {
      return NextResponse.json({ error: 'Project not found' }, { status: 404 });
    }

    const body = await req.json();

    // Whitelist updatable fields
    const allowedFields = [
      'name',
      'description',
      'status',
      'specUrl',
      'specRaw',
      'analysis',
      'toolConfig',
      'appConfig',
      'authConfig',
      'serverBundle',
    ] as const;

    const updates: Record<string, unknown> = { updatedAt: new Date() };

    for (const field of allowedFields) {
      if (body[field] !== undefined) {
        updates[field] = body[field];
      }
    }

    const [updated] = (await db
      .update(projects)
      .set(updates)
      .where(and(eq(projects.id, id), eq(projects.userId, user.id)))
      .returning()) as any[];

    return NextResponse.json({ data: updated });
  } catch (error) {
    console.error('[PATCH /api/projects/[id]]', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 },
    );
  }
}

// ── DELETE /api/projects/[id] — delete project + cascade ────────────────────

export async function DELETE(req: NextRequest, context: RouteContext) {
  try {
    const { userId: clerkId } = await auth();
    if (!clerkId) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const user = await db.query.users.findFirst({
      where: eq(users.clerkId, clerkId),
    });
    if (!user) {
      return NextResponse.json({ error: 'User not found' }, { status: 404 });
    }

    const { id } = await context.params;

    // Verify ownership
    const existing = await db.query.projects.findFirst({
      where: and(eq(projects.id, id), eq(projects.userId, user.id)),
    });
    if (!existing) {
      return NextResponse.json({ error: 'Project not found' }, { status: 404 });
    }

    // Delete non-cascade relations first
    await db.delete(deployments).where(eq(deployments.projectId, id));

    // tools, apps, apiKeys cascade automatically via FK onDelete
    await db
      .delete(projects)
      .where(and(eq(projects.id, id), eq(projects.userId, user.id)));

    return NextResponse.json({ success: true }, { status: 200 });
  } catch (error) {
    console.error('[DELETE /api/projects/[id]]', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 },
    );
  }
}
