-- ============================================================
-- Tests pgTAP: Dashboard v3 — RPCs de la Mirada Empresa
--
-- Ejecutar con: supabase test db
-- Requiere: Docker + supabase start + extensión pgtap
--
-- Cubre:
--   1. Existencia de las 11 RPCs + el helper _dash_es_cuidador (firma correcta)
--   2. _dash_es_cuidador: las 4 combinaciones de la definición UNFPA
--      (solo Ninguna / Ninguna+otro / solo "hijo sin discapacidad" / sin responder)
--   3. k≥5 en dos niveles: n=4 → suppressed, n=5 → ok con pct correcto (E1)
--   4. Fix de _dash_responses: el filtro de género ya encuentra '2.5' (no '"A6"')
--   5. Umbral parametrizable de la métrica estrella: mismo dataset, dos
--      resultados distintos según p_umbral_senales (prueba que el parámetro
--      realmente cambia el comportamiento, no es decorativo)
--   6. E9 (rpc_me_segmentacion) — bug real encontrado en VPS: por_nivel leía
--      answers/2.6 en vez de responses.qi_sector. Prueba que ahora lee
--      qi_sector, que por_modalidad sigue leyendo por JOIN a 2.7, y que el
--      k≥5 por segmento sigue omitiendo filas chicas.
--
-- NO escrito por mí pero sí ejecutable por el director: no hay Docker en el
-- entorno donde se generó este archivo — no se corrió contra Postgres real.
-- ============================================================

BEGIN;

SELECT plan(28);

-- ============================================================
-- SECCIÓN 1: las funciones existen con la firma esperada
-- ============================================================
SELECT has_function('public', '_dash_es_cuidador', ARRAY['uuid'],
    '1.1 _dash_es_cuidador(uuid) existe');
SELECT has_function('public', 'rpc_me_prevalencia_cuidadores', ARRAY['uuid','jsonb'],
    '1.2 rpc_me_prevalencia_cuidadores existe');
SELECT has_function('public', 'rpc_me_riesgo_rotacion', ARRAY['uuid','jsonb'],
    '1.3 rpc_me_riesgo_rotacion existe');
SELECT has_function('public', 'rpc_me_ausentismo', ARRAY['uuid','jsonb'],
    '1.4 rpc_me_ausentismo existe');
SELECT has_function('public', 'rpc_me_presentismo', ARRAY['uuid','jsonb'],
    '1.5 rpc_me_presentismo existe');
SELECT has_function('public', 'rpc_me_punto_ciego', ARRAY['uuid','jsonb'],
    '1.6 rpc_me_punto_ciego existe');
SELECT has_function('public', 'rpc_me_apoyos_demandados', ARRAY['uuid','jsonb'],
    '1.7 rpc_me_apoyos_demandados existe');
SELECT has_function('public', 'rpc_me_talento_en_riesgo', ARRAY['uuid','jsonb','int4'],
    '1.8 rpc_me_talento_en_riesgo(uuid,jsonb,int) existe — confirma el parámetro de umbral');
SELECT has_function('public', 'rpc_me_carrera_congelada', ARRAY['uuid','jsonb'],
    '1.9 rpc_me_carrera_congelada existe');
SELECT has_function('public', 'rpc_me_intensidad_carga', ARRAY['uuid','jsonb'],
    '1.10 rpc_me_intensidad_carga existe');
SELECT has_function('public', 'rpc_me_segmentacion', ARRAY['uuid','jsonb'],
    '1.11 rpc_me_segmentacion existe');
SELECT has_function('public', 'rpc_me_disposicion_red', ARRAY['uuid','jsonb'],
    '1.12 rpc_me_disposicion_red existe');

-- ============================================================
-- SECCIÓN 2: fixture — 1 org, 1 survey v3, preguntas mínimas necesarias
-- ============================================================
DO $$
DECLARE
    v_org_id    uuid := '10000000-1111-0000-0000-000000000001';
    v_cv_id     uuid := '20000000-1111-0000-0000-000000000001';
    v_survey_id uuid := '30000000-1111-0000-0000-000000000001';
BEGIN
    INSERT INTO public.organizations (id, name) VALUES (v_org_id, '_test_me_org');
    INSERT INTO public.consent_versions (id, version, body, scopes)
        VALUES (v_cv_id, '_test-cv-me', 'body', '["operativo"]'::jsonb);
    INSERT INTO public.surveys (id, org_id, title, is_anonymous, data_sensitivity, security_class, consent_version_id)
        VALUES (v_survey_id, v_org_id, '_test_me_survey', true, 'sensible', 'confidencial', v_cv_id);

    INSERT INTO public.questions (id, survey_id, code, type, prompt, position) VALUES
        ('40000000-1111-0000-0000-000000000041', v_survey_id, '4.1', 'multiple_choice', 'vínculos', 41),
        ('40000000-1111-0000-0000-000000000072', v_survey_id, '7.2', 'single_choice', 'presentismo', 72),
        ('40000000-1111-0000-0000-000000000073', v_survey_id, '7.3', 'single_choice', 'ausentismo', 73),
        ('40000000-1111-0000-0000-000000000075', v_survey_id, '7.5', 'multiple_choice', 'carrera', 75),
        ('40000000-1111-0000-0000-000000000076', v_survey_id, '7.6', 'single_choice', 'riesgo rotación', 76),
        ('40000000-1111-0000-0000-000000000091', v_survey_id, '9.1', 'single_choice', 'conciencia', 91),
        ('40000000-1111-0000-0000-000000000025', v_survey_id, '2.5', 'single_choice', 'género', 25);
END;
$$;

-- ============================================================
-- SECCIÓN 3: _dash_es_cuidador — las 4 combinaciones de la definición UNFPA
-- ============================================================
DO $$
DECLARE
    v_survey_id uuid := '30000000-1111-0000-0000-000000000001';
    v_q41       uuid := '40000000-1111-0000-0000-000000000041';
    v_cr_id     uuid := '50000000-1111-0000-0000-000000000001';
    v_r_ninguna uuid := '60000000-1111-0000-0000-000000000001'; -- solo "Ninguna..."
    v_r_mixto   uuid := '60000000-1111-0000-0000-000000000002'; -- "Ninguna..." + otra opción
    v_r_solonin uuid := '60000000-1111-0000-0000-000000000003'; -- solo "Hijo menor sin discapacidad"
    v_r_sinresp uuid := '60000000-1111-0000-0000-000000000004'; -- no respondió 4.1
BEGIN
    INSERT INTO public.consent_records (id, consent_version_id, granted_scopes)
        VALUES (v_cr_id, '20000000-1111-0000-0000-000000000001', '{"operativo":true}'::jsonb);

    INSERT INTO public.responses (id, survey_id, company_id, consent_record_id) VALUES
        (v_r_ninguna, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
        (v_r_mixto,   v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
        (v_r_solonin, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
        (v_r_sinresp, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id);

    INSERT INTO public.answers (response_id, question_id, instance_id, value) VALUES
        (v_r_ninguna, v_q41, 'default', '["Ninguna de las anteriores / No tengo vinculación de cuidado"]'::jsonb),
        (v_r_mixto,   v_q41, 'default', '["Ninguna de las anteriores / No tengo vinculación de cuidado","Otro / Especificar"]'::jsonb),
        (v_r_solonin, v_q41, 'default', '["Hijo menor sin discapacidad"]'::jsonb);
        -- v_r_sinresp: sin fila en answers para 4.1 (a propósito)
END;
$$;

SELECT is(public._dash_es_cuidador('60000000-1111-0000-0000-000000000001'), false,
    '3.1 solo "Ninguna..." → NO es cuidador');
SELECT is(public._dash_es_cuidador('60000000-1111-0000-0000-000000000002'), true,
    '3.2 "Ninguna..." + otra opción → SÍ es cuidador (la otra opción cuenta)');
SELECT is(public._dash_es_cuidador('60000000-1111-0000-0000-000000000003'), true,
    '3.3 solo "Hijo menor sin discapacidad" → SÍ es cuidador (criterio UNFPA)');
SELECT is(public._dash_es_cuidador('60000000-1111-0000-0000-000000000004'), false,
    '3.4 sin respuesta a 4.1 → NO es cuidador');

-- ============================================================
-- SECCIÓN 4: k≥5 en rpc_me_prevalencia_cuidadores (E1)
-- 4 cuidadores → suppressed; al agregar 1 más (5) → ok, pct correcto
-- ============================================================
SELECT is(
    (public.rpc_me_prevalencia_cuidadores('30000000-1111-0000-0000-000000000001'::uuid)->>'status'),
    'suppressed',
    '4.1 con 4 responses (n<5) → status=suppressed'
);

DO $$
DECLARE
    v_survey_id uuid := '30000000-1111-0000-0000-000000000001';
    v_q41       uuid := '40000000-1111-0000-0000-000000000041';
    v_cr_id     uuid := '50000000-1111-0000-0000-000000000001';
    v_r5        uuid := '60000000-1111-0000-0000-000000000005'; -- 5ta response, NO cuidador
BEGIN
    INSERT INTO public.responses (id, survey_id, company_id, consent_record_id)
        VALUES (v_r5, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id);
    INSERT INTO public.answers (response_id, question_id, instance_id, value)
        VALUES (v_r5, v_q41, 'default', '["Ninguna de las anteriores / No tengo vinculación de cuidado"]'::jsonb);
END;
$$;

-- Ahora hay 5 responses: 3 cuidadores (mixto, solonin) + ... v_r_sinresp NO es
-- cuidador (sin 4.1), v_r_ninguna NO es cuidador, v_r5 NO es cuidador.
-- Cuidadores reales = {v_r_mixto, v_r_solonin} = 2 de 5 → 40.0%
SELECT is(
    (public.rpc_me_prevalencia_cuidadores('30000000-1111-0000-0000-000000000001'::uuid)->>'status'),
    'ok',
    '4.2 con 5 responses (n>=5) → status=ok'
);
SELECT is(
    ((public.rpc_me_prevalencia_cuidadores('30000000-1111-0000-0000-000000000001'::uuid)->>'pct_cuidadores')::numeric),
    40.0,
    '4.3 pct_cuidadores = 2/5 = 40.0%'
);

-- ============================================================
-- SECCIÓN 5: fix de _dash_responses — filtro de género contra 2.5 (no A6)
-- ============================================================
DO $$
DECLARE
    v_survey_id uuid := '30000000-1111-0000-0000-000000000001';
    v_q25       uuid := '40000000-1111-0000-0000-000000000025';
    v_cr_id     uuid := '50000000-1111-0000-0000-000000000001';
    v_rg        uuid := '60000000-1111-0000-0000-000000000006';
BEGIN
    INSERT INTO public.responses (id, survey_id, company_id, consent_record_id)
        VALUES (v_rg, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id);
    INSERT INTO public.answers (response_id, question_id, instance_id, value)
        VALUES (v_rg, v_q25, 'default', '"Femenino"'::jsonb);
END;
$$;

SELECT is(
    (SELECT count(*)::int FROM public._dash_responses(
        '30000000-1111-0000-0000-000000000001'::uuid, NULL, ARRAY['Femenino'], NULL, NULL
    ) WHERE response_id = '60000000-1111-0000-0000-000000000006'),
    1,
    '5.1 filtro p_genero=[Femenino] encuentra la response con 2.5=Femenino (post-fix)'
);
SELECT is(
    (SELECT count(*)::int FROM public._dash_responses(
        '30000000-1111-0000-0000-000000000001'::uuid, NULL, ARRAY['Masculino'], NULL, NULL
    ) WHERE response_id = '60000000-1111-0000-0000-000000000006'),
    0,
    '5.2 filtro p_genero=[Masculino] NO encuentra esa response (control negativo)'
);

-- ============================================================
-- SECCIÓN 6: umbral parametrizable — métrica estrella
-- 1 cuidador con exactamente 1 de 3 señales (riesgo de rotación, vía 7.6)
-- ============================================================
DO $$
DECLARE
    v_survey_id uuid := '30000000-1111-0000-0000-000000000001';
    v_q41       uuid := '40000000-1111-0000-0000-000000000041';
    v_q76       uuid := '40000000-1111-0000-0000-000000000076';
    v_q73       uuid := '40000000-1111-0000-0000-000000000073';
    v_q75       uuid := '40000000-1111-0000-0000-000000000075';
    v_cr_id     uuid := '50000000-1111-0000-0000-000000000001';
    v_r1        uuid := '60000000-2222-0000-0000-000000000001';
    v_r2        uuid := '60000000-2222-0000-0000-000000000002';
    v_r3        uuid := '60000000-2222-0000-0000-000000000003';
    v_r4        uuid := '60000000-2222-0000-0000-000000000004';
    v_r5        uuid := '60000000-2222-0000-0000-000000000005';
BEGIN
    INSERT INTO public.responses (id, survey_id, company_id, consent_record_id)
        VALUES (v_r1, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
               (v_r2, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
               (v_r3, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
               (v_r4, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id),
               (v_r5, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id);

    -- Las 5 son cuidadoras (4.1 con un vínculo real) y respondieron 7.6
    -- (ancla de la población), pero NINGUNA cumple 2+ señales — cada una
    -- cumple EXACTAMENTE 1 (riesgo de rotación), 0 en ausentismo/carrera.
    INSERT INTO public.answers (response_id, question_id, instance_id, value)
    SELECT r, v_q41, 'default', '["Otro / Especificar"]'::jsonb
    FROM unnest(ARRAY[v_r1,v_r2,v_r3,v_r4,v_r5]) AS r;

    INSERT INTO public.answers (response_id, question_id, instance_id, value)
    SELECT r, v_q76, 'default', '"Muy probable"'::jsonb
    FROM unnest(ARRAY[v_r1,v_r2,v_r3,v_r4,v_r5]) AS r;

    INSERT INTO public.answers (response_id, question_id, instance_id, value)
    SELECT r, v_q73, 'default', '"Nunca"'::jsonb
    FROM unnest(ARRAY[v_r1,v_r2,v_r3,v_r4,v_r5]) AS r;

    INSERT INTO public.answers (response_id, question_id, instance_id, value)
    SELECT r, v_q75, 'default', '["Ninguna de las anteriores"]'::jsonb
    FROM unnest(ARRAY[v_r1,v_r2,v_r3,v_r4,v_r5]) AS r;
END;
$$;

-- Con el umbral default (2 de 3): nadie llega → 0%
SELECT is(
    ((public.rpc_me_talento_en_riesgo('30000000-1111-0000-0000-000000000001'::uuid)->>'pct_talento_riesgo')::numeric),
    0.0,
    '6.1 umbral default (2 de 3): 0% — nadie acumula 2 señales'
);
-- Bajando el umbral a 1 de 3: las 5 cumplen (todas tienen la señal de riesgo) → 100%
SELECT is(
    ((public.rpc_me_talento_en_riesgo(
        '30000000-1111-0000-0000-000000000001'::uuid, '{}'::jsonb, 1
    )->>'pct_talento_riesgo')::numeric),
    100.0,
    '6.2 umbral=1 (parámetro explícito): 100% — el parámetro SÍ cambia el resultado'
);
SELECT is(
    ((public.rpc_me_talento_en_riesgo('30000000-1111-0000-0000-000000000001'::uuid)->>'criterios_promedio')::numeric),
    1.00,
    '6.3 criterios_promedio = 1.00 (cada cuidadora cumple exactamente 1 de 3 señales)'
);

-- ============================================================
-- SECCIÓN 7: E9 (rpc_me_segmentacion) — por_nivel via qi_sector,
-- por_modalidad via JOIN a 2.7, k≥5 por segmento
-- ============================================================
DO $$
DECLARE
    v_survey_id uuid := '30000000-1111-0000-0000-000000000001';
    v_q27       uuid := '40000000-1111-0000-0000-000000000027';
    v_cr_id     uuid := '50000000-1111-0000-0000-000000000001';
    v_r         uuid;
    i           int;
BEGIN
    INSERT INTO public.questions (id, survey_id, code, type, prompt, position)
        VALUES (v_q27, v_survey_id, '2.7', 'single_choice', 'modalidad', 27);

    -- 6 responses "Operativo"/"Presencial" (n=6 >= 5 → visible)
    FOR i IN 1..6 LOOP
        v_r := ('60000000-3333-0000-0000-' || lpad(i::text, 12, '0'))::uuid;
        INSERT INTO public.responses (id, survey_id, company_id, consent_record_id, qi_sector)
            VALUES (v_r, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id, 'Operativo');
        INSERT INTO public.answers (response_id, question_id, instance_id, value)
            VALUES (v_r, v_q27, 'default', '"Presencial"'::jsonb);
    END LOOP;

    -- 3 responses "Gerencial"/"Remoto (home office)" (n=3 < 5 → omitido)
    FOR i IN 1..3 LOOP
        v_r := ('60000000-4444-0000-0000-' || lpad(i::text, 12, '0'))::uuid;
        INSERT INTO public.responses (id, survey_id, company_id, consent_record_id, qi_sector)
            VALUES (v_r, v_survey_id, '10000000-1111-0000-0000-000000000001', v_cr_id, 'Gerencial');
        INSERT INTO public.answers (response_id, question_id, instance_id, value)
            VALUES (v_r, v_q27, 'default', '"Remoto (home office)"'::jsonb);
    END LOOP;
END;
$$;

SELECT is(
    jsonb_path_query_first(
        public.rpc_me_segmentacion('30000000-1111-0000-0000-000000000001'::uuid),
        '$.por_nivel[*] ? (@.nivel == "Operativo")'
    )->>'n',
    '6',
    '7.1 por_nivel lee qi_sector — "Operativo" aparece con n=6 (post-fix)'
);
SELECT is(
    jsonb_path_query_first(
        public.rpc_me_segmentacion('30000000-1111-0000-0000-000000000001'::uuid),
        '$.por_nivel[*] ? (@.nivel == "Gerencial")'
    ),
    NULL::jsonb,
    '7.2 "Gerencial" (n=3 < 5) está omitido de por_nivel — k-anonimato por segmento'
);
SELECT is(
    jsonb_path_query_first(
        public.rpc_me_segmentacion('30000000-1111-0000-0000-000000000001'::uuid),
        '$.por_modalidad[*] ? (@.modalidad == "Presencial")'
    )->>'n',
    '6',
    '7.3 por_modalidad lee 2.7 por JOIN a answers — "Presencial" aparece con n=6'
);
SELECT is(
    jsonb_path_query_first(
        public.rpc_me_segmentacion('30000000-1111-0000-0000-000000000001'::uuid),
        '$.por_modalidad[*] ? (@.modalidad == "Remoto (home office)")'
    ),
    NULL::jsonb,
    '7.4 "Remoto (home office)" (n=3 < 5) está omitido de por_modalidad'
);

SELECT * FROM finish();
ROLLBACK;
