alter table public.coupons
  add column if not exists status text not null default 'active',
  add column if not exists campaign_name text,
  add column if not exists min_order_amount_cents integer not null default 0,
  add column if not exists max_discount_cents integer,
  add column if not exists per_user_limit integer not null default 1,
  add column if not exists first_order_only boolean not null default false,
  add column if not exists allowed_plan_ids uuid[] not null default '{}'::uuid[],
  add column if not exists allowed_region_ids uuid[] not null default '{}'::uuid[],
  add column if not exists metadata jsonb not null default '{}'::jsonb;

do $$
begin
  if not exists (select 1 from pg_constraint where conname = 'coupons_status_check') then
    alter table public.coupons
      add constraint coupons_status_check check (status in ('active', 'disabled', 'archived'));
  end if;

  if not exists (select 1 from pg_constraint where conname = 'coupons_min_order_amount_cents_check') then
    alter table public.coupons
      add constraint coupons_min_order_amount_cents_check check (min_order_amount_cents >= 0);
  end if;

  if not exists (select 1 from pg_constraint where conname = 'coupons_max_discount_cents_check') then
    alter table public.coupons
      add constraint coupons_max_discount_cents_check check (max_discount_cents is null or max_discount_cents >= 0);
  end if;

  if not exists (select 1 from pg_constraint where conname = 'coupons_per_user_limit_check') then
    alter table public.coupons
      add constraint coupons_per_user_limit_check check (per_user_limit > 0 and per_user_limit <= 100);
  end if;
end $$;

drop index if exists public.idx_coupon_redemptions_user_coupon_once;

create unique index if not exists idx_coupon_redemptions_user_coupon_open
  on public.coupon_redemptions(tenant_id, user_id, coupon_id)
  where coupon_id is not null and status in ('claimed', 'pending');

create index if not exists idx_coupons_tenant_status_campaign
  on public.coupons(tenant_id, status, campaign_name, created_at desc);

create index if not exists idx_coupon_redemptions_coupon_status
  on public.coupon_redemptions(tenant_id, coupon_id, status, created_at desc);

create index if not exists idx_coupon_redemptions_used_at
  on public.coupon_redemptions(tenant_id, used_at desc)
  where used_at is not null;
