/**
 * POST /api/zabbix/webhook
 * Receives Zabbix alert/recovery notifications and writes them to zabbix_events.
 * Enriches each event with company/site context from the local zabbix_wan_hosts cache.
 *
 * Expected JSON payload (sent by the Zabbix webhook media type script):
 * {
 *   event_id:       string   -- {EVENT.ID}
 *   event_name:     string   -- {EVENT.NAME}
 *   event_value:    string   -- "1" = PROBLEM, "0" = RESOLVED
 *   event_severity: string   -- numeric severity "0"–"5"
 *   event_clock:    string   -- Unix timestamp string
 *   trigger_id:     string   -- {TRIGGER.ID}
 *   host_id:        string   -- {HOST.ID}
 *   host_name:      string   -- {HOST.HOST} (technical name)
 *   r_event_id?:    string   -- {EVENT.RECOVERY.ID} (only on recovery)
 *   r_clock?:       string   -- {EVENT.RECOVERY.DATE} as unix ts (only on recovery)
 * }
 *
 * Auth: Bearer token in Authorization header, matched against ZABBIX_WEBHOOK_SECRET env var.
 */
import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';

export async function POST(request: NextRequest) {
  // Optional shared secret — skip check if not configured
  const secret = process.env.ZABBIX_WEBHOOK_SECRET;
  if (secret) {
    const auth = request.headers.get('authorization') ?? '';
    const token = auth.startsWith('Bearer ') ? auth.slice(7) : auth;
    if (token !== secret) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }
  }

  let body: Record<string, string>;
  try {
    const raw = await request.text();
    console.log('[ZABBIX-WEBHOOK] Incoming request — auth:', request.headers.get('authorization') ? 'present' : 'none', '— body:', raw.substring(0, 500));
    body = JSON.parse(raw);
  } catch {
    console.log('[ZABBIX-WEBHOOK] Failed to parse JSON');
    return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 });
  }

  const {
    event_id,
    event_name,
    event_value,
    event_severity,
    event_clock,
    trigger_id,
    host_id,
    r_event_id,
    r_clock,
  } = body;

  if (!event_id || !host_id || !event_clock) {
    return NextResponse.json({ error: 'Missing required fields: event_id, host_id, event_clock' }, { status: 400 });
  }

  try {
    // Enrich with local host context
    const hostRow = await postgresClient.query<{
      display_name: string;
      wan_ip: string | null;
      autotask_company_id: number | null;
      autotask_company_name: string | null;
      rmm_site_uid: string | null;
      isp_name: string | null;
    }>(
      'SELECT display_name, wan_ip, autotask_company_id, autotask_company_name, rmm_site_uid, isp_name FROM zabbix_wan_hosts WHERE hostid = $1',
      [host_id]
    );

    const host = hostRow.rows[0] ?? null;

    const toInt     = (v: string | undefined) => { const n = Number(v); return Number.isFinite(n) ? n : null; };
    const toTs      = (v: string | undefined) => { const n = Number(v); return Number.isFinite(n) && n > 0 ? new Date(n * 1000) : null; };
    const isMacro   = (v: string | undefined) => !v || v.startsWith('{');

    const isResolved = event_value === '0';
    const clockTs    = toTs(event_clock) ?? new Date();
    // {EVENT.RECOVERY.CLOCK} often doesn't resolve in webhook params — fall back to NOW() for recoveries
    const rClockTs   = toTs(r_clock) ?? (isResolved ? new Date() : null);
    const duration   = rClockTs ? Math.round((rClockTs.getTime() - clockTs.getTime()) / 1000) : null;
    // {EVENT.RECOVERY.ID} also may not resolve — use event_id as marker so the row is flagged resolved
    const rEventId   = !isMacro(r_event_id) && r_event_id !== '0'
      ? r_event_id
      : (isResolved ? event_id : null);

    await postgresClient.query(
      `INSERT INTO zabbix_events (
        eventid, objectid, name, severity, clock,
        r_eventid, r_clock, duration_seconds,
        hostid, host_name, wan_ip,
        autotask_company_id, autotask_company_name, rmm_site_uid, isp_name,
        last_synced_at
      ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,NOW())
      ON CONFLICT (eventid) DO UPDATE SET
        name                  = EXCLUDED.name,
        r_eventid             = COALESCE(EXCLUDED.r_eventid, zabbix_events.r_eventid),
        r_clock               = COALESCE(EXCLUDED.r_clock,   zabbix_events.r_clock),
        duration_seconds      = COALESCE(EXCLUDED.duration_seconds, zabbix_events.duration_seconds),
        host_name             = EXCLUDED.host_name,
        wan_ip                = EXCLUDED.wan_ip,
        autotask_company_id   = EXCLUDED.autotask_company_id,
        autotask_company_name = EXCLUDED.autotask_company_name,
        rmm_site_uid          = EXCLUDED.rmm_site_uid,
        isp_name              = EXCLUDED.isp_name,
        last_synced_at        = NOW()`,
      [
        event_id,
        trigger_id ?? null,
        event_name ?? null,
        toInt(event_severity),
        clockTs,
        rEventId,
        rClockTs,
        duration,
        host_id,
        host?.display_name ?? body.host_name ?? null,
        host?.wan_ip ?? null,
        host?.autotask_company_id ?? null,
        host?.autotask_company_name ?? null,
        host?.rmm_site_uid ?? null,
        host?.isp_name ?? null,
      ]
    );

    return NextResponse.json({ ok: true, event_id, resolved: isResolved });
  } catch (err) {
    const msg = err instanceof Error ? err.message : String(err);
    console.error('[ZABBIX-WEBHOOK]', msg);
    return NextResponse.json({ error: msg }, { status: 500 });
  }
}

/**
 * GET /api/zabbix/webhook
 * Returns the Zabbix media type script and parameter config ready to paste.
 */
export async function GET() {
  const baseUrl = process.env.WEBHOOK_BASE_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? process.env.APP_URL ?? 'https://your-pulse-url';
  const secret  = process.env.ZABBIX_WEBHOOK_SECRET ?? '';

  const script = `// Pulse WAN Correlation Webhook
var params = JSON.parse(value);
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
${secret ? "req.addHeader('Authorization: Bearer ' + params.webhook_secret);" : '// No auth configured — set ZABBIX_WEBHOOK_SECRET env var to enable'}

var payload = JSON.stringify({
    event_id:       params.event_id,
    event_name:     params.event_name,
    event_value:    params.event_value,
    event_severity: params.event_severity,
    event_clock:    params.event_clock,
    trigger_id:     params.trigger_id,
    host_id:        params.host_id,
    host_name:      params.host_name,
    r_event_id:     params.r_event_id,
    r_clock:        params.r_clock
});

var response = req.post(params.webhook_url, payload);
if (req.getStatus() !== 200) {
    throw 'Pulse webhook failed: HTTP ' + req.getStatus() + ' — ' + response;
}
return 'OK';`;

  const parameters = [
    { name: 'webhook_url',    value: `${baseUrl}/api/zabbix/webhook` },
    { name: 'webhook_secret', value: secret || '(set ZABBIX_WEBHOOK_SECRET env var)' },
    { name: 'event_id',       value: '{EVENT.ID}' },
    { name: 'event_name',     value: '{EVENT.NAME}' },
    { name: 'event_value',    value: '{EVENT.VALUE}' },
    { name: 'event_severity', value: '{EVENT.SEVERITY.NUM}' },
    { name: 'event_clock',    value: '{EVENT.CLOCK}' },
    { name: 'trigger_id',     value: '{TRIGGER.ID}' },
    { name: 'host_id',        value: '{HOST.ID}' },
    { name: 'host_name',      value: '{HOST.HOST}' },
    { name: 'r_event_id',     value: '{EVENT.RECOVERY.ID}' },
    { name: 'r_clock',        value: '{EVENT.RECOVERY.CLOCK}' },
  ];

  return NextResponse.json({ script, parameters, webhook_url: `${baseUrl}/api/zabbix/webhook` });
}
