alter table public.subcontractor_payments
  add column if not exists po_number text,
  add column if not exists project_id uuid references public.projects(id) on delete set null,
  add column if not exists due_date date,
  add column if not exists terms text default 'Net 15',
  add column if not exists sent_at timestamptz,
  add column if not exists approved_at timestamptz,
  add column if not exists cancelled_at timestamptz;

alter table public.subcontractor_payments
  drop constraint if exists subcontractor_payments_status_check;

update public.subcontractor_payments
set status = 'ready_to_pay'
where status = 'pending';

alter table public.subcontractor_payments
  add constraint subcontractor_payments_status_check
  check (status in ('draft', 'sent', 'approved', 'ready_to_pay', 'paid', 'cancelled'));

with numbered as (
  select
    id,
    'PO-' || to_char(coalesce(created_at, now()), 'YYYY') || '-' || lpad((row_number() over (order by created_at, id))::text, 4, '0') as generated_po_number
  from public.subcontractor_payments
  where po_number is null
)
update public.subcontractor_payments sp
set po_number = numbered.generated_po_number
from numbered
where sp.id = numbered.id;

create unique index if not exists subcontractor_payments_po_number_key
  on public.subcontractor_payments(po_number)
  where po_number is not null;

drop policy if exists "External reads own subcontractor purchase orders" on public.subcontractor_payments;
create policy "External reads own subcontractor purchase orders" on public.subcontractor_payments
  for select using (
    get_my_role() = 'external'
    and profile_id = auth.uid()
  );

drop policy if exists "External updates own subcontractor purchase orders" on public.subcontractor_payments;
create policy "External updates own subcontractor purchase orders" on public.subcontractor_payments
  for update using (
    get_my_role() = 'external'
    and profile_id = auth.uid()
  ) with check (
    get_my_role() = 'external'
    and profile_id = auth.uid()
  );
