export async function migrate(pool) {
  await pool.query("create extension if not exists timescaledb");
  await pool.query("create extension if not exists postgis");

  await pool.query(`
    create table if not exists gelios_connections (
      tenant_id text not null,
      connection_id text not null,
      provider_id text not null default 'gelios',
      unit_scope text not null default 'allowlist',
      allowed_unit_ids jsonb not null default '[]'::jsonb,
      collection_enabled boolean not null default false,
      created_at timestamptz not null default now(),
      updated_at timestamptz not null default now(),
      primary key (tenant_id, connection_id)
    )
  `);
  await pool.query("alter table gelios_connections add column if not exists unit_scope text not null default 'allowlist'");

  await pool.query(`
    create table if not exists gelios_collection_runs (
      id uuid primary key,
      tenant_id text not null,
      connection_id text not null,
      capability_id text not null,
      status text not null,
      unit_count integer not null default 0,
      inserted_snapshots integer not null default 0,
      error_code text,
      started_at timestamptz not null default now(),
      completed_at timestamptz,
      foreign key (tenant_id, connection_id)
        references gelios_connections (tenant_id, connection_id)
        on delete cascade
    )
  `);

  await pool.query(`
    create table if not exists gelios_raw_envelopes (
      id uuid primary key,
      tenant_id text not null,
      connection_id text not null,
      collection_run_id uuid references gelios_collection_runs(id) on delete set null,
      capability_id text not null,
      payload_hash text not null,
      payload jsonb not null,
      payload_bytes integer not null,
      received_at timestamptz not null,
      expires_at timestamptz not null,
      unique (tenant_id, connection_id, capability_id, payload_hash)
    )
  `);
  await pool.query("create index if not exists gelios_raw_envelopes_expiry_idx on gelios_raw_envelopes (expires_at)");

  await pool.query(`
    create table if not exists gelios_units (
      tenant_id text not null,
      connection_id text not null,
      source_unit_id bigint not null,
      stable_subject_id text not null,
      name text not null,
      first_seen_at timestamptz not null default now(),
      last_seen_at timestamptz not null default now(),
      primary key (tenant_id, connection_id, source_unit_id),
      unique (tenant_id, connection_id, stable_subject_id),
      foreign key (tenant_id, connection_id)
        references gelios_connections (tenant_id, connection_id)
        on delete cascade
    )
  `);

  await pool.query(`
    create table if not exists gelios_unit_current (
      tenant_id text not null,
      connection_id text not null,
      source_unit_id bigint not null,
      stable_subject_id text not null,
      name text not null,
      observed_at timestamptz not null,
      received_at timestamptz not null,
      latitude double precision,
      longitude double precision,
      position geography(Point, 4326),
      speed double precision,
      course double precision,
      gps_valid boolean,
      satellites double precision,
      hdop double precision,
      accuracy_m double precision,
      telemetry jsonb not null,
      fingerprint text not null,
      updated_at timestamptz not null default now(),
      primary key (tenant_id, connection_id, source_unit_id),
      foreign key (tenant_id, connection_id, source_unit_id)
        references gelios_units (tenant_id, connection_id, source_unit_id)
        on delete cascade
    )
  `);
  await pool.query("create index if not exists gelios_unit_current_position_idx on gelios_unit_current using gist (position)");
  await pool.query("create index if not exists gelios_unit_current_observed_idx on gelios_unit_current (tenant_id, connection_id, observed_at desc)");

  await pool.query(`
    create table if not exists gelios_telemetry_snapshots (
      tenant_id text not null,
      connection_id text not null,
      source_unit_id bigint not null,
      observed_at timestamptz not null,
      received_at timestamptz not null,
      fingerprint text not null,
      telemetry jsonb not null,
      primary key (tenant_id, connection_id, source_unit_id, observed_at, fingerprint)
    )
  `);
  await pool.query("select create_hypertable('gelios_telemetry_snapshots', 'observed_at', if_not_exists => true, migrate_data => true)");
  await pool.query("create index if not exists gelios_snapshots_unit_time_idx on gelios_telemetry_snapshots (tenant_id, connection_id, source_unit_id, observed_at desc)");
}
