/**
 * Reconciliation migration — favorites system (B4 of reconcile-historical-add-scripts).
 *
 * Captures the DDL effects of the historical `scripts/add-favorites-system.js`
 * job, which has been applied to every long-lived environment but is NOT
 * reproduced by the post-migration-tool history on a fresh Neon branch. After
 * this migration lands, `npm install` → `npm run setup-db` against a clean
 * branch produces a `user_favorites` table that is structurally equivalent to
 * prod (same columns, same UNIQUE tuple, same four supporting indexes).
 *
 * Source script (READ ONLY, per `.cursor/rules/no-go-zones.mdc`):
 *   scripts/add-favorites-system.js
 *
 * Runtime evidence the table exists in prod and that this is the exact shape
 * the API expects:
 *   pages/api/favorites.js — SELECT / INSERT / DELETE against
 *     `user_favorites` keyed by (user_id, item_type, item_id), with
 *     item_type ∈ {'card', 'collection', 'deck'} and a polymorphic item_id.
 *
 * Idempotency (convoy D2):
 *   - `CREATE TABLE IF NOT EXISTS` — re-applying against any env where the
 *     historical script already ran is a documented no-op.
 *   - `CREATE INDEX IF NOT EXISTS` — same idempotency contract for all four
 *     indexes.
 *   - `UNIQUE(user_id, item_type, item_id)` is declared inline on the table
 *     so it is created at the same moment as the table and never needs a
 *     separate guarded `ADD CONSTRAINT` path.
 *
 * Shape parity with the historical script:
 *   - Same column set (id SERIAL PK, user_id INTEGER FK CASCADE,
 *     item_type VARCHAR(50) NOT NULL, item_id INTEGER NOT NULL,
 *     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP).
 *   - Same UNIQUE tuple.
 *   - Same four index definitions (single-column on user_id, item_type,
 *     item_id; composite (user_id, item_type)).
 *   - Same index naming (idx_user_favorites_*).
 *
 * FK style follows `migrations/1779853647564_initial-schema.js` —
 * `INTEGER REFERENCES users(id) ON DELETE CASCADE`, no separate FK
 * constraint name.
 *
 * Down-migration is a hard stub: this is a reconciliation migration whose
 * purpose is to bring fresh envs to parity with prod; rolling back would
 * drop `user_favorites` on prod, which is a destructive operation that
 * deserves its own scoped convoy.
 *
 * Note on schema-map terminology drift:
 *   `.cursor/rules/schema-map.mdc` § "Common reference" mentions
 *   `favorites (user_id, card_id)` — that line is a minimal shorthand and
 *   does NOT match the actual prod table (`user_favorites`, polymorphic on
 *   item_type + item_id, per `pages/api/favorites.js`). The rule's wording
 *   is updated by B7 of this convoy; this migration follows the runtime
 *   evidence.
 *
 * @type {import('node-pg-migrate').ColumnDefinitions | undefined}
 */
export const shorthands = undefined;

/**
 * @param {import('node-pg-migrate').MigrationBuilder} pgm
 * @returns {void}
 */
export const up = (pgm) => {
  pgm.sql(`
    CREATE TABLE IF NOT EXISTS user_favorites (
      id SERIAL PRIMARY KEY,
      user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
      item_type VARCHAR(50) NOT NULL,
      item_id INTEGER NOT NULL,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      UNIQUE(user_id, item_type, item_id)
    )
  `);

  pgm.sql(`
    CREATE INDEX IF NOT EXISTS idx_user_favorites_user_id
      ON user_favorites(user_id);
    CREATE INDEX IF NOT EXISTS idx_user_favorites_item_type
      ON user_favorites(item_type);
    CREATE INDEX IF NOT EXISTS idx_user_favorites_item_id
      ON user_favorites(item_id);
    CREATE INDEX IF NOT EXISTS idx_user_favorites_user_type
      ON user_favorites(user_id, item_type);
  `);
};

/**
 * @returns {void}
 */
export const down = () => {
  throw new Error(
    '[migration:1781000000004_reconcile-favorites-system] Refusing to drop user_favorites. ' +
      'This is a reconciliation migration that brings fresh envs to parity with prod; rolling it ' +
      'back would drop the user_favorites table (and every row in it) on whatever env it runs against. ' +
      'If you need to remove the favorites system, ship a dedicated convoy with a real down() that ' +
      'audits readers (pages/api/favorites.js + any UI surfaces) first.'
  );
};
