/**
 * POST /api/itglue/sync-wan
 * Pulls all Internet/WAN flexible assets (type 3794) from the local itg_flexible_assets
 * table, parses static IPs, and upserts into itg_wan_circuits.
 * Also matches Zabbix WAN hosts by IP to populate zabbix_hostid.
 */
import { NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';

export const maxDuration = 120;

// Extract public IPs from the raw HTML/text blob IT Glue stores
function parseStaticIps(raw: string | null): string[] {
  if (!raw) return [];
  // Strip HTML tags
  const text = raw.replace(/<[^>]+>/g, ' ').replace(/&nbsp;/g, ' ');
  // Match IPv4 addresses
  const matches = text.match(/\b(\d{1,3}\.){3}\d{1,3}\b/g) ?? [];
  // Filter out private/RFC1918 ranges, subnet masks, gateways that look like masks
  return [...new Set(
    matches.filter(ip => {
      const parts = ip.split('.').map(Number);
      if (parts[0] === 10) return false;
      if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return false;
      if (parts[0] === 192 && parts[1] === 168) return false;
      if (parts[0] === 255) return false;
      if (parts[0] === 0) return false;
      if (ip === 'DHCP') return false;
      return true;
    })
  )];
}

function isDecommissioned(notes: string | null): boolean {
  if (!notes) return false;
  const lower = notes.toLowerCase();
  return lower.includes('decommission') || lower.includes('decomission') || lower.includes('retired') || lower.includes('removed');
}

export async function POST() {
  try {
    // Pull all IT Glue WAN flexible assets joined to org data
    const assets = await postgresClient.query<{
      id: number;
      organization_id: number;
      org_name: string;
      psa_id: string | null;
      provider: string | null;
      link_type: string | null;
      static_ips_raw: string | null;
      upload_mbps: string | null;
      download_mbps: string | null;
      location_name: string | null;
      location_city: string | null;
      notes: string | null;
    }>(`
      SELECT
        fa.id,
        fa.organization_id,
        io.name AS org_name,
        io.psa_id,
        fa.traits->>'provider'              AS provider,
        fa.traits->>'link-type'             AS link_type,
        fa.traits->>'static-ip-address-es'  AS static_ips_raw,
        fa.traits->>'upload-speed-mbps'     AS upload_mbps,
        fa.traits->>'download-speed-mbps'   AS download_mbps,
        fa.traits->'location-s'->'values'->0->>'name' AS location_name,
        fa.traits->'location-s'->'values'->0->>'city' AS location_city,
        fa.traits->>'notes'                 AS notes
      FROM itg_flexible_assets fa
      JOIN itg_organizations io ON io.id = fa.organization_id
      WHERE fa.flexible_asset_type_id = 3794
    `);

    // Build IP → hostid map from zabbix_wan_hosts for matching
    const zabbixRows = await postgresClient.query<{ hostid: string; wan_ip: string }>(
      'SELECT hostid, wan_ip FROM zabbix_wan_hosts WHERE wan_ip IS NOT NULL'
    );
    const zabbixByIp = new Map<string, string>();
    for (const r of zabbixRows.rows) {
      zabbixByIp.set(r.wan_ip, r.hostid);
    }

    let upserted = 0;

    for (const a of assets.rows) {
      const staticIps = parseStaticIps(a.static_ips_raw);
      const decommissioned = isDecommissioned(a.notes);
      const autotaskCompanyId = a.psa_id ? Number(a.psa_id) : null;

      // Try to match a Zabbix host by any of the circuit's static IPs
      let zabbixHostid: string | null = null;
      for (const ip of staticIps) {
        if (zabbixByIp.has(ip)) { zabbixHostid = zabbixByIp.get(ip)!; break; }
      }

      await postgresClient.query(
        `INSERT INTO itg_wan_circuits (
          id, organization_id, org_name, autotask_company_id,
          provider, link_type, static_ips, raw_ip_text,
          upload_mbps, download_mbps, location_name, location_city,
          notes, is_decommissioned, zabbix_hostid,
          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 (id) DO UPDATE SET
          org_name              = EXCLUDED.org_name,
          autotask_company_id   = EXCLUDED.autotask_company_id,
          provider              = EXCLUDED.provider,
          link_type             = EXCLUDED.link_type,
          static_ips            = EXCLUDED.static_ips,
          raw_ip_text           = EXCLUDED.raw_ip_text,
          upload_mbps           = EXCLUDED.upload_mbps,
          download_mbps         = EXCLUDED.download_mbps,
          location_name         = EXCLUDED.location_name,
          location_city         = EXCLUDED.location_city,
          notes                 = EXCLUDED.notes,
          is_decommissioned     = EXCLUDED.is_decommissioned,
          zabbix_hostid         = EXCLUDED.zabbix_hostid,
          last_synced_at        = NOW(),
          updated_at            = NOW()`,
        [
          a.id, a.organization_id, a.org_name, autotaskCompanyId,
          a.provider, a.link_type, staticIps, a.static_ips_raw,
          a.upload_mbps ? Number(a.upload_mbps) : null,
          a.download_mbps ? Number(a.download_mbps) : null,
          a.location_name, a.location_city,
          a.notes, decommissioned, zabbixHostid,
        ]
      );
      upserted++;
    }

    // Summary stats
    const stats = await postgresClient.query<{
      total: string; with_ip: string; matched_zabbix: string; decommissioned: string; no_itg_org_link: string;
    }>(`
      SELECT
        COUNT(*)                                           AS total,
        COUNT(*) FILTER (WHERE array_length(static_ips,1) > 0) AS with_ip,
        COUNT(*) FILTER (WHERE zabbix_hostid IS NOT NULL)  AS matched_zabbix,
        COUNT(*) FILTER (WHERE is_decommissioned)           AS decommissioned,
        COUNT(*) FILTER (WHERE autotask_company_id IS NULL) AS no_itg_org_link
      FROM itg_wan_circuits
    `);

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