-- Keep the accounting dashboard's accounts (accounting.accounts) reflected into
-- public.chart_of_accounts for PLATFORM associations, so every COA consumer
-- (Bill Approvals, bills, budgets, etc.) shows the same accounts and stays in
-- sync. One-way mirror, same id, so existing FKs + PostgREST embeds keep working.
create or replace function accounting.sync_account_to_public_coa()
returns trigger
language plpgsql
security definer
set search_path to 'public','accounting'
as $$
declare
  _assoc uuid;
  _system text;
  _parent uuid;
begin
  if tg_op = 'DELETE' then
    delete from public.chart_of_accounts where id = old.id;
    return old;
  end if;

  select c.association_id, a.accounting_system
    into _assoc, _system
  from accounting.companies c
  join public.associations a on a.id = c.association_id
  where c.id = new.company_id;

  -- Only mirror accounts the accounting dashboard actually manages (platform).
  -- If the association isn't on platform, ensure no stale mirror row lingers.
  if _system is distinct from 'platform' then
    delete from public.chart_of_accounts where id = new.id;
    return new;
  end if;

  -- Only point at a parent that already exists in the public table to satisfy
  -- the self-FK; hierarchy fills in as parents sync.
  _parent := null;
  if new.parent_account_id is not null then
    select id into _parent from public.chart_of_accounts where id = new.parent_account_id;
  end if;

  insert into public.chart_of_accounts as coa
    (id, association_id, account_number, account_name, account_type,
     parent_account_id, is_active, description, association_ids, accounting_system)
  values
    (new.id, _assoc, coalesce(new.code, ''), new.name, new.type::text,
     _parent, true, new.description, array[_assoc], 'platform')
  on conflict (id) do update set
    association_id    = excluded.association_id,
    account_number    = excluded.account_number,
    account_name      = excluded.account_name,
    account_type      = excluded.account_type,
    parent_account_id = excluded.parent_account_id,
    is_active         = true,
    description       = excluded.description,
    association_ids   = excluded.association_ids,
    accounting_system = 'platform',
    updated_at        = now();

  return new;
end;
$$;

drop trigger if exists trg_sync_account_to_public_coa on accounting.accounts;
create trigger trg_sync_account_to_public_coa
  after insert or update or delete on accounting.accounts
  for each row execute function accounting.sync_account_to_public_coa();

-- Backfill: mirror every existing platform account (parent left null for pass 1).
insert into public.chart_of_accounts
  (id, association_id, account_number, account_name, account_type,
   parent_account_id, is_active, description, association_ids, accounting_system)
select ac.id, c.association_id, coalesce(ac.code, ''), ac.name, ac.type::text,
       null, true, ac.description, array[c.association_id], 'platform'
from accounting.accounts ac
join accounting.companies c on c.id = ac.company_id
join public.associations a on a.id = c.association_id
where a.accounting_system = 'platform'
on conflict (id) do update set
  association_id    = excluded.association_id,
  account_number    = excluded.account_number,
  account_name      = excluded.account_name,
  account_type      = excluded.account_type,
  is_active         = true,
  description       = excluded.description,
  association_ids   = excluded.association_ids,
  accounting_system = 'platform',
  updated_at        = now();

-- Pass 2: wire up parent hierarchy now that all rows exist.
update public.chart_of_accounts coa
set parent_account_id = ac.parent_account_id, updated_at = now()
from accounting.accounts ac
where coa.id = ac.id
  and ac.parent_account_id is not null
  and exists (select 1 from public.chart_of_accounts p where p.id = ac.parent_account_id);

-- Hide legacy (buildium/zoho) COA rows for platform associations so pickers that
-- respect is_active show only the synced platform accounts. Nothing is deleted.
update public.chart_of_accounts coa
set is_active = false, updated_at = now()
from public.associations a
where a.id = coa.association_id
  and a.accounting_system = 'platform'
  and coalesce(coa.accounting_system, '') <> 'platform';
