CREATE OR REPLACE FUNCTION public.sync_owner_balance_from_ledger()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  affected_owner_id uuid;
BEGIN
  affected_owner_id := COALESCE(NEW.owner_id, OLD.owner_id);

  IF affected_owner_id IS NOT NULL THEN
    UPDATE public.owners o
    SET balance = COALESCE((
      SELECT ROUND(SUM(COALESCE(ole.debit, 0) - COALESCE(ole.credit, 0))::numeric, 2)
      FROM public.owner_ledger_entries ole
      WHERE ole.owner_id = affected_owner_id
    ), 0)
    WHERE o.id = affected_owner_id;
  END IF;

  IF TG_OP = 'UPDATE' AND OLD.owner_id IS DISTINCT FROM NEW.owner_id AND OLD.owner_id IS NOT NULL THEN
    UPDATE public.owners o
    SET balance = COALESCE((
      SELECT ROUND(SUM(COALESCE(ole.debit, 0) - COALESCE(ole.credit, 0))::numeric, 2)
      FROM public.owner_ledger_entries ole
      WHERE ole.owner_id = OLD.owner_id
    ), 0)
    WHERE o.id = OLD.owner_id;
  END IF;

  RETURN COALESCE(NEW, OLD);
END;
$$;

DROP TRIGGER IF EXISTS sync_owner_balance_after_ledger_change ON public.owner_ledger_entries;

CREATE TRIGGER sync_owner_balance_after_ledger_change
AFTER INSERT OR UPDATE OR DELETE ON public.owner_ledger_entries
FOR EACH ROW
EXECUTE FUNCTION public.sync_owner_balance_from_ledger();