"use server";

import { redirect } from "next/navigation";
import { z } from "zod";
import { newPasswordSchema } from "@/lib/validation/auth";
import { requireSession } from "@/server/auth/current-user";
import { changeOwnPassword } from "@/server/auth/password-service";
import { getRequestMeta } from "@/server/http/request-meta";

export type ChangePasswordState = { error: string | null };

const changePasswordSchema = z
  .object({
    currentPassword: z.string().min(1, "Ingresa tu contraseña actual").max(128),
    newPassword: newPasswordSchema,
    confirmPassword: z.string(),
  })
  .refine((data) => data.newPassword === data.confirmPassword, {
    message: "La confirmación no coincide con la nueva contraseña.",
    path: ["confirmPassword"],
  });

const ERRORS = {
  WRONG_CURRENT: "La contraseña actual no es correcta.",
  SAME_AS_CURRENT: "La nueva contraseña debe ser distinta de la actual.",
} as const;

export async function changePasswordAction(
  _prev: ChangePasswordState,
  formData: FormData,
): Promise<ChangePasswordState> {
  const session = await requireSession();
  const parsed = changePasswordSchema.safeParse({
    currentPassword: formData.get("currentPassword"),
    newPassword: formData.get("newPassword"),
    confirmPassword: formData.get("confirmPassword"),
  });
  if (!parsed.success) {
    return { error: parsed.error.issues[0]?.message ?? "Datos inválidos." };
  }

  const meta = await getRequestMeta();
  const result = await changeOwnPassword({
    userId: session.user.id,
    currentSessionId: session.sessionId,
    currentPassword: parsed.data.currentPassword,
    newPassword: parsed.data.newPassword,
    ...meta,
  });
  if (!result.ok) return { error: ERRORS[result.code] };

  redirect("/admin");
}
