import * as migration from './migrations/20260626T130000-share-aliases';
import type {
  InsertableShareAlias,
  ShareAlias,
  UpdatableShareAlias,
} from './types/entity.types';

/**
 * Sanity checks for the share_aliases migration + entity types. We don't run a
 * live Postgres here (that's the integration suite); instead we assert the
 * migration exposes the expected up/down contract and creates the table with
 * the unique (workspace_id, alias) constraint and the page_id index, and that
 * the generated entity types line up with the column set.
 */
describe('share-aliases migration', () => {
  it('up creates the table, the unique index and the page_id index', async () => {
    const calls: string[] = [];

    const tableBuilder: any = new Proxy(
      {},
      {
        get(_t, prop: string) {
          if (prop === 'execute') return async () => undefined;
          // addColumn/addConstraint/etc. are chainable no-ops.
          return () => tableBuilder;
        },
      },
    );

    const indexBuilder: any = new Proxy(
      {},
      {
        get(_t, prop: string) {
          if (prop === 'execute') return async () => undefined;
          return () => indexBuilder;
        },
      },
    );

    const schema = {
      createTable: (name: string) => {
        calls.push(`createTable:${name}`);
        return tableBuilder;
      },
      createIndex: (name: string) => {
        calls.push(`createIndex:${name}`);
        return indexBuilder;
      },
    };

    await migration.up({ schema } as any);

    expect(calls).toContain('createTable:share_aliases');
    expect(calls).toContain(
      'createIndex:share_aliases_workspace_id_alias_unique',
    );
    expect(calls).toContain('createIndex:share_aliases_page_id_idx');
  });

  it('down drops the table', async () => {
    const calls: string[] = [];
    const dropBuilder: any = { execute: async () => undefined };
    const schema = {
      dropTable: (name: string) => {
        calls.push(`dropTable:${name}`);
        return dropBuilder;
      },
    };
    await migration.down({ schema } as any);
    expect(calls).toContain('dropTable:share_aliases');
  });

  it('entity types expose the alias columns', () => {
    // Compile-time only: these typed declarations fail `tsc` if the entity types
    // drift (missing/renamed columns, wrong nullability). The runtime assertions
    // would be tautological, so the value is purely in the type-check.
    const row: ShareAlias = {
      id: 'a-1',
      workspaceId: 'ws-1',
      alias: 'foo',
      pageId: 'p-1',
      creatorId: 'u-1',
      createdAt: new Date(),
      updatedAt: new Date(),
    };
    const insert: InsertableShareAlias = {
      workspaceId: 'ws-1',
      alias: 'foo',
    };
    const update: UpdatableShareAlias = { pageId: null };

    expect([row, insert, update]).toHaveLength(3);
  });
});
