import { redirect } from "next/navigation";

import { AuthTokenType, UserStatus } from "@prisma/client";

import { Button, PageHeader, SectionCard } from "@/components/ui";
import { consumeAuthToken } from "@/lib/auth-tokens";
import { hashPassword } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { getRequestAuditContext, writeAuditTrail } from "@/lib/audit";

async function acceptInvite(formData: FormData) {
  "use server";

  const requestContext = await getRequestAuditContext();
  const tokenRaw = formData.get("token");
  const token = typeof tokenRaw === "string" ? tokenRaw.trim() : "";
  const fullNameRaw = formData.get("fullName");
  const fullName = typeof fullNameRaw === "string" ? fullNameRaw.trim() : "";
  const passwordRaw = formData.get("password");
  const password = typeof passwordRaw === "string" ? passwordRaw : "";
  const confirmRaw = formData.get("confirmPassword");
  const confirmPassword = typeof confirmRaw === "string" ? confirmRaw : "";

  if (!token || !fullName || !password || !confirmPassword) {
    redirect(`/invite/${encodeURIComponent(token)}?error=missing_fields`);
  }

  if (password !== confirmPassword) {
    redirect(`/invite/${encodeURIComponent(token)}?error=password_mismatch`);
  }

  const resolvedToken = await consumeAuthToken(token, AuthTokenType.INVITE_ACCEPTANCE);
  if (!resolvedToken.valid) {
    redirect(
      `/invite/${encodeURIComponent(token)}?error=${resolvedToken.reason === "expired" ? "expired_token" : "invalid_token"}`
    );
  }

  const user = await prisma.user.findUnique({
    where: { id: resolvedToken.token.userId }
  });

  if (!user || user.status !== UserStatus.INVITED) {
    redirect(`/invite/${encodeURIComponent(token)}?error=invalid_token`);
  }

  await prisma.$transaction([
    prisma.user.update({
      where: { id: user.id },
      data: {
        fullName,
        passwordHash: await hashPassword(password),
        status: UserStatus.ACTIVE
      }
    }),
    prisma.authToken.update({
      where: { id: resolvedToken.token.id },
      data: { consumedAt: new Date() }
    })
  ]);

  await writeAuditTrail({
    tenantId: user.tenantId,
    actorUserId: user.id,
    entityType: "user",
    entityId: user.id,
    action: "user_invite_accepted",
    metadata: {
      fullName,
      email: user.email
    },
    ipAddress: requestContext.ipAddress,
    userAgent: requestContext.userAgent
  });

  redirect("/login?success=invite_accepted");
}

export default async function InvitationPage({
  params,
  searchParams
}: {
  params: Promise<{ token: string }>;
  searchParams?: Promise<{ error?: string }>;
}) {
  const { token } = await params;
  const paramsData = await (searchParams ?? Promise.resolve({ error: undefined }));
  const error = paramsData?.error;

  const resolvedToken = await consumeAuthToken(token, AuthTokenType.INVITE_ACCEPTANCE);
  const isTokenValid = resolvedToken.valid;

  const tokenInvalidMessage = error === "expired_token" ? "Token undangan sudah kedaluwarsa." : error === "invalid_token" ? "Link undangan tidak valid." : error === "missing_fields" ? "Lengkapi data nama dan password." : error === "password_mismatch" ? "Password tidak cocok." : null;

  return (
    <main className="min-h-screen bg-background px-6 py-16">
      <div className="mx-auto w-full max-w-2xl rounded-[1.5rem] bg-surface-container-lowest p-4 shadow-card md:p-8">
        <PageHeader title="Accept invitation" description="Selesaikan setup akun awal sebelum masuk ke dashboard." />
        <div className="mt-8">
          <SectionCard title="Invitation setup">
            {!isTokenValid || tokenInvalidMessage ? (
              <p className="mb-4 rounded-xl border border-error-container bg-error-container p-3 text-sm text-on-error-container">
                {tokenInvalidMessage || "Link undangan tidak valid atau sudah kedaluwarsa."}
              </p>
            ) : null}
            {isTokenValid ? (
              <form action={acceptInvite} className="grid gap-4">
                <input type="hidden" name="token" value={token} />
                <label className="text-sm font-medium text-on-surface-variant">
                  Full name
                  <input
                    name="fullName"
                    required
                    className="mt-2 w-full rounded-full border border-line bg-surface-container-high px-4 py-3 text-sm outline-none ring-1 ring-transparent transition focus:ring-primary"
                  />
                </label>
                <label className="text-sm font-medium text-on-surface-variant">
                  Password
                  <input
                    name="password"
                    type="password"
                    required
                    className="mt-2 w-full rounded-full border border-line bg-surface-container-high px-4 py-3 text-sm outline-none ring-1 ring-transparent transition focus:ring-primary"
                  />
                </label>
                <label className="text-sm font-medium text-on-surface-variant">
                  Confirm password
                  <input
                    name="confirmPassword"
                    type="password"
                    required
                    className="mt-2 w-full rounded-full border border-line bg-surface-container-high px-4 py-3 text-sm outline-none ring-1 ring-transparent transition focus:ring-primary"
                  />
                </label>
                <div className="mt-4">
                  <Button type="submit">Accept invitation</Button>
                </div>
              </form>
            ) : (
              <Button href="/login">Kembali ke login</Button>
            )}
          </SectionCard>
        </div>
      </div>
    </main>
  );
}
