import { redirect } from "next/navigation";

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

import { Button, PageHeader, SectionCard } from "@/components/ui";
import { createAuthToken, makeResetUrl } from "@/lib/auth-tokens";
import { getLocale, getTranslator } from "@/lib/i18n";
import { getRequestAuditContext, writeAuditTrail } from "@/lib/audit";
import { consumeRateLimit } from "@/lib/rate-limit";
import { prisma } from "@/lib/prisma";
import { sendTransactionalNotification } from "@/lib/notification";

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

  const requestContext = await getRequestAuditContext();
  const rawEmail = formData.get("email");
  const email = typeof rawEmail === "string" ? rawEmail.trim().toLowerCase() : "";

  const rateLimit = consumeRateLimit(requestContext.ipAddress || "unknown", {
    scope: "password_reset_request",
    limit: 6,
    windowMs: 15 * 60 * 1000
  });
  if (!rateLimit.allowed) {
    redirect("/forgot-password?error=rate_limited");
  }

  if (!email) {
    redirect("/forgot-password?error=missing_email");
  }

  const user = await prisma.user.findUnique({
    where: { email }
  });

  if (user && user.status === UserStatus.ACTIVE) {
    const created = await createAuthToken({
      userId: user.id,
      tenantId: user.tenantId,
      tokenType: AuthTokenType.PASSWORD_RESET
    });
    const resetUrl = makeResetUrl(created.rawToken);
    const notificationResult = await sendTransactionalNotification({
      to: user.email,
      subject: "Reset password to continue your account access",
      text: `Gunakan tautan ini untuk mengatur ulang password: ${resetUrl}`,
      html: `<p>Gunakan tautan berikut untuk mengatur ulang password: <a href="${resetUrl}">${resetUrl}</a></p>`
    });

    if (!notificationResult.ok) {
      await writeAuditTrail({
        tenantId: user.tenantId,
        actorUserId: user.id,
        entityType: "user",
        entityId: user.id,
        action: "password_reset_notified_failed",
        metadata: {
          email,
          reason: notificationResult.error,
          source: "web",
          provider: notificationResult.provider ?? null
        },
        ipAddress: requestContext.ipAddress,
        userAgent: requestContext.userAgent
      });
    }

    await writeAuditTrail({
      tenantId: user.tenantId,
      actorUserId: user.id,
      entityType: "user",
      entityId: user.id,
        action: "password_reset_requested",
        metadata: {
          email,
          expiresAt: created.expiresAt.toISOString(),
          source: "web",
          notifyProvider: notificationResult?.provider ?? null,
          notifyQueued: notificationResult?.ok ?? false
        },
      ipAddress: requestContext.ipAddress,
      userAgent: requestContext.userAgent
    });
    if (notificationResult.ok === true && notificationResult.provider === "console") {
      console.log(`RESET_PASSWORD_LINK=${resetUrl}`);
    }
  } else if (user) {
    await writeAuditTrail({
      tenantId: user.tenantId,
      actorUserId: user.id,
      entityType: "user",
      entityId: user.id,
      action: "password_reset_denied",
      metadata: {
        email,
        status: user.status,
        source: "web"
      },
      ipAddress: requestContext.ipAddress,
      userAgent: requestContext.userAgent
    });
  }

  // Always respond with generic success to avoid user enumeration.
  redirect("/forgot-password?success=sent");
}

export default async function ForgotPasswordPage({
  searchParams
}: {
  searchParams?: Promise<{ error?: string; success?: string }>;
}) {
  const t = getTranslator(await getLocale());
  const params = await (searchParams ?? Promise.resolve({ error: undefined, success: undefined }));
  const error =
    params?.error === "missing_email"
      ? t("login", "missing_email")
      : params?.error === "rate_limited"
        ? t("login", "error_rate_limited")
        : null;

  const success = params?.success === "sent";

  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={t("pages", "forgot_password")}
          description={t("pages", "reset_password")}
          actions={<Button href="/login" variant="secondary">{t("common", "back_to_login")}</Button>}
        />
        <div className="mt-8">
          <SectionCard title={t("pages", "reset_password")}>
            {error ? (
              <p className="mb-4 rounded-xl border border-error-container bg-error-container p-3 text-sm text-on-error-container">
                {error}
              </p>
            ) : null}
            {success ? (
              <p className="mb-4 rounded-xl border border-success/30 bg-success/10 p-3 text-sm text-success">
                {t("login", "forgot_success")}
              </p>
            ) : null}
            <form action={requestPasswordReset} className="grid gap-4">
              <label className="block text-sm font-medium text-on-surface-variant">
                {t("login", "email_label")}
                <input
                  name="email"
                  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"
                  placeholder={t("login", "work_email_placeholder")}
                  required
                />
              </label>
              <div />
              <div className="mt-4">
                <Button type="submit">{t("login", "forgot_action")}</Button>
              </div>
            </form>
          </SectionCard>
        </div>
      </div>
    </main>
  );
}
