/**
 * CLUB-001 — Club de Clientes core backend.
 *
 * Phase 1 schema:
 * - anonymous members + device tokens
 * - ledger transactions as source of truth
 * - future-ready recovery/campaign/reward tables
 * - club config seeds in store_settings
 */

/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
export const up = (pgm) => {
  pgm.sql(`
    CREATE TABLE IF NOT EXISTS club_members (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      user_id uuid REFERENCES identity_users(id) ON DELETE SET NULL,
      member_code text NOT NULL UNIQUE,
      status text NOT NULL DEFAULT 'active',
      tier_code text NOT NULL DEFAULT 'base',
      current_balance_cents integer NOT NULL DEFAULT 0,
      created_at timestamptz NOT NULL DEFAULT now(),
      updated_at timestamptz NOT NULL DEFAULT now(),
      CONSTRAINT club_members_status_check CHECK (status IN ('active', 'blocked', 'merged')),
      CONSTRAINT club_members_balance_non_negative CHECK (current_balance_cents >= 0),
      CONSTRAINT club_members_member_code_format CHECK (member_code ~ '^MDV-[A-Z0-9]{8}$')
    )
  `);

  pgm.sql(`
    CREATE UNIQUE INDEX IF NOT EXISTS club_members_user_id_unique_idx
      ON club_members (user_id)
      WHERE user_id IS NOT NULL
  `);

  pgm.sql(`
    CREATE TABLE IF NOT EXISTS club_devices (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      member_id uuid NOT NULL REFERENCES club_members(id) ON DELETE CASCADE,
      device_token_hash text NOT NULL UNIQUE,
      last_used_at timestamptz NOT NULL DEFAULT now(),
      created_at timestamptz NOT NULL DEFAULT now(),
      revoked_at timestamptz
    )
  `);
  pgm.sql(`CREATE INDEX IF NOT EXISTS club_devices_member_id_idx ON club_devices (member_id)`);

  pgm.sql(`
    CREATE TABLE IF NOT EXISTS club_campaigns (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      name text NOT NULL,
      kind text NOT NULL DEFAULT 'generic',
      status text NOT NULL DEFAULT 'draft',
      config jsonb NOT NULL DEFAULT '{}'::jsonb,
      starts_at timestamptz,
      ends_at timestamptz,
      created_at timestamptz NOT NULL DEFAULT now(),
      updated_at timestamptz NOT NULL DEFAULT now(),
      CONSTRAINT club_campaigns_status_check CHECK (status IN ('draft', 'active', 'archived'))
    )
  `);

  pgm.sql(`
    CREATE TABLE IF NOT EXISTS club_transactions (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      member_id uuid NOT NULL REFERENCES club_members(id) ON DELETE CASCADE,
      sale_id uuid REFERENCES orders_orders(id) ON DELETE SET NULL,
      store_id uuid REFERENCES pos_stores(id) ON DELETE SET NULL,
      type text NOT NULL,
      amount_cents integer NOT NULL DEFAULT 0,
      balance_delta_cents integer NOT NULL,
      idempotency_key text UNIQUE,
      metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
      created_at timestamptz NOT NULL DEFAULT now(),
      CONSTRAINT club_transactions_type_check CHECK (type IN ('earn', 'redeem', 'refund', 'bonus', 'adjustment')),
      CONSTRAINT club_transactions_amount_non_negative CHECK (amount_cents >= 0),
      CONSTRAINT club_transactions_balance_delta_non_zero CHECK (balance_delta_cents <> 0)
    )
  `);
  pgm.sql(`
    CREATE INDEX IF NOT EXISTS club_transactions_member_id_created_at_idx
      ON club_transactions (member_id, created_at DESC)
  `);
  pgm.sql(`CREATE INDEX IF NOT EXISTS club_transactions_sale_id_idx ON club_transactions (sale_id)`);

  pgm.sql(`
    CREATE TABLE IF NOT EXISTS club_recovery_codes (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      member_id uuid NOT NULL REFERENCES club_members(id) ON DELETE CASCADE,
      code_hash text NOT NULL,
      code_fingerprint text NOT NULL UNIQUE,
      used_at timestamptz,
      expires_at timestamptz,
      created_at timestamptz NOT NULL DEFAULT now()
    )
  `);
  pgm.sql(`CREATE INDEX IF NOT EXISTS club_recovery_codes_member_id_idx ON club_recovery_codes (member_id)`);

  pgm.sql(`
    CREATE TABLE IF NOT EXISTS club_rewards (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      member_id uuid NOT NULL REFERENCES club_members(id) ON DELETE CASCADE,
      campaign_id uuid REFERENCES club_campaigns(id) ON DELETE SET NULL,
      status text NOT NULL DEFAULT 'available',
      label text NOT NULL,
      amount_cents integer,
      metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
      expires_at timestamptz,
      created_at timestamptz NOT NULL DEFAULT now(),
      updated_at timestamptz NOT NULL DEFAULT now(),
      CONSTRAINT club_rewards_status_check CHECK (status IN ('available', 'redeemed', 'expired', 'cancelled'))
    )
  `);
  pgm.sql(`CREATE INDEX IF NOT EXISTS club_rewards_member_id_idx ON club_rewards (member_id)`);

  pgm.sql(`
    INSERT INTO store_settings (key, value) VALUES
      ('club_enabled', 'true'),
      ('club_cashback_bps', '200'),
      ('club_allow_anonymous_members', 'true'),
      ('club_allow_recovery_codes', 'true'),
      ('club_minimum_redeem_cents', '500')
    ON CONFLICT (key) DO NOTHING
  `);
};

/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
export const down = (pgm) => {
  pgm.sql(`DELETE FROM store_settings WHERE key IN (
    'club_enabled',
    'club_cashback_bps',
    'club_allow_anonymous_members',
    'club_allow_recovery_codes',
    'club_minimum_redeem_cents'
  )`);
  pgm.sql('DROP INDEX IF EXISTS club_rewards_member_id_idx');
  pgm.sql('DROP TABLE IF EXISTS club_rewards');
  pgm.sql('DROP INDEX IF EXISTS club_recovery_codes_member_id_idx');
  pgm.sql('DROP TABLE IF EXISTS club_recovery_codes');
  pgm.sql('DROP INDEX IF EXISTS club_transactions_sale_id_idx');
  pgm.sql('DROP INDEX IF EXISTS club_transactions_member_id_created_at_idx');
  pgm.sql('DROP TABLE IF EXISTS club_transactions');
  pgm.sql('DROP TABLE IF EXISTS club_campaigns');
  pgm.sql('DROP INDEX IF EXISTS club_devices_member_id_idx');
  pgm.sql('DROP TABLE IF EXISTS club_devices');
  pgm.sql('DROP INDEX IF EXISTS club_members_user_id_unique_idx');
  pgm.sql('DROP TABLE IF EXISTS club_members');
};
