import { wrapAsyncHandler } from "@batch-cooking/express-tools";
import { adminLoginSchema } from "@batch-cooking/shared";
import { type CookieOptions, type Response, Router } from "express";
import { env } from "../../config/env.js";
import { type AdminLocals, requireAdmin } from "../../middlewares/require-admin.js";
import { adminLogin } from "./admin-auth.service.js";

/** Router mounted at `/admin/auth` (via `admin.routes.ts`) — admin login, logout, current-admin. No signup: admins are created out-of-band (`src/scripts/create-admin.ts`). */
export const adminAuthRouter = Router();

const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;

/**
 * Cookie options for the admin session — same shape as `auth.routes.ts`'s
 * end-user cookie (httpOnly, `Secure` in production unless `COOKIE_SECURE`
 * overrides, `SameSite=Lax`), just written under {@link env.ADMIN_COOKIE_NAME}
 * so the two sessions never collide in one browser.
 */
const adminCookieOptions: CookieOptions = {
  httpOnly: true,
  secure: env.COOKIE_SECURE ?? env.NODE_ENV === "production",
  sameSite: "lax",
  maxAge: SEVEN_DAYS_MS,
};

// `res.clearCookie` sets its own expiry — passing `maxAge` alongside is
// deprecated as of Express 4.20, so the logout route reuses the options
// minus that one field (same trick as `auth.routes.ts`).
const { maxAge: _maxAge, ...clearAdminCookieOptions } = adminCookieOptions;

/** Verifies admin credentials and starts an admin session. */
adminAuthRouter.post(
  "/login",
  wrapAsyncHandler(async (req, res) => {
    const input = adminLoginSchema.parse(req.body);
    const { admin, token } = await adminLogin(input);
    res.cookie(env.ADMIN_COOKIE_NAME, token, adminCookieOptions);
    res.status(200).json(admin);
  }),
);

/** Ends the admin session by clearing the cookie. Stateless JWT — nothing to revoke server-side beyond bumping `tokenVersion` (no UI for that yet). */
adminAuthRouter.post("/logout", (_req, res) => {
  res.clearCookie(env.ADMIN_COOKIE_NAME, clearAdminCookieOptions);
  res.status(204).end();
});

/** Returns the currently authenticated admin. Behind `requireAdmin` — 401s if there's no valid admin session. */
adminAuthRouter.get("/me", requireAdmin, (_req, res: Response<unknown, AdminLocals>) => {
  res.status(200).json(res.locals.adminUser);
});
