import { createServerFn } from "@tanstack/react-start";
import { useSession } from "@tanstack/react-start/server";
import { redirect } from "@tanstack/react-router";
import { z } from "zod";

const ADMIN_EMAIL = "gregory@gbonfanti.com.br";

type SessionData = {
  email?: string;
};

function getSessionConfig() {
  const adminPassword = process.env.ADMIN_PASSWORD;
  if (!adminPassword) {
    throw new Error("ADMIN_PASSWORD não configurado no servidor.");
  }
  // Password must be >= 32 chars for encryption; pad with fixed app salt.
  const password = (adminPassword + "::x3-sites-proposals-session-salt").padEnd(
    32,
    "0",
  );
  return {
    password,
    name: "x3_admin_session",
    maxAge: 60 * 60 * 24 * 7, // 7 dias
    cookie: {
      httpOnly: true,
      sameSite: "lax" as const,
      secure: true,
      path: "/",
    },
  };
}

export const getSessionFn = createServerFn({ method: "GET" }).handler(
  async () => {
    const session = await useSession<SessionData>(getSessionConfig());
    const email = session.data?.email ?? null;
    return {
      isAuthenticated: Boolean(email && email === ADMIN_EMAIL),
      email,
    };
  },
);

export const loginFn = createServerFn({ method: "POST" })
  .inputValidator((input: unknown) =>
    z
      .object({
        email: z.string().email().max(255),
        password: z.string().min(1).max(255),
      })
      .parse(input),
  )
  .handler(async ({ data }) => {
    const adminPassword = process.env.ADMIN_PASSWORD;
    if (!adminPassword) {
      throw new Error("Servidor não configurado.");
    }
    const emailOk = data.email.trim().toLowerCase() === ADMIN_EMAIL;
    const passOk = data.password === adminPassword;
    if (!emailOk || !passOk) {
      // Generic error to avoid leaking which field failed.
      throw new Error("E-mail ou senha inválidos.");
    }
    const session = await useSession<SessionData>(getSessionConfig());
    await session.update({ email: ADMIN_EMAIL });
    return { success: true as const };
  });

export const logoutFn = createServerFn({ method: "POST" }).handler(async () => {
  const session = await useSession<SessionData>(getSessionConfig());
  await session.clear();
  return { success: true as const };
});

export function requireAuthRedirect(
  isAuthenticated: boolean,
  currentHref: string,
) {
  if (!isAuthenticated) {
    throw redirect({
      to: "/login",
      search: { redirect: currentHref },
    });
  }
}
