import { db } from "@/app/db/db";
import { NextRequest, NextResponse } from "next/server";
import { portfolioInvitations } from "@/app/db/schema/portfolio";
import { and, eq } from "drizzle-orm";
import { z } from "zod";
import { getServerSession } from "next-auth";
import { AuthOptions } from "@/app/api/auth/[...nextauth]/authOptions";
import { denyIfNotAdmin } from "@/app/lib/resolvePortfolioPrivilege";

// GET: list pending invitations for a portfolio. Invitations are consumed
// (deleted) when the invitee signs in, so anything returned here is still
// pending.
export async function GET(
  _req: NextRequest,
  props: { params: Promise<{ portfolioId: string }> },
) {
  const { portfolioId } = await props.params;

  const session = await getServerSession(AuthOptions);
  const denied = await denyIfNotAdmin(BigInt(portfolioId), session);
  if (denied) return denied;

  try {
    const pId = BigInt(portfolioId);
    const rows = await db
      .select({
        id: portfolioInvitations.id,
        email: portfolioInvitations.email,
        role: portfolioInvitations.role,
        createdAt: portfolioInvitations.createdAt,
      })
      .from(portfolioInvitations)
      .where(eq(portfolioInvitations.portfolioId, pId));

    const invitations = rows.map((r) => ({
      invitationId: r.id.toString(),
      email: r.email,
      role: r.role,
      createdAt: r.createdAt.toISOString(),
    }));

    return NextResponse.json({ invitations }, { status: 200 });
  } catch (err) {
    console.error("GET /invitations error:", err);
    return NextResponse.json(
      { error: "Failed to fetch invitations" },
      { status: 500 },
    );
  }
}

// DELETE: revoke a pending invitation. Idempotent — 404 if it's already
// been consumed or revoked.
export async function DELETE(
  req: NextRequest,
  props: { params: Promise<{ portfolioId: string }> },
) {
  const { portfolioId } = await props.params;

  const session = await getServerSession(AuthOptions);
  const denied = await denyIfNotAdmin(BigInt(portfolioId), session);
  if (denied) return denied;

  const bodySchema = z.object({ invitationId: z.string() });
  let body: z.infer<typeof bodySchema>;
  try {
    body = bodySchema.parse(await req.json());
  } catch {
    return NextResponse.json({ error: "Invalid body" }, { status: 400 });
  }

  try {
    const pId = BigInt(portfolioId);
    const invId = BigInt(body.invitationId);

    const result = await db
      .delete(portfolioInvitations)
      .where(
        and(
          eq(portfolioInvitations.id, invId),
          eq(portfolioInvitations.portfolioId, pId),
        ),
      )
      .returning({ id: portfolioInvitations.id });

    if (result.length === 0) {
      return NextResponse.json(
        { error: "Invitation not found in this portfolio" },
        { status: 404 },
      );
    }

    return NextResponse.json(
      { success: true, invitationId: body.invitationId },
      { status: 200 },
    );
  } catch (err) {
    console.error("DELETE /invitations error:", err);
    return NextResponse.json(
      { error: "Failed to revoke invitation" },
      { status: 500 },
    );
  }
}
