import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * §12e Pay Supplier — supplier-side mirror of payment_collections.
 *
 * One row per Pay Supplier screen submission: a single payout event
 * that allocates a paid amount across N supplier-side settlements
 * (across N bookings + service types) under a shared voucher_no.
 *
 * Voucher prefix `PAY` lives in the same settlement_receipt_sequences
 * table as `RCP` / `RFD` so a tenant's series stays per-prefix without
 * a new sequence object.
 *
 * Append-only with admin-only void, matching payment_collections /
 * settlement_payments. Voiding a payout cascades to voiding every
 * child settlement_payment (handled in the service).
 */
export class SupplierPayouts1782300000000 implements MigrationInterface {
  name = 'SupplierPayouts1782300000000';

  public async up(qr: QueryRunner): Promise<void> {
    await qr.query(`
      CREATE TABLE supplier_payouts (
        id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
        tenant_id uuid NOT NULL,
        voucher_no varchar(20) NOT NULL,
        voucher_year integer NOT NULL,
        supplier_id uuid NOT NULL REFERENCES suppliers(id),
        supplier_name varchar(200),
        payment_date date NOT NULL,
        mode varchar(32) NOT NULL,
        ref_no varchar(100),
        currency_id uuid NOT NULL REFERENCES currencies(id),
        paid_amount numeric(12,2) NOT NULL,
        allocated_amount numeric(12,2) NOT NULL DEFAULT 0,
        excess_amount numeric(12,2) NOT NULL DEFAULT 0,
        notes text,
        is_void boolean NOT NULL DEFAULT false,
        voided_at timestamptz,
        voided_by uuid,
        void_reason text,
        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 supplier_payouts_paid_positive CHECK (paid_amount > 0),
        CONSTRAINT supplier_payouts_allocated_nonneg CHECK (allocated_amount >= 0),
        CONSTRAINT supplier_payouts_excess_nonneg CHECK (excess_amount >= 0),
        CONSTRAINT supplier_payouts_allocated_le_paid
          CHECK (allocated_amount <= paid_amount + 0.005)
      );
    `);

    await qr.query(`
      CREATE INDEX idx_supplier_payouts_tenant_supplier_date
        ON supplier_payouts (tenant_id, supplier_id, payment_date DESC);
    `);
    await qr.query(`
      CREATE INDEX idx_supplier_payouts_tenant_date
        ON supplier_payouts (tenant_id, payment_date DESC);
    `);
    await qr.query(`
      CREATE UNIQUE INDEX uq_supplier_payouts_tenant_voucher
        ON supplier_payouts (tenant_id, voucher_year, voucher_no);
    `);

    await qr.query(`
      ALTER TABLE settlement_payments
        ADD COLUMN payout_id uuid REFERENCES supplier_payouts(id) ON DELETE SET NULL;
    `);
    await qr.query(`
      CREATE INDEX idx_settlement_payments_payout
        ON settlement_payments (tenant_id, payout_id);
    `);
  }

  public async down(qr: QueryRunner): Promise<void> {
    await qr.query(`DROP INDEX IF EXISTS idx_settlement_payments_payout;`);
    await qr.query(`ALTER TABLE settlement_payments DROP COLUMN IF EXISTS payout_id;`);
    await qr.query(`DROP INDEX IF EXISTS uq_supplier_payouts_tenant_voucher;`);
    await qr.query(`DROP INDEX IF EXISTS idx_supplier_payouts_tenant_date;`);
    await qr.query(`DROP INDEX IF EXISTS idx_supplier_payouts_tenant_supplier_date;`);
    await qr.query(`DROP TABLE IF EXISTS supplier_payouts;`);
  }
}
