/**
 * Type definitions for the PAX8 REST API (v1) and the shapes Pulse persists.
 * Source spec lives at `https://devx.pax8.com`.
 *
 * Only the slices Pulse consumes are typed — PAX8 exposes a much larger
 * surface (marketplace/provisioning endpoints Pulse never calls as a
 * partner/reseller). Long-tail fields fall back to the `[key: string]:
 * unknown` escape hatch on each interface, matching lib/types/appgate.ts.
 */

// ─── API response shapes ──────────────────────────────────────────────────

export interface Pax8PageEnvelope<T> {
  content: T[];
  page: {
    size: number;
    totalElements: number;
    totalPages: number;
    number: number;
  };
}

export interface Pax8Company {
  id: string;
  name: string;
  externalId: string | null;
  website: string | null;
  status: string | null;
  city: string | null;
  stateOrProvince: string | null;
  postalCode: string | null;
  country: string | null;
  [key: string]: unknown; // escape hatch for fields not yet modeled
}

export interface Pax8Subscription {
  id: string;
  companyId: string;
  productId: string;
  quantity: number;
  billingTerm: string | null;
  status: string | null;
  startDate: string | null;
  price: number | null; // customer/list price (D-03)
  partnerCost: number | null; // partner/reseller cost (D-03)
  currencyCode: string | null;
  productName: string | null;
  endDate: string | null;
  updatedDate: string | null;
  [key: string]: unknown; // escape hatch for fields not yet modeled
}

export interface Pax8Product {
  id: string;
  sku: string;
  vendorSku: string | null;
  name: string;
  category: string | null;
  vendorName: string | null;
  shortDescription: string | null;
  [key: string]: unknown; // escape hatch for fields not yet modeled
  // NOTE: the deprecated alternate-vendor-SKU field per PAX8's own schema is intentionally omitted.
}

// Live-verified against PAX8's real /invoices response (12-RESEARCH.md
// Pitfall 2) — the header is the partner's consolidated monthly bill.
export interface Pax8Invoice {
  id: string;
  // Always null on the header for this single-tenant reseller account —
  // per-company data lives on each invoice item (Pax8InvoiceItem), not here.
  companyId: string | null;
  invoiceDate: string | null;
  total: number | null;
  status: string | null;
  currencyCode: string | null;
  [key: string]: unknown; // escape hatch for fields not yet modeled
}

// Live-verified against PAX8's real /invoices response (12-RESEARCH.md
// Pitfall 2) — the line item carries the actual per-company, per-period cost.
export interface Pax8InvoiceItem {
  id: string;
  type: string | null;
  externalId: string | null;
  companyId: string | null;
  forCompanyId: string | null;
  companyName: string | null;
  startPeriod: string | null;
  endPeriod: string | null;
  quantity: number | null;
  unitOfMeasure: string | null;
  term: string | null;
  sku: string | null;
  description: string | null;
  rateType: string | null;
  chargeType: string | null;
  price: number | null;
  subTotal: number | null;
  cost: number | null;
  costTotal: number | null;
  total: number | null;
  amountDue: number | null;
  productId: string | null;
  productName: string | null;
  vendorName: string | null;
  currencyCode: string | null;
  subscriptionId: string | null;
  [key: string]: unknown; // escape hatch for fields not yet modeled
}

// ─── Sync result shapes ───────────────────────────────────────────────────
// Mirrors lib/types/appgate.ts's AppgateSyncResult/AppgateEntity shape —
// the sync service (Plan 02) reports one Pax8EntitySyncResult per entity
// type (companies/products/subscriptions), rolled up into a Pax8SyncResult.

export interface Pax8EntitySyncResult {
  entity: string;
  success: boolean;
  upserted: number;
  tombstoned: number;
  durationMs: number;
  error?: string;
  // Populated only by the 'company_matches' entity: pax8_companies rows
  // flagged for manual review this run (ambiguous + no-candidate). Kept
  // separate from `tombstoned` (a real soft-delete count) so it is never
  // folded into sync_history.records_deleted / the Sync History UI's
  // "deleted" column.
  flaggedForReview?: number;
}

export interface Pax8SyncResult {
  syncId: string;
  status: 'completed' | 'failed';
  startedAt: Date;
  completedAt: Date | null;
  durationMs: number;
  entities: Pax8EntitySyncResult[];
  errors: string[];
}
