/**
 * Invoice adapter schema — P056 invoices-adapters.
 * Postgres / Neon via Hyperdrive.
 *
 * Tables:
 * - integration_sync_logs: per-entity push/pull outcome log for all IL invoice providers.
 *
 * Supported IL invoice adapter providers:
 *   morning | icount | rivhit | invoice4u | easycount
 *
 * Adapter credentials (API keys, tokens) are stored encrypted in the existing
 * adapter_credentials table (packages/db/src/schema/communications.ts) using
 * INTEGRATION_ENCRYPTION_KEY / encryptCredential from @zync/auth.
 * The adapter_id values used here MUST match entries in adapter_credentials.
 *
 * DB conventions:
 * - UUID PK .defaultRandom()
 * - TIMESTAMPTZ via timestamp(col, { withTimezone: true })
 * - Enums: text() + check(... IN (...)) — NEVER pgEnum
 * - Partial/GIN indexes → raw_ddl only (drizzle snapshot truncation)
 * - JSONB for provider-specific config and error payloads
 */
import {
  pgTable,
  uuid,
  text,
  jsonb,
  timestamp,
  integer,
  index,
  check,
} from 'drizzle-orm/pg-core'
import { sql } from 'drizzle-orm'
import { tenants } from './tenants'
import { users } from './users'

// ── IL invoice provider values ─────────────────────────────────────────────────

export const IL_INVOICE_PROVIDERS = [
  'morning',
  'icount',
  'rivhit',
  'invoice4u',
  'easycount',
] as const

export type ILInvoiceProvider = (typeof IL_INVOICE_PROVIDERS)[number]

// ── integration_sync_logs ─────────────────────────────────────────────────────
// Tracks each push (Zync → provider) and pull (provider → Zync) attempt outcome.
// entity_type: what Zync entity was synced ('invoice' | 'customer')
// direction:   'push' (Zync data → provider) | 'pull' (provider data → Zync)
// status:      'success' | 'failure' | 'skipped'
// Partial index idx_isl_tenant_entity lives in raw_ddl only.

export const integrationSyncLogs = pgTable(
  'integration_sync_logs',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    tenantId: uuid('tenant_id')
      .notNull()
      .references(() => tenants.id, { onDelete: 'cascade' }),
    // Which IL invoice provider was used
    provider: text('provider').notNull(),
    // 'invoice' | 'customer' — Zync entity type being synced
    entityType: text('entity_type').notNull(),
    // UUID of the Zync entity (invoice_id or customer_id)
    entityId: uuid('entity_id').notNull(),
    // Provider's external reference (their doc ID, if known)
    externalId: text('external_id'),
    direction: text('direction').notNull(),
    status: text('status').notNull(),
    // HTTP status code from provider, if applicable
    httpStatus: integer('http_status'),
    // Structured error detail (provider error payload, validation messages)
    errorPayload: jsonb('error_payload').$type<Record<string, unknown>>(),
    // Duration in ms
    durationMs: integer('duration_ms'),
    // Actor: NULL for cron-triggered syncs
    triggeredBy: uuid('triggered_by').references(() => users.id, { onDelete: 'set null' }),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (t) => ({
    tenantIdx: index('idx_isl_tenant').on(t.tenantId, t.provider, t.createdAt.desc()),
    providerCheck: check(
      'integration_sync_logs_provider_check',
      sql`${t.provider} IN ('morning','icount','rivhit','invoice4u','easycount')`,
    ),
    entityTypeCheck: check(
      'integration_sync_logs_entity_type_check',
      sql`${t.entityType} IN ('invoice','credit_note','payment','customer')`,
    ),
    directionCheck: check(
      'integration_sync_logs_direction_check',
      sql`${t.direction} IN ('push','pull')`,
    ),
    statusCheck: check(
      'integration_sync_logs_status_check',
      sql`${t.status} IN ('success','failure','skipped')`,
    ),
    // Compound partial index on (tenant, entity_type, entity_id, created_at DESC)
    // lives in raw_ddl only (drizzle snapshot truncation).
  }),
)

export type IntegrationSyncLogRow = typeof integrationSyncLogs.$inferSelect
export type NewIntegrationSyncLog = typeof integrationSyncLogs.$inferInsert
