/**
 * F-145 — Reporting: payment lines and POS cash-safe capture.
 *
 * Creates `reporting_payment_lines`, an immutable table of payment events per order
 * enriched with store/terminal/session/method — the reporting layer's view of payments.
 *
 * Immutability: no UPDATE path. A refund is a new row with status='refund'.
 *
 * Idempotency: `pgm.createTable` is already IF NOT EXISTS; the DO $$ block guards
 * against duplicate FK constraint errors on re-run (PG16 does NOT support
 * `ADD CONSTRAINT IF NOT EXISTS`).
 *
 * @param {import('node-pg-migrate').MigrationBuilder} pgm
 */

/** Table name */
const TABLE = 'reporting_payment_lines';

/** FK name for order_id */
const FK_ORDER = 'reporting_payment_lines_order_id_fkey';
/** FK name for store_id */
const FK_STORE = 'reporting_payment_lines_store_id_fkey';

export const up = (pgm) => {
  // ── Table ────────────────────────────────────────────────────────────────
  // `createTable` generates CREATE TABLE IF NOT EXISTS (PG>=9.6).
  pgm.createTable(
    TABLE,
    {
      id: { type: 'uuid', primaryKey: true, default: pgm.func('gen_random_uuid()') },
      order_id: { type: 'uuid', notNull: true },
      store_id: { type: 'uuid', notNull: true },
      terminal_id: { type: 'uuid' },
      cash_session_id: { type: 'uuid' },
      payment_method_id: { type: 'uuid' },
      provider: { type: 'text', notNull: true },
      amount_cents: { type: 'integer', notNull: true },
      currency: { type: 'text', notNull: true, default: "'EUR'" },
      status: { type: 'text', notNull: true },
      provider_ref: { type: 'text' },
      created_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
      updated_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
    },
    {
      // Inline CHECK constraint.
      constraints: {
        check: 'amount_cents != 0',
      },
    },
  );

  // ── Foreign Keys (guarded — PG16 does NOT support ADD CONSTRAINT IF NOT EXISTS) ─
  pgm.sql(`
    DO $$
    BEGIN
      IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = '${FK_ORDER}'
      ) THEN
        ALTER TABLE ${TABLE}
          ADD CONSTRAINT ${FK_ORDER}
          FOREIGN KEY (order_id) REFERENCES orders_orders(id)
          ON DELETE RESTRICT;
      END IF;

      IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = '${FK_STORE}'
      ) THEN
        ALTER TABLE ${TABLE}
          ADD CONSTRAINT ${FK_STORE}
          FOREIGN KEY (store_id) REFERENCES pos_stores(id)
          ON DELETE RESTRICT;
      END IF;
    END
    $$ LANGUAGE plpgsql;
  `);

  // ── Indexes ─────────────────────────────────────────────────────────────
  pgm.createIndex(TABLE, ['store_id', 'created_at'], {
    name: 'reporting_payment_lines_store_created_idx',
  });
  pgm.createIndex(TABLE, 'order_id', { name: 'reporting_payment_lines_order_idx' });
  pgm.createIndex(
    TABLE,
    'cash_session_id',
    {
      name: 'reporting_payment_lines_session_idx',
      where: 'cash_session_id IS NOT NULL',
    },
  );
};

export const down = (pgm) => {
  pgm.dropIndex(TABLE, 'cash_session_id', {
    name: 'reporting_payment_lines_session_idx',
    ifExists: true,
  });
  pgm.dropIndex(TABLE, 'order_id', {
    name: 'reporting_payment_lines_order_idx',
    ifExists: true,
  });
  pgm.dropIndex(TABLE, ['store_id', 'created_at'], {
    name: 'reporting_payment_lines_store_created_idx',
    ifExists: true,
  });
  pgm.dropTable(TABLE, { ifExists: true });
};
