-- =============================================================================
-- Fix (regressão schema-per-tenant): log_audit_change quebra INSERT em tabelas
-- GLOBAIS auditadas.
--
-- log_audit_change deriva o tenant via tenant_id_for_schema(TG_TABLE_SCHEMA).
-- Para tabelas em tenant_<slug> isso resolve certo. Mas o trigger também está
-- em public.tenant_members (tabela global) — e tenant_id_for_schema('public')
-- retorna NULL, violando audit_logs.tenant_id (NOT NULL). Resultado: QUALQUER
-- INSERT em tenant_members falhava (provisionamento, aceite de convite).
--
-- Fix: quando o schema não resolve um tenant (tabela global), usa o tenant_id
-- da própria linha (tenant_members.tenant_id). Se ainda assim for NULL, não
-- audita — mas NUNCA quebra a operação de negócio.
-- =============================================================================

CREATE OR REPLACE FUNCTION public.log_audit_change()
RETURNS trigger
LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public','pg_temp'
AS $function$
DECLARE
    v_tenant_id uuid; v_entity_id text; v_old jsonb; v_new jsonb; v_changed text[];
    v_heavy text[] := ARRAY['content','content_html','content_json','raw_data','signature_data','pdf_blob','binary','body_html','body_text'];
    v_noise text[] := ARRAY['updated_at','last_seen_at','last_activity_at'];
BEGIN
    v_tenant_id := public.tenant_id_for_schema(TG_TABLE_SCHEMA);

    -- tabela global (public.*): cai no tenant_id da própria linha, se existir
    IF v_tenant_id IS NULL THEN
        v_tenant_id := NULLIF(to_jsonb(COALESCE(NEW, OLD)) ->> 'tenant_id', '')::uuid;
    END IF;

    -- sem tenant resolvível → não audita, mas não quebra a operação
    IF v_tenant_id IS NULL THEN
        RETURN COALESCE(NEW, OLD);
    END IF;

    IF TG_OP = 'DELETE' THEN
        v_entity_id := OLD.id::text; v_old := to_jsonb(OLD) - v_heavy; v_new := NULL;
    ELSIF TG_OP = 'INSERT' THEN
        v_entity_id := NEW.id::text; v_old := NULL; v_new := to_jsonb(NEW) - v_heavy;
    ELSE
        v_entity_id := NEW.id::text; v_old := to_jsonb(OLD) - v_heavy; v_new := to_jsonb(NEW) - v_heavy;
        SELECT array_agg(key ORDER BY key) INTO v_changed
        FROM jsonb_each(to_jsonb(NEW)) AS kv(key, value)
        WHERE (to_jsonb(OLD))->kv.key IS DISTINCT FROM kv.value;
        IF v_changed IS NULL THEN RETURN NEW; END IF;
        IF v_changed <@ v_noise THEN RETURN NEW; END IF;
    END IF;

    INSERT INTO public.audit_logs (tenant_id, user_id, entity_type, entity_id, action, old_values, new_values, changed_fields)
    VALUES (v_tenant_id, auth.uid(), TG_TABLE_NAME, v_entity_id, lower(TG_OP), v_old, v_new, v_changed);
    RETURN COALESCE(NEW, OLD);
END $function$;
