"use server";

import "server-only";
import { randomBytes } from "crypto";
import { query } from "@/lib/db";
import {
  requestPasswordReset as neonAuthRequestPasswordReset,
  setUserPassword as neonAuthSetUserPassword,
} from "@/lib/auth";
import { getAdminUser } from "@/lib/admin-permissions";

export type ResetAdminPasswordResult =
  | { success: true; tempPassword: string; method: "set" }
  | { success: true; method: "reset_link_sent"; message: string }
  | { success: false; error: string };

/**
 * Emergency recovery action — resets the password for the specified
 * email so the platform admin can hand a working credential to the
 * user.
 *
 * Tries, in order:
 *   1. `auth.admin.setUserPassword({ userId, newPassword })` — instant,
 *      works when the caller has `role='admin'` in `neon_auth.user`.
 *   2. Falls back to `requestPasswordReset({ email, redirectTo })` —
 *      public Neon Auth endpoint, always works, but the user has to
 *      click the link in the email. The fallback covers the common
 *      case where `provision-admin.ts` did not promote the caller to
 *      `role='admin'` in Neon Auth.
 *
 * Authorization: platform_admin only. The dev-session platform_admin
 * shim is honored (same as the rest of the admin actions).
 */
export async function resetAdminPassword(
  email: string,
): Promise<ResetAdminPasswordResult> {
  // 1. Authz check.
  const me = await getAdminUser();
  if (!me) {
    return { success: false, error: "Not authenticated." };
  }
  if (me.role !== "platform_admin") {
    return {
      success: false,
      error: "Only platform admins can reset passwords.",
    };
  }

  const normalizedEmail = email.trim().toLowerCase();
  if (!normalizedEmail) {
    return { success: false, error: "Email is required." };
  }

  // 2. Look up the Neon Auth user id by email.
  const { rows } = await query<{ id: string }>(
    `SELECT id FROM neon_auth.user WHERE email = $1 LIMIT 1`,
    [normalizedEmail],
  );
  const user = rows[0];
  if (!user) {
    return {
      success: false,
      error: `No Neon Auth user found for ${normalizedEmail}.`,
    };
  }

  // 3. Generate a strong temp password server-side. 16 bytes → 32
  //    base64url chars; mix in a symbol so it satisfies typical
  //    password policies.
  const tempPassword = `${randomBytes(18).toString("base64url")}!`;

  // 4. Try the privileged admin endpoint.
  try {
    const adminResult = await neonAuthSetUserPassword({
      userId: user.id,
      newPassword: tempPassword,
    });

    if (adminResult?.error) {
      const code = adminResult.error.code ?? "";
      const canFallback =
        code === "FORBIDDEN" ||
        code === "UNAUTHORIZED" ||
        code === "INTERNAL_SERVER_ERROR";
      console.warn(
        "[resetAdminPassword] setUserPassword failed (code=%s), will%s fall back: %s",
        code,
        canFallback ? "" : " NOT",
        adminResult.error.message ?? "",
      );

      if (!canFallback) {
        return {
          success: false,
          error: adminResult.error.message ?? `setUserPassword failed: ${code}`,
        };
      }
      // fall through to the public reset-link path below
    } else {
      // Success — flip must_change_password so the user is forced
      // to pick a new password on next sign-in.
      try {
        await query(
          `UPDATE admin_users SET must_change_password = true WHERE user_id = $1`,
          [user.id],
        );
      } catch (flagErr) {
        console.warn(
          "[resetAdminPassword] failed to set must_change_password (non-fatal):",
          flagErr,
        );
      }
      return { success: true, tempPassword, method: "set" };
    }
  } catch (err) {
    console.error("[resetAdminPassword] setUserPassword threw:", err);
    // network / unexpected — try the fallback below
  }

  // 5. Fallback: send a password-reset email via the public endpoint.
  try {
    const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:4000";
    const resetResult = await neonAuthRequestPasswordReset({
      email: normalizedEmail,
      redirectTo: `${siteUrl}/reset-password`,
    });

    if (resetResult?.error) {
      return {
        success: false,
        error:
          resetResult.error.message ??
          resetResult.error.code ??
          "Failed to send reset email",
      };
    }

    return {
      success: true,
      method: "reset_link_sent",
      message: `Set-password is not available for this account. Sent a password-reset email to ${normalizedEmail} instead — share that link with the user.`,
    };
  } catch (err) {
    return {
      success: false,
      error: err instanceof Error ? err.message : String(err),
    };
  }
}
