/**
 * Bulk CSV/XLSX importer tables.
 *
 * See docs/superpowers/specs/2026-06-01-bulk-import-design.md. Three tables,
 * no changes to entity tables:
 *   - `import_batches`     — one row per import run (header + live counts).
 *   - `import_batch_rows`  — per-row action ledger; powers the error report
 *                            and inserts-only Undo.
 *   - `import_mappings`    — saved column mappings, reusable across runs.
 */
import { index, integer, jsonb, pgTable, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core';

import { ports } from './ports';

/** A saved or in-flight column mapping: target field key → source header. */
export type ImportMappingJson = Record<string, string>;

export const importBatches = pgTable(
  'import_batches',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    portId: text('port_id')
      .notNull()
      .references(() => ports.id, { onDelete: 'cascade' }),
    /** Which adapter this batch targets (ImportEntityKey). */
    entityType: text('entity_type').notNull(),
    filename: text('filename').notNull(),
    /** getStorageBackend() key of the uploaded file (re-read by the worker). */
    storageKey: text('storage_key'),
    /** uploaded | dry_run | committing | completed | failed | undone */
    status: text('status').notNull().default('uploaded'),
    /** skip-matches | update-matches | error-on-match */
    conflictPolicy: text('conflict_policy').notNull().default('skip-matches'),
    mappingJson: jsonb('mapping_json').$type<ImportMappingJson>(),
    totalRows: integer('total_rows').notNull().default(0),
    inserted: integer('inserted').notNull().default(0),
    updated: integer('updated').notNull().default(0),
    skipped: integer('skipped').notNull().default(0),
    errored: integer('errored').notNull().default(0),
    createdBy: text('created_by').notNull(),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
    completedAt: timestamp('completed_at', { withTimezone: true }),
  },
  (t) => [index('idx_import_batches_port').on(t.portId, t.createdAt)],
);

export const importBatchRows = pgTable(
  'import_batch_rows',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    batchId: text('batch_id')
      .notNull()
      .references(() => importBatches.id, { onDelete: 'cascade' }),
    /** 1-based source row number (after the header). */
    rowNumber: integer('row_number').notNull(),
    /** inserted | updated | skipped | errored */
    action: text('action').notNull(),
    /** Created/updated entity id (null for skipped/errored). */
    entityId: text('entity_id'),
    error: text('error'),
  },
  (t) => [index('idx_import_batch_rows_batch').on(t.batchId, t.rowNumber)],
);

export const importMappings = pgTable(
  'import_mappings',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    portId: text('port_id')
      .notNull()
      .references(() => ports.id, { onDelete: 'cascade' }),
    entityType: text('entity_type').notNull(),
    name: text('name').notNull(),
    mappingJson: jsonb('mapping_json').$type<ImportMappingJson>().notNull(),
    createdBy: text('created_by').notNull(),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (t) => [uniqueIndex('uniq_import_mappings_name').on(t.portId, t.entityType, t.name)],
);

export type ImportBatch = typeof importBatches.$inferSelect;
export type NewImportBatch = typeof importBatches.$inferInsert;
export type ImportBatchRow = typeof importBatchRows.$inferSelect;
export type ImportMapping = typeof importMappings.$inferSelect;
