import { NextRequest, NextResponse } from "next/server";
import { eq, and } from "drizzle-orm";
import { db } from "@/db";
import { clients, deliverables, tasks, phases, projects } from "@/db/schema";
import { rateLimit } from "@/lib/rate-limit";

export async function POST(request: NextRequest) {
  const ip = request.headers.get("x-forwarded-for") ?? "unknown";
  if (!rateLimit(`approve:${ip}`, 20, 60_000)) {
    return NextResponse.json({ error: "Troppe richieste" }, { status: 429 });
  }

  try {
    const body = await request.json();
    const { token, deliverableId } = body as { token?: string; deliverableId?: string };

    if (!token || !deliverableId) {
      return NextResponse.json({ error: "token e deliverableId richiesti" }, { status: 400 });
    }

    // Validate token — find the client
    const clientRows = await db
      .select({ id: clients.id })
      .from(clients)
      .where(eq(clients.token, token))
      .limit(1);

    if (clientRows.length === 0) {
      return NextResponse.json({ error: "Accesso non consentito" }, { status: 403 });
    }

    const clientId = clientRows[0].id;

    // Verify deliverable belongs to this client (prevents cross-client approval)
    // deliverable → task → phase → project → client
    const ownershipCheck = await db
      .select({ deliverable_id: deliverables.id, approved_at: deliverables.approved_at })
      .from(deliverables)
      .innerJoin(tasks, eq(deliverables.task_id, tasks.id))
      .innerJoin(phases, eq(tasks.phase_id, phases.id))
      .innerJoin(projects, and(eq(phases.project_id, projects.id), eq(projects.client_id, clientId)))
      .where(eq(deliverables.id, deliverableId))
      .limit(1);

    if (ownershipCheck.length === 0) {
      return NextResponse.json({ error: "Accesso non consentito" }, { status: 403 });
    }

    // IMMUTABILITY RULE (CLAUDE.md): if approved_at is already set, this is a no-op
    if (ownershipCheck[0].approved_at !== null) {
      return NextResponse.json({ approved: true, message: "Già approvato" }, { status: 200 });
    }

    // Set approved — approved_at is immutable once set, client cannot unset it
    await db
      .update(deliverables)
      .set({ status: "approved", approved_at: new Date() })
      .where(eq(deliverables.id, deliverableId));

    return NextResponse.json({ approved: true }, { status: 200 });
  } catch (err) {
    console.error("/api/client/approve error:", err);
    return NextResponse.json({ error: "Errore interno" }, { status: 500 });
  }
}