import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * Refresh-token session store.
 *
 * Stores SHA-256 digests of issued refresh tokens (never plaintext),
 * per-family for rotation reuse-detection. See RefreshTokenEntity
 * header for the full rotation contract.
 */
export class RefreshTokens1785500000000 implements MigrationInterface {
  name = 'RefreshTokens1785500000000';

  public async up(q: QueryRunner): Promise<void> {
    await q.query(`
      CREATE TABLE "refresh_tokens" (
        "id"                UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
        "tenant_id"         UUID NOT NULL,
        "user_id"           UUID NOT NULL,
        "family_id"         UUID NOT NULL,
        "token_hash"        VARCHAR(64) NOT NULL,
        "expires_at"        TIMESTAMPTZ NOT NULL,
        "used_at"           TIMESTAMPTZ NULL,
        "revoked_at"        TIMESTAMPTZ NULL,
        "issued_ip"         VARCHAR(45) NULL,
        "issued_user_agent" TEXT NULL,
        "created_at"        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
        "is_deleted"        BOOLEAN NOT NULL DEFAULT FALSE,
        CONSTRAINT "FK_refresh_tokens_user"
          FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
      )
    `);

    // Unique on active hashes — rotated / soft-deleted rows drop out.
    await q.query(`
      CREATE UNIQUE INDEX "IDX_refresh_tokens_token_hash"
        ON "refresh_tokens" ("token_hash")
        WHERE "is_deleted" = false
    `);

    // Fast lookup of a user's live tokens (rotation + logout paths).
    await q.query(`
      CREATE INDEX "IDX_refresh_tokens_user_active"
        ON "refresh_tokens" ("user_id")
        WHERE "used_at" IS NULL AND "is_deleted" = false
    `);

    // Family sweep on reuse detection.
    await q.query(`
      CREATE INDEX "IDX_refresh_tokens_family"
        ON "refresh_tokens" ("family_id")
    `);
  }

  public async down(q: QueryRunner): Promise<void> {
    await q.query(`DROP INDEX IF EXISTS "IDX_refresh_tokens_family"`);
    await q.query(`DROP INDEX IF EXISTS "IDX_refresh_tokens_user_active"`);
    await q.query(`DROP INDEX IF EXISTS "IDX_refresh_tokens_token_hash"`);
    await q.query(`DROP TABLE IF EXISTS "refresh_tokens"`);
  }
}
