import { Kysely, sql } from 'kysely'
import { addDefaultColumns } from '../db';

export async function up(db: Kysely<any>): Promise<void> {
    // TABLE: EVENTS
    await db.schema.createTable("events")
        .$call(addDefaultColumns)
        .addColumn("group", "text", (cb) => cb.notNull())
        .addColumn("type", "text", (cb) => cb.notNull())
        .addColumn("source", "text", (cb) => cb.notNull())
        .addColumn("payload", "jsonb", (cb) => cb.notNull())
        .addColumn("state", "jsonb")
        .addColumn("heartbeat_at", "timestamptz")
        .addColumn("started_at", "timestamptz")
        .addColumn("ended_at", "timestamptz")
        .addColumn("available_at", "timestamptz", (cb) => cb.notNull().defaultTo(sql`now()`))
        .addColumn("errors", "integer", (cb) => cb.notNull().defaultTo(0))
        .addColumn("rate_limits", "integer", (cb) => cb.notNull().defaultTo(0))
        .addColumn("has_failed", "boolean", (cb) => cb.notNull().defaultTo(false))
        .addColumn("last_error", "jsonb")
        .addColumn("dedupe_key", "text")
        .execute()

    await db.schema.createIndex("events_idx_dedupe_key")
        .on("events")
        .columns(["group", "type", "dedupe_key"])
        .unique()
        .where("dedupe_key", "is not", null)
        .where(sql.ref("ended_at"), "is", null)
        .execute()

    // TABLE: STANDARDS_DATASETS
    await db.schema.createTable("standards_datasets")
        .$call(addDefaultColumns)
        .addColumn("name", "text", (cb) => cb.notNull().defaultTo(""))
        .addColumn("data", "jsonb", (cb) => cb.notNull())
        .execute();

    // TABLE: STANDARDS_CONFIGS
    await db.schema.createTable("standards_configs")
        .$call(addDefaultColumns)
        .addColumn("name", "text", (cb) => cb.notNull().defaultTo(""))
        .addColumn("params", "jsonb", (cb) => cb.notNull())
        .addColumn("dataset_id", "bigint", (cb) => cb.notNull())
        .addForeignKeyConstraint(
            "fk_standards_configs_dataset_id",
            ["dataset_id"],
            "standards_datasets",
            ["id"],
            (cb) => cb.onDelete("restrict")
        )
        .execute();

    // TABLE: CALCULATORS
    await db.schema.createTable("calculators")
        .$call(addDefaultColumns)
        .addColumn("name", "text", (cb) => cb.notNull().unique())
        .addColumn("standards_config_id", "bigint", (cb) => cb.notNull())
        .addForeignKeyConstraint(
            "fk_calculators_standards_config_id",
            ["standards_config_id"],
            "standards_configs",
            ["id"],
            (cb) => cb.onDelete("restrict")
        )
        .execute();
}

export async function down(db: Kysely<any>): Promise<void> {
    // TABLE: EVENTS
    await db.schema.dropTable("events").ifExists().execute()

    await db.schema.dropIndex("events_idx_dedupe_key").ifExists().execute();

    // TABLE: CALCULATORS
    await db.schema.dropTable("calculators").ifExists().execute()

    // TABLE: STANDARDS_CONFIGS
    await db.schema.dropTable("standards_configs").ifExists().execute()

    // TABLE: STANDARDS_DATASETS
    await db.schema.dropTable("standards_datasets").ifExists().execute()
}
