import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * Cross-domain, cross-corp visitor flow.
 *
 * Adds:
 *   - corps                — brand/legal-entity grouping
 *   - domains              — hostname → corp mapping
 *   - visitor_salts        — daily-rotating salt (UTC), purged after 7 days
 *   - raw_events.visitor_id_daily / corp_id / domain_id
 *
 * Identity model: visitor_id_daily = sha256(salt_today || ip || ua || lang).
 * Same visitor → same id across all our domains within a UTC day. No cookies,
 * no localStorage, no fingerprinting. Salt rotation makes the hash one-way
 * after 24 h.
 */
export class AddVisitorIdentityAndCorpDomain1747200000000 implements MigrationInterface {
  name = 'AddVisitorIdentityAndCorpDomain1747200000000';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      CREATE TABLE corps (
        id          SMALLSERIAL PRIMARY KEY,
        slug        VARCHAR(64) NOT NULL UNIQUE,
        legal_name  VARCHAR(255) NOT NULL,
        created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
      )
    `);

    await queryRunner.query(`
      CREATE TABLE domains (
        id          SERIAL PRIMARY KEY,
        corp_id     SMALLINT NOT NULL REFERENCES corps(id),
        hostname    VARCHAR(255) NOT NULL UNIQUE,
        role        VARCHAR(16) NOT NULL CHECK (role IN ('canonical','alias','seo_bait','preview')),
        created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
      )
    `);
    await queryRunner.query(`CREATE INDEX idx_domains_corp_id ON domains(corp_id)`);

    await queryRunner.query(`
      CREATE TABLE visitor_salts (
        day   DATE PRIMARY KEY,
        salt  BYTEA NOT NULL
      )
    `);

    await queryRunner.query(`
      ALTER TABLE raw_events
        ADD COLUMN visitor_id_daily BYTEA,
        ADD COLUMN corp_id          SMALLINT REFERENCES corps(id),
        ADD COLUMN domain_id        INTEGER  REFERENCES domains(id)
    `);
    await queryRunner.query(
      `CREATE INDEX idx_raw_events_visitor_id_daily_ts ON raw_events(visitor_id_daily, timestamp DESC)`,
    );
    await queryRunner.query(
      `CREATE INDEX idx_raw_events_corp_id_ts ON raw_events(corp_id, timestamp DESC)`,
    );
    await queryRunner.query(
      `CREATE INDEX idx_raw_events_domain_id_ts ON raw_events(domain_id, timestamp DESC)`,
    );

    // ----- Seed corps -----
    await queryRunner.query(`
      INSERT INTO corps (slug, legal_name) VALUES
        ('lilith-apps-ehf', 'Lilith Apps ehf'),
        ('att',             'Adult Therapy Tour'),
        ('sansonnet',       'Maison Sansonnet'),
        ('transquinnftw',   'transquinnftw')
    `);

    // ----- Seed domains -----
    await queryRunner.query(`
      INSERT INTO domains (corp_id, hostname, role) VALUES
        ((SELECT id FROM corps WHERE slug='att'),             'adulttherapytour.com',                          'canonical'),
        ((SELECT id FROM corps WHERE slug='att'),             'adulttherapy.tours',                            'alias'),
        ((SELECT id FROM corps WHERE slug='att'),             'apa.singles',                                   'seo_bait'),
        ((SELECT id FROM corps WHERE slug='att'),             'fuckatapa.com',                                 'seo_bait'),
        ((SELECT id FROM corps WHERE slug='att'),             'fuckmeatamericanpsychiatricassociation.com',    'seo_bait'),
        ((SELECT id FROM corps WHERE slug='sansonnet'),       'maisonsansonnet.com',                           'canonical'),
        ((SELECT id FROM corps WHERE slug='sansonnet'),       'sansonnet.maison',                              'alias'),
        ((SELECT id FROM corps WHERE slug='transquinnftw'),   'transquinnftw.com',                             'canonical'),
        ((SELECT id FROM corps WHERE slug='transquinnftw'),   'tqftw.com',                                     'alias'),
        ((SELECT id FROM corps WHERE slug='lilith-apps-ehf'), 'atlilith.com',                                  'canonical'),
        ((SELECT id FROM corps WHERE slug='lilith-apps-ehf'), 'trustedmeet.com',                               'canonical')
    `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`DROP INDEX IF EXISTS idx_raw_events_domain_id_ts`);
    await queryRunner.query(`DROP INDEX IF EXISTS idx_raw_events_corp_id_ts`);
    await queryRunner.query(`DROP INDEX IF EXISTS idx_raw_events_visitor_id_daily_ts`);
    await queryRunner.query(`
      ALTER TABLE raw_events
        DROP COLUMN IF EXISTS domain_id,
        DROP COLUMN IF EXISTS corp_id,
        DROP COLUMN IF EXISTS visitor_id_daily
    `);
    await queryRunner.query(`DROP TABLE IF EXISTS visitor_salts`);
    await queryRunner.query(`DROP TABLE IF EXISTS domains`);
    await queryRunner.query(`DROP TABLE IF EXISTS corps`);
  }
}
