import { getServerSession } from "next-auth/next";
import { redirect } from "next/navigation";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import AdminPrintTicketsClient, {
  type PrintTicketRow,
} from "@/components/AdminPrintTicketsClient";
import {
  PRINT_TICKETS_MAX,
  PRINT_TICKETS_MAX_RANGE_DAYS,
  formatPrintDateTime,
  parseLocalDateParam,
  sanitizePrintEmail,
  sanitizePrintName,
  sanitizePrintPhone,
  sanitizePrintSearchQuery,
  sanitizeTicketNum,
  toLocalISODate,
} from "@/lib/print-tickets-safe";

export const dynamic = "force-dynamic";
export const revalidate = 0;

type PageProps = {
  searchParams?: Promise<{ from?: string; to?: string; q?: string }>;
};

export default async function AdminPrintTicketsPage({ searchParams }: PageProps) {
  const session = await getServerSession(authOptions);
  if (!session?.user || (session.user as { role?: string }).role !== "ADMIN") {
    redirect("/");
  }

  const params = (await searchParams) ?? {};
  const today = new Date();
  today.setHours(0, 0, 0, 0);

  // Por defecto: últimos 30 días (así al entrar ya se ven tickets recientes)
  const defaultFrom = new Date(today);
  defaultFrom.setDate(defaultFrom.getDate() - 30);

  let from = parseLocalDateParam(params.from) ?? defaultFrom;
  let to = parseLocalDateParam(params.to) ?? today;
  const searchQ = sanitizePrintSearchQuery(params.q);

  // Normalizar: from <= to
  if (from > to) {
    const tmp = from;
    from = to;
    to = tmp;
  }

  // Limitar rango para no exfiltrar años de PII de golpe
  const maxMs = PRINT_TICKETS_MAX_RANGE_DAYS * 24 * 60 * 60 * 1000;
  if (to.getTime() - from.getTime() > maxMs) {
    from = new Date(to.getTime() - maxMs);
    from.setHours(0, 0, 0, 0);
  }

  const fromStart = new Date(from);
  fromStart.setHours(0, 0, 0, 0);
  const toEnd = new Date(to);
  toEnd.setHours(23, 59, 59, 999);

  const phoneDigits = searchQ.replace(/\D/g, "");
  const userFilter =
    searchQ.length > 0
      ? {
          OR: [
            { email: { contains: searchQ, mode: "insensitive" as const } },
            ...(phoneDigits.length >= 3
              ? [{ phone: { contains: phoneDigits } }]
              : []),
          ],
        }
      : undefined;

  const tickets = await prisma.ticket.findMany({
    where: {
      order: {
        status: "PAID",
        createdAt: { gte: fromStart, lte: toEnd },
        ...(userFilter ? { user: userFilter } : {}),
      },
    },
    orderBy: { createdAt: "desc" },
    take: PRINT_TICKETS_MAX,
    include: {
      order: {
        select: {
          id: true,
          createdAt: true,
          user: { select: { name: true, phone: true, email: true } },
        },
      },
    },
  });

  const rows: PrintTicketRow[] = tickets.map((t) => ({
    id: t.id,
    ticketNum: sanitizeTicketNum(t.ticketNum),
    createdAt: t.order.createdAt.toISOString(),
    createdAtLabel: formatPrintDateTime(t.order.createdAt),
    orderId: t.order.id,
    name: sanitizePrintName(t.order.user.name),
    phone: sanitizePrintPhone(t.order.user.phone),
    email: sanitizePrintEmail(t.order.user.email),
  }));

  const truncated = tickets.length >= PRINT_TICKETS_MAX;

  return (
    <AdminPrintTicketsClient
      initialTickets={rows}
      initialFrom={toLocalISODate(fromStart)}
      initialTo={toLocalISODate(to)}
      initialQuery={searchQ}
      truncated={truncated}
      maxTickets={PRINT_TICKETS_MAX}
      maxRangeDays={PRINT_TICKETS_MAX_RANGE_DAYS}
    />
  );
}
