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

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

// ── POST /api/marketplace/[id]/fork — fork a template into user projects ────

export async function POST(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: listingId } = await context.params;

    // Fetch the marketplace listing
    const listing = await db.query.marketplaceListings.findFirst({
      where: and(
        eq(marketplaceListings.id, listingId),
        eq(marketplaceListings.status, 'published'),
      ),
    });
    if (!listing) {
      return NextResponse.json(
        { error: 'Marketplace listing not found' },
        { status: 404 },
      );
    }

    // Generate a unique slug (append timestamp if collision)
    let slug = listing.slug;
    const existingProject = await db.query.projects.findFirst({
      where: and(eq(projects.userId, user.id), eq(projects.slug, slug)),
    });
    if (existingProject) {
      slug = `${listing.slug}-${Date.now().toString(36)}`;
    }

    // Create the forked project
    const [newProject] = (await db
      .insert(projects)
      .values({
        userId: user.id,
        teamId: user.teamId,
        name: listing.name,
        slug,
        description: listing.description,
        status: 'draft',
        templateId: listing.id,
      })
      .returning()) as any[];

    // If the listing has a source project, copy its tools
    if (listing.projectId) {
      const sourceTools = await db.query.tools.findMany({
        where: eq(tools.projectId, listing.projectId),
      });

      if (sourceTools.length > 0) {
        await db.insert(tools).values(
          sourceTools.map((t) => ({
            projectId: newProject.id,
            name: t.name,
            description: t.description,
            groupName: t.groupName,
            inputSchema: t.inputSchema,
            outputSchema: t.outputSchema,
            annotations: t.annotations,
            enabled: t.enabled,
            position: t.position,
            canvasX: t.canvasX,
            canvasY: t.canvasY,
          })),
        );
      }
    }

    // Increment fork count on the listing
    await db
      .update(marketplaceListings)
      .set({
        forkCount: sql`${marketplaceListings.forkCount} + 1`,
      })
      .where(eq(marketplaceListings.id, listingId));

    // Fetch the full project with tools for the response
    const result = await db.query.projects.findFirst({
      where: eq(projects.id, newProject.id),
      with: {
        tools: true,
        apps: true,
      },
    });

    return NextResponse.json({ data: result }, { status: 201 });
  } catch (error) {
    console.error('[POST /api/marketplace/[id]/fork]', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 },
    );
  }
}
