"use server";

import { redirect } from "next/navigation";
import { loginSchema } from "@/lib/validation/auth";
import { safeAdminRedirect } from "@/lib/security/safe-redirect";
import { LOGIN_ERROR_MESSAGES, login, logout } from "@/server/auth/login-service";
import {
  clearSessionCookie,
  readSessionCookie,
  setSessionCookie,
} from "@/server/auth/session-cookie";
import { getRequestMeta } from "@/server/http/request-meta";

export type LoginFormState = {
  error: string | null;
  fieldErrors: { email?: string; password?: string };
  email: string;
};

/**
 * Login desde el formulario /admin/login.
 * Next.js valida que el Origin de la Server Action coincida con el Host (protección CSRF).
 */
export async function loginAction(
  _prev: LoginFormState,
  formData: FormData,
): Promise<LoginFormState> {
  const rawEmail = formData.get("email");
  const parsed = loginSchema.safeParse({
    email: rawEmail,
    password: formData.get("password"),
  });
  const echoedEmail = typeof rawEmail === "string" ? rawEmail.slice(0, 254) : "";

  if (!parsed.success) {
    const fieldErrors: LoginFormState["fieldErrors"] = {};
    for (const issue of parsed.error.issues) {
      const field = issue.path[0];
      if ((field === "email" || field === "password") && !fieldErrors[field]) {
        fieldErrors[field] = issue.message;
      }
    }
    return { error: null, fieldErrors, email: echoedEmail };
  }

  const meta = await getRequestMeta();
  const result = await login({
    email: parsed.data.email,
    password: parsed.data.password,
    ip: meta.ip,
    userAgent: meta.userAgent,
    currentToken: await readSessionCookie(),
  });

  if (!result.ok) {
    return { error: LOGIN_ERROR_MESSAGES[result.code], fieldErrors: {}, email: echoedEmail };
  }

  await setSessionCookie(result.token, result.expiresAt);
  const next = formData.get("next");
  redirect(safeAdminRedirect(typeof next === "string" ? next : null));
}

export async function logoutAction(): Promise<void> {
  const token = await readSessionCookie();
  if (token) {
    await logout(token, await getRequestMeta());
  }
  await clearSessionCookie();
  redirect("/admin/login?logout=1");
}
