/**
 * GET /api/debug?token=<DEBUG_TOKEN>
 *
 * Endpoint de diagnóstico protegido. Retorna:
 *  - Estado de la conexión a la BD (test en vivo)
 *  - Variables de entorno relevantes (sin exponer valores sensibles)
 *  - Logs capturados en memoria
 *  - Info del proceso Node.js
 */

import { NextRequest, NextResponse } from "next/server";
import logger from "@/lib/logger";
import { db } from "@/lib/db";
import { curso } from "@/db/schema";
import { count, sql } from "drizzle-orm";

export const dynamic = "force-dynamic";

export async function GET(req: NextRequest) {
  const { searchParams } = req.nextUrl;

  // ── Validación del token ────────────────────────────────────────────────
  const debugToken = process.env.DEBUG_TOKEN;
  if (!debugToken) {
    return NextResponse.json(
      { error: "Debug no habilitado. Define DEBUG_TOKEN en las vars de entorno de cPanel." },
      { status: 403 }
    );
  }

  const token = searchParams.get("token");
  if (token !== debugToken) {
    return NextResponse.json({ error: "Token invalido." }, { status: 401 });
  }

  const levelFilter = searchParams.get("level")?.toUpperCase();
  const ctxFilter   = searchParams.get("ctx")?.toLowerCase();
  const limitParam  = parseInt(searchParams.get("limit") || "200", 10);
  const doClear     = searchParams.get("clear") === "1";

  // ── Test de conexión a la BD en VIVO ─────────────────────────────────────
  let dbStatus: {
    ok: boolean;
    message: string;
    tables?: string[];
    durationMs?: number;
    error?: string;
  } = { ok: false, message: "No probado" };

  try {
    const t0 = Date.now();

    // Query mínima: contar cursos (confirma conexión Y que la tabla existe)
    const countResult = await db.select({ count: count() }).from(curso);
    const cursoCount = countResult[0]?.count || 0;

    // También lista tablas del schema para diagnóstico
    // Usando execute de Drizzle para raw queries
    const tablesRaw = await db.execute(
      sql`SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME`
    );

    const tables = (tablesRaw as any).rows || [];
    dbStatus = {
      ok: true,
      message: `Conexion exitosa. Cursos en BD: ${cursoCount}`,
      tables: tables.map((r: { TABLE_NAME: string }) => r.TABLE_NAME),
      durationMs: Date.now() - t0,
    };

    logger.info("debug", `DB test OK — ${cursoCount} cursos`, { durationMs: dbStatus.durationMs });
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : String(err);
    dbStatus = { ok: false, message: "Fallo de conexion", error: msg };
    logger.error("debug", "DB test FALLO", err);
  }

  // ── Variables de entorno (solo estado, no valores) ────────────────────────
  const envStatus = {
    NODE_ENV:         process.env.NODE_ENV || "(no definida)",
    DATABASE_URL:     process.env.DATABASE_URL
                        ? "✅ definida (" + (process.env.DATABASE_URL.replace(/:([^@:]+)@/, ":***@")) + ")"
                        : "❌ NO definida",
    NEXTAUTH_URL:     process.env.NEXTAUTH_URL     || "❌ NO definida",
    NEXTAUTH_SECRET:  process.env.NEXTAUTH_SECRET  ? "✅ definida" : "❌ NO definida",
    DEBUG_TOKEN:      process.env.DEBUG_TOKEN       ? "✅ definida" : "❌ NO definida",
    CLOUDINARY_CLOUD: process.env.CLOUDINARY_CLOUD_NAME || "(no definida)",
  };

  // ── Info del proceso ──────────────────────────────────────────────────────
  const processInfo = {
    pid:       process.pid,
    nodeVersion: process.version,
    platform:  process.platform,
    arch:      process.arch,
    uptimeSeconds: Math.round(process.uptime()),
    memoryMB: {
      rss:      Math.round(process.memoryUsage().rss / 1024 / 1024),
      heapUsed: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
      heapTotal:Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
    },
    cwd: process.cwd(),
  };

  // ── Logs del buffer ───────────────────────────────────────────────────────
  let logs = logger.getLogs();
  if (levelFilter) logs = logs.filter((l) => l.level === levelFilter);
  if (ctxFilter)   logs = logs.filter((l) => l.ctx.toLowerCase().includes(ctxFilter));
  logs = logs.slice(0, limitParam);

  if (doClear) logger.clear();

  return NextResponse.json(
    {
      ok: true,
      ts: new Date().toISOString(),
      db: dbStatus,
      env: envStatus,
      process: processInfo,
      logsTotal: logs.length,
      logsCleared: doClear,
      logs,
    },
    { headers: { "Cache-Control": "no-store" } }
  );
}
