/**
 * GET /api/zabbix/alert-correlation
 * Cross-references Zabbix WAN problem events against Datto RMM ping/offline alerts
 * for the same company within a configurable time window.
 *
 * Query params:
 *   days        — look-back window in days (default 30)
 *   windowMins  — match window ± minutes around Zabbix event (default 120)
 *   companyId   — optional: filter to one Autotask company
 */
import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';

export async function GET(request: NextRequest) {
  const { searchParams } = request.nextUrl;
  const days       = Number(searchParams.get('days')       ?? 30);
  const windowMins = Number(searchParams.get('windowMins') ?? 120);
  const companyId  = searchParams.get('companyId');

  try {
    const since = new Date(Date.now() - days * 86400 * 1000);

    // ── 1. Zabbix events with matched RMM alert count ────────────────────────
    const zabbixRows = await postgresClient.query<{
      eventid: string;
      name: string;
      severity: number;
      clock: string;
      r_clock: string | null;
      duration_seconds: number | null;
      host_name: string;
      wan_ip: string;
      isp_name: string | null;
      autotask_company_id: number;
      autotask_company_name: string;
      rmm_site_uid: string | null;
      rmm_alert_count: string;
      rmm_alerts: string; // JSON array
    }>(`
      SELECT
        ze.eventid,
        ze.name,
        ze.severity,
        ze.clock,
        ze.r_clock,
        ze.duration_seconds,
        ze.host_name,
        ze.wan_ip,
        ze.isp_name,
        ze.autotask_company_id,
        ze.autotask_company_name,
        ze.rmm_site_uid,
        COUNT(ra.alert_uid)::text                  AS rmm_alert_count,
        json_agg(json_build_object(
          'alert_uid',       ra.alert_uid,
          'site_name',       ra.site_name,
          'alert_class',     ra.alert_context->>'@class',
          'alert_message',   ra.alert_message_en,
          'timestamp',       ra.timestamp,
          'resolved',        ra.resolved,
          'resolved_on',     ra.resolved_on,
          'device_name',     ra.device_name
        ) ORDER BY ra.timestamp)
          FILTER (WHERE ra.alert_uid IS NOT NULL) AS rmm_alerts
      FROM zabbix_events ze
      LEFT JOIN datto_rmm_alerts ra
        ON ra.timestamp BETWEEN ze.clock - ($1 * INTERVAL '1 minute')
                             AND ze.clock + ($1 * INTERVAL '1 minute')
        AND EXISTS (
          SELECT 1 FROM datto_rmm_sites ds
          JOIN rmm_site_mappings rsm ON rsm.rmm_site_uid = ds.uid
          WHERE ds.uid = ra.site_uid
            AND rsm.company_id = ze.autotask_company_id
        )
      WHERE ze.clock >= $2
        ${companyId ? 'AND ze.autotask_company_id = $3' : ''}
      GROUP BY
        ze.eventid, ze.name, ze.severity, ze.clock, ze.r_clock,
        ze.duration_seconds, ze.host_name, ze.wan_ip, ze.isp_name,
        ze.autotask_company_id, ze.autotask_company_name, ze.rmm_site_uid
      ORDER BY ze.clock DESC
    `, companyId
      ? [windowMins, since, Number(companyId)]
      : [windowMins, since]);

    // ── 2. RMM ping/offline alerts with NO matching Zabbix event ────────────
    const rmmOnlyRows = await postgresClient.query<{
      alert_uid: string;
      site_name: string;
      alert_class: string;
      alert_message: string | null;
      timestamp: string;
      resolved: boolean;
      resolved_on: string | null;
      device_name: string | null;
      autotask_company_id: number | null;
      autotask_company_name: string | null;
    }>(`
      SELECT
        ra.alert_uid,
        ra.site_name,
        ra.alert_context->>'@class'  AS alert_class,
        ra.alert_message_en          AS alert_message,
        ra.timestamp,
        ra.resolved,
        ra.resolved_on,
        ra.device_name,
        rsm.company_id               AS autotask_company_id,
        c.company_name               AS autotask_company_name
      FROM datto_rmm_alerts ra
      JOIN datto_rmm_sites ds ON ds.uid = ra.site_uid
      JOIN rmm_site_mappings rsm ON rsm.rmm_site_uid = ds.uid
      JOIN companies c ON c.id = rsm.company_id
      WHERE ra.timestamp >= $1
        AND ra.alert_context->>'@class' IN ('ping_ctx', 'device_offline_ctx', 'network_ctx')
        AND NOT EXISTS (
          SELECT 1 FROM zabbix_events ze
          WHERE ze.autotask_company_id = rsm.company_id
            AND ze.clock BETWEEN ra.timestamp - ($2 * INTERVAL '1 minute')
                              AND ra.timestamp + ($2 * INTERVAL '1 minute')
        )
        ${companyId ? 'AND rsm.company_id = $3' : ''}
      ORDER BY ra.timestamp DESC
      LIMIT 500
    `, companyId
      ? [since, windowMins, Number(companyId)]
      : [since, windowMins]);

    // ── 3. Summary stats ─────────────────────────────────────────────────────
    const zabbixWithRmm   = zabbixRows.rows.filter(r => Number(r.rmm_alert_count) > 0).length;
    const zabbixWithoutRmm = zabbixRows.rows.filter(r => Number(r.rmm_alert_count) === 0).length;

    const lastEventSync = await postgresClient.query<{ last_sync: string | null }>(
      'SELECT MAX(last_synced_at) AS last_sync FROM zabbix_events'
    );

    return NextResponse.json({
      summary: {
        days,
        window_mins: windowMins,
        zabbix_events_total:       zabbixRows.rows.length,
        zabbix_with_rmm_match:     zabbixWithRmm,
        zabbix_without_rmm_match:  zabbixWithoutRmm,
        rmm_only_alerts:           rmmOnlyRows.rows.length,
        last_event_sync:           lastEventSync.rows[0]?.last_sync ?? null,
      },
      zabbix_events: zabbixRows.rows,
      rmm_only:      rmmOnlyRows.rows,
    });
  } catch (err) {
    const msg = err instanceof Error ? err.message : String(err);
    return NextResponse.json({ error: msg }, { status: 500 });
  }
}
