import { headers } from "next/headers";
import { NextResponse } from "next/server";

import { db } from "@/server/db";
import { cel } from "@/server/db/schemas";
import { and, asc, desc, eq, gte, like, lte, or, sql, type SQL } from "drizzle-orm";

import { auth } from "@/lib/auth/auth";

/**
 * GET /api/reportes/cel
 * Regresa eventos CEL con paginación, filtros y ordenamiento.
 * Puede filtrar por uniqueid para ver el flujo de una llamada específica.
 */
export async function GET(request: Request) {
  try {
    const session = await auth.api.getSession({ headers: await headers() });
    if (!session) {
      return NextResponse.json(
        { success: false, error: "No autorizado" },
        { status: 401 },
      );
    }

    const userRole = (session.user as { role?: string }).role ?? "user";
    if (userRole !== "admin" && userRole !== "superAdmin") {
      return NextResponse.json(
        { success: false, error: "No tienes permisos" },
        { status: 403 },
      );
    }

    const { searchParams } = new URL(request.url);
    const page = parseInt(searchParams.get("page") ?? "1");
    const limit = parseInt(searchParams.get("limit") ?? "20");
    const offset = (page - 1) * limit;

    const search = searchParams.get("search") ?? undefined;
    const uniqueid = searchParams.get("uniqueid") ?? undefined;
    const eventtype = searchParams.get("eventtype") ?? undefined;
    const src = searchParams.get("cid_num") ?? undefined;
    const exten = searchParams.get("exten") ?? undefined;
    const context = searchParams.get("context") ?? undefined;
    const dateFrom = searchParams.get("dateFrom") ?? undefined;
    const dateTo = searchParams.get("dateTo") ?? undefined;
    const sortKeys = [
      "eventtime",
      "eventtype",
      "cid_num",
      "exten",
      "context",
      "appname",
    ] as const;
    type SortKey = (typeof sortKeys)[number];
    const sortByParam = searchParams.get("sortBy") ?? "eventtime";
    const sortBy: SortKey = (sortKeys as readonly string[]).includes(sortByParam)
      ? (sortByParam as SortKey)
      : "eventtime";
    const sortOrder = (searchParams.get("sortOrder") ?? "asc") as
      | "asc"
      | "desc";

    const filters: SQL[] = [];
    if (search) {
      const searchFilter = or(
        like(cel.eventtype, `%${search}%`),
        like(cel.cid_num, `%${search}%`),
        like(cel.exten, `%${search}%`),
        like(cel.context, `%${search}%`),
        like(cel.channame, `%${search}%`),
        like(cel.appname, `%${search}%`),
      );
      if (searchFilter) filters.push(searchFilter);
    }
    if (uniqueid) filters.push(eq(cel.uniqueid, uniqueid));
    if (eventtype) filters.push(eq(cel.eventtype, eventtype));
    if (src) filters.push(like(cel.cid_num, `%${src}%`));
    if (exten) filters.push(like(cel.exten, `%${exten}%`));
    if (context) filters.push(like(cel.context, `%${context}%`));
    if (dateFrom) filters.push(gte(cel.eventtime, dateFrom));
    if (dateTo) filters.push(lte(cel.eventtime, dateTo));

    const sorts = {
      eventtime: cel.eventtime,
      eventtype: cel.eventtype,
      cid_num: cel.cid_num,
      exten: cel.exten,
      context: cel.context,
      appname: cel.appname,
    } as const;

    const selectedSort = sorts[sortBy] ?? cel.eventtime;
    const orderExpr =
      sortOrder === "asc" ? asc(selectedSort) : desc(selectedSort);
    const whereExpr = filters.length > 0 ? and(...filters) : undefined;

    const celData = await db
      .select()
      .from(cel)
      .where(whereExpr)
      .orderBy(orderExpr)
      .limit(limit)
      .offset(offset);

    const totalResult = await db
      .select({ count: sql<number>`count(*)::int` })
      .from(cel)
      .where(whereExpr);

    const total = totalResult[0]?.count ?? 0;
    const totalPages = Math.ceil(total / limit);

    return NextResponse.json({
      success: true,
      data: celData,
      pagination: { page, limit, total, totalPages },
    });
  } catch (error) {
    console.error("[API /reportes/cel] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al obtener registros CEL" },
      { status: 500 },
    );
  }
}
