import { query } from '../db.js';
import {
  getAuthorityProfile,
  getSupplierProfile,
  type EntityProfile,
} from '../seap-client.js';

// In-memory cache to avoid duplicate API calls within a session
const entityCache = new Map<string, boolean>();

function cacheKey(entityId: number, type: string) {
  return `${type}:${entityId}`;
}

export async function ensureAuthority(entityId: number): Promise<void> {
  await ensureEntity(entityId, 'authority');
}

export async function ensureSupplier(entityId: number): Promise<void> {
  await ensureEntity(entityId, 'supplier');
}

async function ensureEntity(entityId: number, type: 'authority' | 'supplier'): Promise<void> {
  const key = cacheKey(entityId, type);
  if (entityCache.has(key)) return;

  // Check DB first
  const existing = await query(
    'SELECT entity_id FROM seap.entities WHERE entity_id = $1',
    [entityId]
  );

  if (existing.rows.length > 0) {
    entityCache.set(key, true);
    return;
  }

  // Fetch from SEAP
  let profile: EntityProfile;
  try {
    profile = type === 'authority'
      ? await getAuthorityProfile(entityId)
      : await getSupplierProfile(entityId);
  } catch (err: any) {
    console.warn(`Failed to fetch ${type} entity ${entityId}: ${err.message}`);
    // Insert minimal record so we don't retry
    await query(
      `INSERT INTO seap.entities (entity_id, entity_type, name)
       VALUES ($1, $2, $3)
       ON CONFLICT (entity_id) DO NOTHING`,
      [entityId, type, `Unknown ${type} ${entityId}`]
    );
    entityCache.set(key, true);
    return;
  }

  await query(
    `INSERT INTO seap.entities
       (entity_id, entity_type, fiscal_number, name, city, county, address, postal_code, is_utility)
     VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
     ON CONFLICT (entity_id) DO UPDATE SET
       name = EXCLUDED.name,
       city = EXCLUDED.city,
       county = EXCLUDED.county,
       address = EXCLUDED.address,
       updated_at = now()`,
    [
      profile.entityId,
      type,
      profile.fiscalNumber || profile.numericFiscalNumber,
      profile.entityName,
      profile.city,
      profile.county,
      profile.address,
      profile.postalCode,
      profile.isUtility ?? false,
    ]
  );

  entityCache.set(key, true);
}

export function getEntityCacheSize(): number {
  return entityCache.size;
}
