import { headers } from "next/headers";
import { NextResponse } from "next/server";

import { db } from "@/server/db";
import { cdr } 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/cdr
 * Regresa registros CDR con paginación, filtros y ordenamiento.
 * Accesible para roles admin y superAdmin.
 */
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") ?? "15");
    const offset = (page - 1) * limit;

    const search = searchParams.get("search") ?? undefined;
    const src = searchParams.get("src") ?? undefined;
    const dst = searchParams.get("dst") ?? undefined;
    const accountcode = searchParams.get("accountcode") ?? undefined;
    const disposition = searchParams.get("disposition") ?? undefined;
    const dateFrom = searchParams.get("dateFrom") ?? undefined; // ISO string
    const dateTo = searchParams.get("dateTo") ?? undefined; // ISO string
    const sortBy = searchParams.get("sortBy") ?? "calldate";
    const sortOrder = (searchParams.get("sortOrder") ?? "desc") as
      | "asc"
      | "desc";

    const filters: SQL[] = [];

    if (search) {
      const searchFilter = or(
        like(cdr.src, `%${search}%`),
        like(cdr.dst, `%${search}%`),
        like(cdr.accountcode, `%${search}%`),
        like(cdr.disposition, `%${search}%`),
      );
      if (searchFilter) filters.push(searchFilter);
    }
    if (src) filters.push(like(cdr.src, `%${src}%`));
    if (dst) filters.push(like(cdr.dst, `%${dst}%`));
    if (accountcode) filters.push(like(cdr.accountcode, `%${accountcode}%`));
    if (disposition) filters.push(eq(cdr.disposition, disposition));
    if (dateFrom) filters.push(gte(cdr.calldate, dateFrom));
    if (dateTo) filters.push(lte(cdr.calldate, dateTo));

    const sorts = {
      calldate: cdr.calldate,
      duration: cdr.duration,
      billsec: cdr.billsec,
      src: cdr.src,
      dst: cdr.dst,
      accountcode: cdr.accountcode,
      disposition: cdr.disposition,
    } as const;

    const selectedSort = (sortBy in sorts) ? sorts[sortBy as keyof typeof sorts] : cdr.calldate;

    const orderExpr =
      sortOrder === "asc" ? asc(selectedSort) : desc(selectedSort);

    const whereExpr = filters.length > 0 ? and(...filters) : undefined;

    const cdrData = await db
      .select()
      .from(cdr)
      .where(whereExpr)
      .orderBy(orderExpr)
      .limit(limit)
      .offset(offset);

    const totalResult = await db
      .select({ count: sql<number>`count(*)::int` })
      .from(cdr)
      .where(whereExpr);

    const total = totalResult[0]?.count ?? 0;
    const totalPages = Math.ceil(total / limit);

    return NextResponse.json({
      success: true,
      data: cdrData,
      pagination: { page, limit, total, totalPages },
    });
  } catch (error) {
    console.error("[API /reportes/cdr] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al obtener registros CDR" },
      { status: 500 },
    );
  }
}
