import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * Communication Templates — master for tenant-configurable Email +
 * WhatsApp message bodies.
 *
 * One row per (channel, context, name). Templates are context-scoped
 * — Query / Booking / Movement Dashboard — so the caller (a Copy
 * button on the relevant page) fetches ONLY templates that belong to
 * its context. The user picks a template when multiple exist within
 * that scope; otherwise the row flagged is_default = true is used.
 *
 * body_template holds a mustache-lite string: `{{var}}` for simple
 * substitution and `{{#each list}} … {{/each}}` for iteration. The
 * renderer service (see communication-template.renderer.ts) walks
 * a JSON bag emitted by a per-context resolver.
 *
 * `subject` is populated only when channel = 'EMAIL' (WhatsApp is
 * body-only). Kept nullable on the schema so the DTO can validate.
 *
 * The partial unique index enforces "at most one default per tenant
 * × channel × context" — the FE "make default" action clears the
 * previous one in the same bucket.
 */
export class CommunicationTemplates1782500000000 implements MigrationInterface {
  name = 'CommunicationTemplates1782500000000';

  public async up(qr: QueryRunner): Promise<void> {
    await qr.query(`
      CREATE TABLE communication_templates (
        id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
        tenant_id uuid NOT NULL,
        channel varchar(20) NOT NULL,
        context varchar(20) NOT NULL,
        name varchar(120) NOT NULL,
        subject varchar(200),
        body_template text NOT NULL,
        is_default boolean NOT NULL DEFAULT false,
        is_active boolean NOT NULL DEFAULT true,
        is_deleted boolean NOT NULL DEFAULT false,
        created_by uuid,
        updated_by uuid,
        created_at timestamptz NOT NULL DEFAULT now(),
        updated_at timestamptz NOT NULL DEFAULT now(),
        CONSTRAINT communication_templates_channel_chk
          CHECK (channel IN ('EMAIL','WHATSAPP')),
        CONSTRAINT communication_templates_context_chk
          CHECK (context IN ('QUERY','BOOKING','MOVEMENT')),
        CONSTRAINT communication_templates_email_subject_chk
          CHECK (channel <> 'EMAIL' OR subject IS NOT NULL)
      );
    `);
    await qr.query(`
      CREATE INDEX idx_communication_templates_tenant_channel_context
        ON communication_templates (tenant_id, channel, context)
       WHERE is_deleted = false;
    `);
    // "One default per (tenant, channel, context)" — partial unique
    // index skips soft-deleted rows and any row where is_default = false.
    await qr.query(`
      CREATE UNIQUE INDEX uq_communication_templates_default_per_bucket
        ON communication_templates (tenant_id, channel, context)
       WHERE is_default = true AND is_deleted = false;
    `);
  }

  public async down(qr: QueryRunner): Promise<void> {
    await qr.query(`DROP INDEX IF EXISTS uq_communication_templates_default_per_bucket;`);
    await qr.query(`DROP INDEX IF EXISTS idx_communication_templates_tenant_channel_context;`);
    await qr.query(`DROP TABLE IF EXISTS communication_templates;`);
  }
}
