/**
 * POST /api/zabbix/sync-hosts
 * Pulls all hosts from the live Zabbix API and caches them in zabbix_wan_hosts.
 * Also fetches current open problems and stamps last_problem_at on affected hosts.
 */
import { NextResponse } from 'next/server';
import { ZabbixClient } from '@/lib/services/zabbix-client';
import { postgresClient } from '@/lib/services/postgres-client';

export const maxDuration = 120;

export async function POST() {
  if (!process.env.ZABBIX_API_URL || !process.env.ZABBIX_API_TOKEN) {
    return NextResponse.json({ error: 'Zabbix not configured' }, { status: 500 });
  }

  const zabbix = new ZabbixClient({
    apiUrl: process.env.ZABBIX_API_URL,
    apiToken: process.env.ZABBIX_API_TOKEN,
  });

  try {
    const hosts = await zabbix.getHosts();

    // Fetch open problems to stamp last_problem_at
    const problems = await zabbix.getOpenProblems(2);
    const problemByHostId = new Map<string, { name: string; clock: string }>();
    for (const p of problems) {
      for (const h of (p.hosts ?? [])) {
        if (!problemByHostId.has(h.hostid) || Number(p.clock) > Number(problemByHostId.get(h.hostid)!.clock)) {
          problemByHostId.set(h.hostid, { name: p.name, clock: p.clock });
        }
      }
    }

    let upserted = 0;
    let skipped = 0;

    for (const host of hosts) {
      // Only process ICMP/WAN hosts — they have an agent interface with an IP
      const iface = (host.interfaces ?? []).find(i => Number(i.useip) === 1 && i.ip && i.ip !== '127.0.0.1');
      if (!iface) { skipped++; continue; }

      const getMacro = (name: string) =>
        (host.macros ?? []).find(m => m.macro === name)?.value ?? null;

      const getTag = (name: string) =>
        (host.tags ?? []).find(t => t.tag === name)?.value ?? null;

      const rmmSiteUid        = getMacro('{$RMM_SITE_UID}');
      const autotaskCompanyId = getMacro('{$AUTOTASK_COMPANY_ID}');
      const autotaskCompanyName = getMacro('{$AUTOTASK_COMPANY_NAME}');
      const ispName           = getMacro('{$ISP_NAME}');
      const asn               = getMacro('{$ASN}');

      const isMultiWan = getTag('multi-wan') === 'true';
      const source     = getTag('source') ?? 'datto-rmm';

      const problem = problemByHostId.get(host.hostid);

      await postgresClient.query(
        `INSERT INTO zabbix_wan_hosts (
          hostid, host_name, display_name, wan_ip, status,
          rmm_site_uid, autotask_company_id, autotask_company_name,
          isp_name, asn, is_multi_wan, source, tags,
          last_problem_at, last_problem_name,
          last_synced_at, updated_at
        ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,NOW(),NOW())
        ON CONFLICT (hostid) DO UPDATE SET
          host_name             = EXCLUDED.host_name,
          display_name          = EXCLUDED.display_name,
          wan_ip                = EXCLUDED.wan_ip,
          status                = EXCLUDED.status,
          rmm_site_uid          = EXCLUDED.rmm_site_uid,
          autotask_company_id   = EXCLUDED.autotask_company_id,
          autotask_company_name = EXCLUDED.autotask_company_name,
          isp_name              = EXCLUDED.isp_name,
          asn                   = EXCLUDED.asn,
          is_multi_wan          = EXCLUDED.is_multi_wan,
          source                = EXCLUDED.source,
          tags                  = EXCLUDED.tags,
          last_problem_at       = EXCLUDED.last_problem_at,
          last_problem_name     = EXCLUDED.last_problem_name,
          last_synced_at        = NOW(),
          updated_at            = NOW()`,
        [
          host.hostid,
          host.host,
          host.name ?? host.host,
          iface.ip,
          Number(host.status ?? 0),
          rmmSiteUid,
          autotaskCompanyId ? Number(autotaskCompanyId) : null,
          autotaskCompanyName,
          ispName,
          asn,
          isMultiWan,
          source,
          JSON.stringify(host.tags ?? []),
          problem ? new Date(Number(problem.clock) * 1000).toISOString() : null,
          problem?.name ?? null,
        ]
      );
      upserted++;
    }

    // Remove hosts no longer in Zabbix
    const liveIds = hosts.map(h => h.hostid);
    if (liveIds.length > 0) {
      const deleted = await postgresClient.query(
        'DELETE FROM zabbix_wan_hosts WHERE hostid <> ALL($1) RETURNING hostid',
        [liveIds]
      );
      return NextResponse.json({ upserted, skipped, removed: deleted.rowCount });
    }

    return NextResponse.json({ upserted, skipped, removed: 0 });
  } catch (err) {
    const msg = err instanceof Error ? err.message : String(err);
    return NextResponse.json({ error: msg }, { status: 500 });
  }
}
