-- ============================================================================
-- create_financial_record_for_session: idempotência ignora cancelled
-- ----------------------------------------------------------------------------
-- Bug: a função recusava criar um novo financial_record quando já existia
-- um record cancelled pro mesmo agenda_evento_id, porque a checagem de
-- idempotência só filtrava `deleted_at IS NULL` (e cancel preserva
-- deleted_at = NULL pra manter auditoria).
--
-- Consequência: user cancelava cobrança sem querer e ficava preso — todo
-- "Gerar cobrança" subsequente retornava o registro cancelado sem inserir
-- nova linha (frontend recebia data, achava sucesso, mas DB ficava como
-- estava).
--
-- Fix: adiciona `AND status != 'cancelled'` na checagem. Cancelled passa a
-- ser tratado como "sem cobrança ativa" pra idempotência. Audit history
-- continua preservado (rows cancelled permanecem na tabela).
--
-- Idempotente: CREATE OR REPLACE substitui a função existente.
-- ============================================================================

BEGIN;

CREATE OR REPLACE FUNCTION public.create_financial_record_for_session(
    p_tenant_id uuid,
    p_owner_id uuid,
    p_patient_id uuid,
    p_agenda_evento_id uuid,
    p_amount numeric,
    p_due_date date
) RETURNS SETOF public.financial_records
    LANGUAGE plpgsql SECURITY DEFINER
    SET search_path TO 'public'
    AS $$
DECLARE
  v_existing public.financial_records%ROWTYPE;
  v_new      public.financial_records%ROWTYPE;
BEGIN
  -- Idempotência: retorna o registro existente se já foi criado.
  -- Ignora cancelled (treat as "no active record") pra permitir regenerar
  -- cobrança após cancelamento.
  SELECT * INTO v_existing
  FROM public.financial_records
  WHERE agenda_evento_id = p_agenda_evento_id
    AND deleted_at IS NULL
    AND status != 'cancelled'
  LIMIT 1;

  IF FOUND THEN
    RETURN NEXT v_existing;
    RETURN;
  END IF;

  -- Cria o novo registro
  INSERT INTO public.financial_records (
    tenant_id,
    owner_id,
    patient_id,
    agenda_evento_id,
    amount,
    discount_amount,
    final_amount,
    status,
    due_date
  ) VALUES (
    p_tenant_id,
    p_owner_id,
    p_patient_id,
    p_agenda_evento_id,
    p_amount,
    0,
    p_amount,
    'pending',
    p_due_date
  )
  RETURNING * INTO v_new;

  -- Marca o evento da agenda como billed = true
  UPDATE public.agenda_eventos
    SET billed = TRUE
  WHERE id = p_agenda_evento_id;

  RETURN NEXT v_new;
END;
$$;

COMMIT;
