<script lang="ts">
  import { onMount } from 'svelte';
  import { auth } from '$lib/stores/auth.js';
  import { goto } from '$app/navigation';

  onMount(() => {
    if (!$auth.isAuthenticated) goto('/login');
  });

  // ─── Types ──────────────────────────────────────────────────────────────────
  interface EndpointDef {
    id: string;
    label: string;
    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
    path: string;
    description: string;
  }

  interface EndpointResult {
    status: number | null;
    ok: boolean | null;
    ms: number | null;
    error: string | null;
    preview: string | null;
    tested: boolean;
    loading: boolean;
  }

  interface PageDef {
    label: string;
    href: string;
    description: string;
    roles: string[];
  }

  // ─── Backend Endpoints ───────────────────────────────────────────────────────
  const GROUPS: { name: string; color: string; endpoints: EndpointDef[] }[] = [
    {
      name: 'Auth',
      color: 'bg-purple-100 text-purple-800',
      endpoints: [
        { id: 'auth-me',          label: 'Perfil actual',          method: 'GET',  path: '/auth/me',                description: 'Información del usuario autenticado' },
        { id: 'auth-refresh',     label: 'Refrescar token',        method: 'POST', path: '/auth/refresh',           description: 'Renovar access token (POST)' },
      ]
    },
    {
      name: 'Health',
      color: 'bg-green-100 text-green-800',
      endpoints: [
        { id: 'health',          label: 'Health Check',           method: 'GET',  path: '/health',                 description: 'Estado general del sistema' },
        { id: 'health-details',  label: 'Health Detallado',       method: 'GET',  path: '/health/detailed',        description: 'Estado con detalle de dependencias' },
      ]
    },
    {
      name: 'Tenants',
      color: 'bg-blue-100 text-blue-800',
      endpoints: [
        { id: 'tenants-list',    label: 'Listar Tenants',         method: 'GET',  path: '/tenants/',               description: 'Todos los tenants registrados' },
        { id: 'tenant-stats',    label: 'Stats Tenant',           method: 'GET',  path: '/tenants/stats',          description: 'Estadísticas globales de tenants' },
      ]
    },
    {
      name: 'Users',
      color: 'bg-indigo-100 text-indigo-800',
      endpoints: [
        { id: 'users-list',      label: 'Listar Usuarios',        method: 'GET',  path: '/users/',                 description: 'Todos los usuarios del sistema' },
      ]
    },
    {
      name: 'Tickets',
      color: 'bg-orange-100 text-orange-800',
      endpoints: [
        { id: 'tickets-list',    label: 'Listar Tickets',         method: 'GET',  path: '/tickets/',               description: 'Tickets con paginación' },
        { id: 'tickets-stats',   label: 'Stats Tickets',          method: 'GET',  path: '/tickets/stats',          description: 'Estadísticas de tickets' },
        { id: 'tickets-comments',label: 'Comentarios recientes',  method: 'GET',  path: '/tickets/comments/recent',description: 'Últimos comentarios' },
      ]
    },
    {
      name: 'Categories',
      color: 'bg-amber-100 text-amber-800',
      endpoints: [
        { id: 'cats-list',       label: 'Listar Categorías',      method: 'GET',  path: '/categories/',            description: 'Categorías de tickets' },
      ]
    },
    {
      name: 'Systems',
      color: 'bg-gray-100 text-gray-800',
      endpoints: [
        { id: 'sys-list',        label: 'Listar Sistemas',        method: 'GET',  path: '/systems/',               description: 'Sistemas soportados' },
      ]
    },
    {
      name: 'SLA',
      color: 'bg-teal-100 text-teal-800',
      endpoints: [
        { id: 'sla-dashboard',   label: 'Dashboard SLA',          method: 'GET',  path: '/sla/dashboard',          description: 'Panel SLA principal' },
        { id: 'sla-compliance',  label: 'SLA Compliance',         method: 'GET',  path: '/sla/compliance',         description: 'Métricas de cumplimiento SLA' },
        { id: 'sla-at-risk',     label: 'Tickets en Riesgo',      method: 'GET',  path: '/sla/at-risk',            description: 'Tickets próximos a violar SLA' },
        { id: 'sla-violations',  label: 'Violaciones SLA',        method: 'GET',  path: '/sla/violations',         description: 'Tickets que violaron SLA' },
      ]
    },
    {
      name: 'Reports',
      color: 'bg-pink-100 text-pink-800',
      endpoints: [
        { id: 'rep-summary',     label: 'Resumen General',        method: 'GET',  path: '/reports/summary',        description: 'Resumen ejecutivo de reportes' },
        { id: 'rep-agents',      label: 'Por Agente',             method: 'GET',  path: '/reports/agents',         description: 'Rendimiento por agente' },
        { id: 'rep-categories',  label: 'Por Categoría',          method: 'GET',  path: '/reports/categories',     description: 'Distribución por categoría' },
        { id: 'rep-trends',      label: 'Tendencias',             method: 'GET',  path: '/reports/trends',         description: 'Tendencias temporales' },
      ]
    },
    {
      name: 'Audit',
      color: 'bg-red-100 text-red-800',
      endpoints: [
        { id: 'audit-logs',      label: 'Logs de Auditoría',      method: 'GET',  path: '/audit/logs',             description: 'Bitácora de acciones' },
        { id: 'audit-stats',     label: 'Stats Auditoría',        method: 'GET',  path: '/audit/stats',            description: 'Estadísticas de auditoría' },
        { id: 'audit-security',  label: 'Análisis Seguridad',     method: 'GET',  path: '/audit/security/analysis',description: 'Análisis de amenazas de seguridad' },
        { id: 'audit-users',     label: 'Actividad Usuarios',     method: 'GET',  path: '/audit/users',            description: 'Actividad por usuario' },
      ]
    },
    {
      name: 'Client Profile',
      color: 'bg-cyan-100 text-cyan-800',
      endpoints: [
        { id: 'client-profile',  label: 'Perfil Cliente',         method: 'GET',  path: '/client/profile',         description: 'Perfil organización cliente' },
        { id: 'client-tickets',  label: 'Tickets Cliente',        method: 'GET',  path: '/client/tickets',         description: 'Tickets del cliente' },
      ]
    },
  ];

  // ─── Frontend Pages ──────────────────────────────────────────────────────────
  const FRONTEND_PAGES: PageDef[] = [
    { label: 'Dashboard',          href: '/',               description: 'Panel principal de administración',           roles: ['todos'] },
    { label: 'Tickets',            href: '/tickets',        description: 'Gestión y listado de tickets',                roles: ['ADMIN', 'SUPPORT_MANAGER', 'AGENT'] },
    { label: 'Clientes (Tenants)', href: '/tenants',        description: 'Administración de organizaciones cliente',     roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'Usuarios',           href: '/users',          description: 'Gestión de usuarios internos',               roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'Categorías',         href: '/categories',     description: 'Categorías y SLA por área',                  roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'Sistemas',           href: '/systems',        description: 'Catálogo de sistemas soportados',            roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'SLA Dashboard',      href: '/sla',            description: 'Monitoreo de SLAs y cumplimiento',           roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'SLA En Riesgo',      href: '/sla/at-risk',   description: 'Tickets próximos a violar SLA',              roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'SLA Violaciones',    href: '/sla/violations', description: 'Historial de violaciones SLA',               roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'Reportes',           href: '/reports',        description: 'Reportes estadísticos e informes',           roles: ['ADMIN', 'SUPPORT_MANAGER'] },
    { label: 'Auditoría',          href: '/audit',          description: 'Bitácora de acciones del sistema',           roles: ['ADMIN', 'AUDITOR'] },
    { label: 'Seguridad',          href: '/audit/security', description: 'Análisis de amenazas y eventos de seguridad',roles: ['ADMIN'] },
    { label: 'Perfil',             href: '/profile',        description: 'Perfil y configuración de seguridad',        roles: ['todos'] },
    { label: 'Rate Limits',        href: '/rate-limits',    description: 'Estado de rate limiting por IP',             roles: ['ADMIN'] },
    { label: 'Reporte Endpoints',  href: '/test-report',   description: 'Esta misma página',                          roles: ['ADMIN'] },
  ];

  // ─── State ───────────────────────────────────────────────────────────────────
  let results: Record<string, EndpointResult> = {};
  let isTesting = false;
  let testingId: string | null = null;
  let totalOk = 0;
  let totalFail = 0;
  let activeTab: 'endpoints' | 'pages' = 'endpoints';

  // Init results
  for (const group of GROUPS) {
    for (const ep of group.endpoints) {
      results[ep.id] = { status: null, ok: null, ms: null, error: null, preview: null, tested: false, loading: false };
    }
  }

  function getToken(): string | null {
    return (typeof window !== 'undefined')
      ? localStorage.getItem('internal_auth_token')
      : null;
  }

  function getTenantId(): string | null {
    if (typeof window === 'undefined') return null;
    try {
      const stored = localStorage.getItem('internal_auth_user');
      if (stored) return JSON.parse(stored)?.tenant_id ?? null;
    } catch { /* ignore */ }
    return null;
  }

  async function testEndpoint(ep: EndpointDef) {
    results[ep.id] = { ...results[ep.id], loading: true, tested: false };
    results = results; // trigger reactivity

    const token = getToken();
    const tenantId = getTenantId();
    const headers: Record<string, string> = { 'Content-Type': 'application/json' };
    if (token) headers['Authorization'] = `Bearer ${token}`;
    if (tenantId) headers['X-Tenant-ID'] = tenantId;

    const url = `/api/v1${ep.path}`;
    const t0 = performance.now();

    try {
      let fetchOptions: RequestInit = { method: ep.method, headers };
      // For non-GET we don't send a body to avoid validation errors
      const res = await fetch(url, fetchOptions);
      const ms = Math.round(performance.now() - t0);
      let preview: string | null = null;
      try {
        const text = await res.text();
        const obj = JSON.parse(text);
        preview = JSON.stringify(obj, null, 2).slice(0, 500);
        if (JSON.stringify(obj, null, 2).length > 500) preview += '\n...';
      } catch { /* ignore */ }

      results[ep.id] = { status: res.status, ok: res.ok, ms, error: null, preview, tested: true, loading: false };
    } catch (e: any) {
      const ms = Math.round(performance.now() - t0);
      results[ep.id] = { status: null, ok: false, ms, error: e.message ?? 'Network error', preview: null, tested: true, loading: false };
    }

    results = results;
    recalcCounters();
  }

  async function testAll() {
    isTesting = true;
    totalOk = 0;
    totalFail = 0;
    for (const group of GROUPS) {
      for (const ep of group.endpoints) {
        testingId = ep.id;
        await testEndpoint(ep);
      }
    }
    testingId = null;
    isTesting = false;
  }

  function recalcCounters() {
    totalOk = Object.values(results).filter(r => r.tested && r.ok).length;
    totalFail = Object.values(results).filter(r => r.tested && !r.ok).length;
  }

  function statusBadge(r: EndpointResult): { text: string; cls: string } {
    if (r.loading) return { text: 'Probando...', cls: 'bg-gray-100 text-gray-600 animate-pulse' };
    if (!r.tested) return { text: 'Sin probar', cls: 'bg-gray-100 text-gray-400' };
    if (r.ok) return { text: `${r.status} OK`, cls: 'bg-green-100 text-green-700' };
    return { text: r.status ? `${r.status} Error` : 'Fallo red', cls: 'bg-red-100 text-red-700' };
  }

  function methodBadge(method: string): string {
    const map: Record<string, string> = {
      GET:    'bg-blue-100 text-blue-700',
      POST:   'bg-green-100 text-green-700',
      PUT:    'bg-yellow-100 text-yellow-700',
      DELETE: 'bg-red-100 text-red-700',
      PATCH:  'bg-purple-100 text-purple-700',
    };
    return map[method] ?? 'bg-gray-100 text-gray-700';
  }

  let expandedIds = new Set<string>();
  function toggleExpand(id: string) {
    if (expandedIds.has(id)) expandedIds.delete(id);
    else expandedIds.add(id);
    expandedIds = new Set(expandedIds);
  }

  const testedCount = () => Object.values(results).filter(r => r.tested).length;
  const totalEndpoints = GROUPS.reduce((acc, g) => acc + g.endpoints.length, 0);
</script>

<svelte:head>
  <title>Reporte de Endpoints - ServiceManager</title>
</svelte:head>

<div class="px-4 py-8 mx-auto max-w-7xl sm:px-6 lg:px-8">
  <!-- Header -->
  <div class="md:flex md:items-center md:justify-between mb-6">
    <div>
      <h2 class="text-2xl font-bold text-gray-900">Reporte de Endpoints & Páginas</h2>
      <p class="mt-1 text-sm text-gray-500">
        Diagnóstico de conectividad de todos los endpoints del backend y páginas del frontend.
      </p>
    </div>
    <div class="mt-4 flex gap-2 md:mt-0">
      <button
        on:click={testAll}
        disabled={isTesting}
        class="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed shadow-sm"
      >
        {#if isTesting}
          <svg class="animate-spin h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
          </svg>
          Probando endpoints...
        {:else}
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
          </svg>
          Probar Todo
        {/if}
      </button>
    </div>
  </div>

  <!-- Summary Bar -->
  {#if testedCount() > 0}
    <div class="mb-6 grid grid-cols-3 gap-4">
      <div class="bg-white rounded-lg border p-4 text-center">
        <div class="text-2xl font-bold text-gray-800">{testedCount()}/{totalEndpoints}</div>
        <div class="text-xs text-gray-500 mt-1">Endpoints probados</div>
      </div>
      <div class="bg-green-50 rounded-lg border border-green-200 p-4 text-center">
        <div class="text-2xl font-bold text-green-700">{totalOk}</div>
        <div class="text-xs text-green-600 mt-1">OK / Exitosos</div>
      </div>
      <div class="bg-red-50 rounded-lg border border-red-200 p-4 text-center">
        <div class="text-2xl font-bold text-red-700">{totalFail}</div>
        <div class="text-xs text-red-600 mt-1">Errores / Fallidos</div>
      </div>
    </div>
  {/if}

  <!-- Tabs -->
  <div class="flex border-b border-gray-200 mb-6">
    <button
      on:click={() => activeTab = 'endpoints'}
      class="px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors {activeTab === 'endpoints' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700'}"
    >
      Endpoints Backend ({totalEndpoints})
    </button>
    <button
      on:click={() => activeTab = 'pages'}
      class="px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors {activeTab === 'pages' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700'}"
    >
      Páginas Frontend ({FRONTEND_PAGES.length})
    </button>
  </div>

  <!-- ─── Endpoints Tab ─────────────────────────────────────────────────────── -->
  {#if activeTab === 'endpoints'}
    <div class="space-y-6">
      {#each GROUPS as group}
        <div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
          <!-- Group header -->
          <div class="flex items-center justify-between px-5 py-3 bg-gray-50 border-b border-gray-200">
            <div class="flex items-center gap-2">
              <span class="text-xs font-semibold uppercase tracking-wider px-2 py-0.5 rounded-full {group.color}">
                {group.name}
              </span>
              <span class="text-xs text-gray-400">{group.endpoints.length} endpoint{group.endpoints.length !== 1 ? 's' : ''}</span>
            </div>
            <div class="flex gap-1 items-center">
              {#each group.endpoints as ep}
                {#if results[ep.id].tested}
                  <span class="w-2 h-2 rounded-full {results[ep.id].ok ? 'bg-green-400' : 'bg-red-400'}" title={ep.label}></span>
                {/if}
              {/each}
            </div>
          </div>

          <!-- Endpoints list -->
          <div class="divide-y divide-gray-100">
            {#each group.endpoints as ep}
              {@const r = results[ep.id]}
              {@const badge = statusBadge(r)}
              <div class="px-5 py-3">
                <div class="flex items-center gap-3 flex-wrap">
                  <!-- Method badge -->
                  <span class="text-xs font-bold px-2 py-0.5 rounded font-mono {methodBadge(ep.method)}">
                    {ep.method}
                  </span>
                  <!-- Path -->
                  <code class="text-xs text-gray-700 bg-gray-50 px-2 py-0.5 rounded border border-gray-200 font-mono flex-shrink-0">
                    /api/v1{ep.path}
                  </code>
                  <!-- Label -->
                  <span class="text-sm text-gray-700 flex-1 min-w-0 truncate">{ep.label}</span>

                  <!-- Status + timing -->
                  <div class="flex items-center gap-2 ml-auto flex-shrink-0">
                    {#if r.ms !== null && r.tested}
                      <span class="text-xs text-gray-400">{r.ms}ms</span>
                    {/if}
                    <span class="text-xs font-medium px-2 py-0.5 rounded-full {badge.cls}">{badge.text}</span>
                    <!-- Test individual -->
                    <button
                      on:click={() => testEndpoint(ep)}
                      disabled={r.loading || isTesting}
                      class="ml-1 text-xs px-2 py-1 rounded border border-gray-200 hover:border-blue-300 hover:text-blue-600 text-gray-500 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
                    >
                      {r.loading ? '...' : 'Probar'}
                    </button>
                    <!-- Expand preview -->
                    {#if r.tested && r.preview}
                      <button
                        on:click={() => toggleExpand(ep.id)}
                        class="text-xs px-2 py-1 rounded border border-gray-200 hover:border-blue-300 hover:text-blue-600 text-gray-500 transition-colors"
                      >
                        {expandedIds.has(ep.id) ? 'Ocultar' : 'Ver respuesta'}
                      </button>
                    {/if}
                  </div>
                </div>

                <!-- Description -->
                <p class="mt-0.5 text-xs text-gray-400 ml-0.5">{ep.description}</p>

                <!-- Error message -->
                {#if r.tested && r.error}
                  <div class="mt-2 text-xs text-red-600 bg-red-50 rounded px-2 py-1.5 font-mono">{r.error}</div>
                {/if}

                <!-- Response preview -->
                {#if expandedIds.has(ep.id) && r.preview}
                  <pre class="mt-2 text-xs text-gray-700 bg-gray-50 border border-gray-200 rounded p-3 overflow-x-auto whitespace-pre-wrap break-words max-h-48">{r.preview}</pre>
                {/if}
              </div>
            {/each}
          </div>
        </div>
      {/each}
    </div>
  {/if}

  <!-- ─── Frontend Pages Tab ─────────────────────────────────────────────────── -->
  {#if activeTab === 'pages'}
    <div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
      <table class="min-w-full divide-y divide-gray-200">
        <thead class="bg-gray-50">
          <tr>
            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Página</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ruta</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Descripción</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Roles</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Acción</th>
          </tr>
        </thead>
        <tbody class="bg-white divide-y divide-gray-100">
          {#each FRONTEND_PAGES as pg}
            <tr class="hover:bg-gray-50 transition-colors">
              <td class="px-6 py-3">
                <span class="text-sm font-medium text-gray-900">{pg.label}</span>
              </td>
              <td class="px-6 py-3">
                <code class="text-xs bg-gray-100 text-gray-700 px-2 py-0.5 rounded font-mono">{pg.href}</code>
              </td>
              <td class="px-6 py-3">
                <span class="text-xs text-gray-500">{pg.description}</span>
              </td>
              <td class="px-6 py-3">
                <div class="flex flex-wrap gap-1">
                  {#each pg.roles as role}
                    <span class="text-xs px-1.5 py-0.5 rounded-full bg-blue-50 text-blue-600 font-medium">{role}</span>
                  {/each}
                </div>
              </td>
              <td class="px-6 py-3">
                <a
                  href={pg.href}
                  target="_blank"
                  rel="noopener noreferrer"
                  class="text-xs text-blue-600 hover:text-blue-800 underline font-medium"
                >
                  Abrir ↗
                </a>
              </td>
            </tr>
          {/each}
        </tbody>
      </table>

      <!-- Notes -->
      <div class="px-6 py-4 bg-gray-50 border-t border-gray-200">
        <p class="text-xs text-gray-500">
          <strong>Nota:</strong> Las páginas se abren en una nueva pestaña para verificar su renderizado.
          Asegúrate de estar autenticado antes de acceder a rutas protegidas.
        </p>
        <div class="mt-3 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
          {#each FRONTEND_PAGES as pg}
            <a
              href={pg.href}
              target="_blank"
              rel="noopener noreferrer"
              class="flex items-center gap-2 px-3 py-2 rounded-lg border border-gray-200 hover:border-blue-300 hover:bg-blue-50 text-xs text-gray-700 hover:text-blue-700 transition-all group"
            >
              <svg class="w-3.5 h-3.5 text-gray-400 group-hover:text-blue-500 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
              </svg>
              <span class="truncate font-medium">{pg.label}</span>
              <code class="ml-auto text-gray-400 text-xs flex-shrink-0">{pg.href}</code>
            </a>
          {/each}
        </div>
      </div>
    </div>
  {/if}
</div>
