-- ============================================
-- rioCata - Tests de Funciones Auxiliares
-- ============================================
-- Tests que verifican las funciones auxiliares
-- con datos generados dinámicamente
-- ============================================

\echo '=========================================='
\echo 'Tests de Funciones Auxiliares'
\echo '=========================================='
\echo ''

-- ============================================
-- TEST: Función get_promedio_parametro_afectivo
-- ============================================
\echo '[FUNCTION 1] Probando función: get_promedio_parametro_afectivo...'

DO $$
DECLARE
  test_sesion_id uuid := gen_random_uuid();
  test_user1_id uuid := gen_random_uuid();
  test_user2_id uuid := gen_random_uuid();
  test_user3_id uuid := gen_random_uuid();
  test_part1_id uuid := gen_random_uuid();
  test_part2_id uuid := gen_random_uuid();
  test_part3_id uuid := gen_random_uuid();
  test_muestra_id uuid := gen_random_uuid();
  avg_acidez numeric;
  avg_dulzor numeric;
  avg_sabor numeric;
  expected_acidez numeric := 7.0; -- (6 + 8 + 7) / 3
  expected_dulzor numeric := 5.0; -- (3 + 7 + 5) / 3
  expected_sabor numeric := 8.0;  -- (8 + 8 + 8) / 3
BEGIN
  -- Crear datos de prueba
  INSERT INTO auth.users (id, email, nombre) VALUES
    (test_user1_id, 'test_func1_u1@test.com', 'User 1'),
    (test_user2_id, 'test_func1_u2@test.com', 'User 2'),
    (test_user3_id, 'test_func1_u3@test.com', 'User 3');

  INSERT INTO sesion (id, codigo, fecha)
  VALUES (test_sesion_id, 'TEST-FUNC-1', CURRENT_DATE);

  INSERT INTO sesion_participante (id, sesion_id, catador_id) VALUES
    (test_part1_id, test_sesion_id, test_user1_id),
    (test_part2_id, test_sesion_id, test_user2_id),
    (test_part3_id, test_sesion_id, test_user3_id);

  INSERT INTO muestra (id, sesion_id, codigo)
  VALUES (test_muestra_id, test_sesion_id, 'TEST-M1');

  -- Crear 3 evaluaciones con diferentes valores
  INSERT INTO evaluacion (muestra_id, sesion_participante_id, intensidades) VALUES
    (test_muestra_id, test_part1_id,
     '{"acidez":{"descriptiva":5,"afectiva":6},"dulzor":{"descriptiva":5,"afectiva":3},"sabor":{"descriptiva":8,"afectiva":8}}'::jsonb),
    (test_muestra_id, test_part2_id,
     '{"acidez":{"descriptiva":10,"afectiva":8},"dulzor":{"descriptiva":10,"afectiva":7},"sabor":{"descriptiva":8,"afectiva":8}}'::jsonb),
    (test_muestra_id, test_part3_id,
     '{"acidez":{"descriptiva":7,"afectiva":7},"dulzor":{"descriptiva":6,"afectiva":5},"sabor":{"descriptiva":8,"afectiva":8}}'::jsonb);

  -- Test función para acidez
  SELECT get_promedio_parametro_afectivo(test_sesion_id, 'acidez')
  INTO avg_acidez;

  IF avg_acidez = expected_acidez THEN
    RAISE NOTICE '  ✓ Promedio acidez correcto: % (esperado: %)',
      avg_acidez, expected_acidez;
  ELSE
    RAISE EXCEPTION '  ✗ Promedio acidez incorrecto: % (esperado: %)',
      avg_acidez, expected_acidez;
  END IF;

  -- Test función para dulzor
  SELECT get_promedio_parametro_afectivo(test_sesion_id, 'dulzor')
  INTO avg_dulzor;

  IF avg_dulzor = expected_dulzor THEN
    RAISE NOTICE '  ✓ Promedio dulzor correcto: % (esperado: %)',
      avg_dulzor, expected_dulzor;
  ELSE
    RAISE EXCEPTION '  ✗ Promedio dulzor incorrecto: % (esperado: %)',
      avg_dulzor, expected_dulzor;
  END IF;

  -- Test función para sabor
  SELECT get_promedio_parametro_afectivo(test_sesion_id, 'sabor')
  INTO avg_sabor;

  IF avg_sabor = expected_sabor THEN
    RAISE NOTICE '  ✓ Promedio sabor correcto: % (esperado: %)',
      avg_sabor, expected_sabor;
  ELSE
    RAISE EXCEPTION '  ✗ Promedio sabor incorrecto: % (esperado: %)',
      avg_sabor, expected_sabor;
  END IF;

  -- Cleanup
  DELETE FROM sesion WHERE id = test_sesion_id;
  DELETE FROM auth.users WHERE id IN (test_user1_id, test_user2_id, test_user3_id);

  RAISE NOTICE '✓ Función get_promedio_parametro_afectivo funciona correctamente';
END $$;

\echo ''

-- ============================================
-- TEST: Función get_top_muestras
-- ============================================
\echo '[FUNCTION 2] Probando función: get_top_muestras...'

DO $$
DECLARE
  test_sesion_id uuid := gen_random_uuid();
  test_user_id uuid := gen_random_uuid();
  test_part_id uuid := gen_random_uuid();
  test_muestra1_id uuid := gen_random_uuid();
  test_muestra2_id uuid := gen_random_uuid();
  test_muestra3_id uuid := gen_random_uuid();
  test_muestra4_id uuid := gen_random_uuid();
  result record;
  result_count int := 0;
  first_muestra text;
  first_puntaje int;
BEGIN
  -- Crear datos de prueba
  INSERT INTO auth.users (id, email, nombre)
  VALUES (test_user_id, 'test_func2@test.com', 'Test User');

  INSERT INTO sesion (id, codigo, fecha)
  VALUES (test_sesion_id, 'TEST-FUNC-2', CURRENT_DATE);

  INSERT INTO sesion_participante (id, sesion_id, catador_id)
  VALUES (test_part_id, test_sesion_id, test_user_id);

  -- Crear 4 muestras con puntajes 25, 50, 75, 100 (ordenadas al revés)
  INSERT INTO muestra (id, sesion_id, codigo) VALUES
    (test_muestra1_id, test_sesion_id, 'PUNTAJE-25'),
    (test_muestra2_id, test_sesion_id, 'PUNTAJE-50'),
    (test_muestra3_id, test_sesion_id, 'PUNTAJE-75'),
    (test_muestra4_id, test_sesion_id, 'PUNTAJE-100');

  INSERT INTO evaluacion (muestra_id, sesion_participante_id, intensidades) VALUES
    (test_muestra1_id, test_part_id,
     '{"fragancia":{"afectiva":3},"aroma":{"afectiva":3},"sabor":{"afectiva":3},"saborResidual":{"afectiva":3},"acidez":{"afectiva":3},"dulzor":{"afectiva":4},"sensacionBoca":{"afectiva":3},"impresionGlobal":{"afectiva":3}}'::jsonb),
    (test_muestra2_id, test_part_id,
     '{"fragancia":{"afectiva":6},"aroma":{"afectiva":6},"sabor":{"afectiva":6},"saborResidual":{"afectiva":6},"acidez":{"afectiva":7},"dulzor":{"afectiva":7},"sensacionBoca":{"afectiva":6},"impresionGlobal":{"afectiva":6}}'::jsonb),
    (test_muestra3_id, test_part_id,
     '{"fragancia":{"afectiva":9},"aroma":{"afectiva":9},"sabor":{"afectiva":9},"saborResidual":{"afectiva":10},"acidez":{"afectiva":10},"dulzor":{"afectiva":10},"sensacionBoca":{"afectiva":9},"impresionGlobal":{"afectiva":9}}'::jsonb),
    (test_muestra4_id, test_part_id,
     '{"fragancia":{"afectiva":10},"aroma":{"afectiva":10},"sabor":{"afectiva":10},"saborResidual":{"afectiva":10},"acidez":{"afectiva":10},"dulzor":{"afectiva":10},"sensacionBoca":{"afectiva":10},"impresionGlobal":{"afectiva":10}}'::jsonb);

  -- Test: obtener top 3
  FOR result IN
    SELECT * FROM get_top_muestras(test_sesion_id, 3)
  LOOP
    result_count := result_count + 1;
    IF result_count = 1 THEN
      first_muestra := result.muestra_codigo;
      first_puntaje := result.puntaje_final;
    END IF;
    RAISE NOTICE '  - Posición %: % (% puntos)',
      result_count, result.muestra_codigo, result.puntaje_final;
  END LOOP;

  -- Validar que devolvió 3 resultados
  IF result_count != 3 THEN
    RAISE EXCEPTION '  ✗ Devolvió % resultados (esperado: 3)', result_count;
  END IF;

  -- Validar que el primero es PUNTAJE-100 con 80 puntos
  IF first_muestra != 'PUNTAJE-100' THEN
    RAISE EXCEPTION '  ✗ Primera muestra incorrecta: % (esperado: PUNTAJE-100)',
      first_muestra;
  END IF;

  IF first_puntaje != 80 THEN
    RAISE EXCEPTION '  ✗ Primer puntaje incorrecto: % (esperado: 80)',
      first_puntaje;
  END IF;

  RAISE NOTICE '  ✓ Función devuelve top 3 correctamente';

  -- Test: obtener top 10 (debería devolver solo 4)
  result_count := 0;
  FOR result IN
    SELECT * FROM get_top_muestras(test_sesion_id, 10)
  LOOP
    result_count := result_count + 1;
  END LOOP;

  IF result_count = 4 THEN
    RAISE NOTICE '  ✓ Función limita correctamente cuando hay menos resultados que el límite';
  ELSE
    RAISE EXCEPTION '  ✗ Con limit=10 devolvió % resultados (esperado: 4)',
      result_count;
  END IF;

  -- Cleanup
  DELETE FROM sesion WHERE id = test_sesion_id;
  DELETE FROM auth.users WHERE id = test_user_id;

  RAISE NOTICE '✓ Función get_top_muestras funciona correctamente';
END $$;

\echo ''

-- ============================================
-- TEST: Funciones con sesión vacía
-- ============================================
\echo '[FUNCTION 3] Probando funciones con sesión sin evaluaciones...'

DO $$
DECLARE
  test_sesion_id uuid := gen_random_uuid();
  avg_result numeric;
  top_count int := 0;
  result record;
BEGIN
  -- Crear sesión vacía
  INSERT INTO sesion (id, codigo, fecha)
  VALUES (test_sesion_id, 'TEST-FUNC-EMPTY', CURRENT_DATE);

  -- Test get_promedio_parametro_afectivo con sesión vacía
  SELECT get_promedio_parametro_afectivo(test_sesion_id, 'acidez')
  INTO avg_result;

  IF avg_result IS NULL THEN
    RAISE NOTICE '  ✓ get_promedio_parametro_afectivo devuelve NULL con sesión vacía';
  ELSE
    RAISE EXCEPTION '  ✗ Devolvió % en lugar de NULL', avg_result;
  END IF;

  -- Test get_top_muestras con sesión vacía
  FOR result IN
    SELECT * FROM get_top_muestras(test_sesion_id, 3)
  LOOP
    top_count := top_count + 1;
  END LOOP;

  IF top_count = 0 THEN
    RAISE NOTICE '  ✓ get_top_muestras devuelve conjunto vacío con sesión vacía';
  ELSE
    RAISE EXCEPTION '  ✗ Devolvió % resultados en lugar de 0', top_count;
  END IF;

  -- Cleanup
  DELETE FROM sesion WHERE id = test_sesion_id;

  RAISE NOTICE '✓ Funciones manejan correctamente sesiones vacías';
END $$;

\echo ''

\echo '=========================================='
\echo 'Tests de Funciones completados'
\echo '=========================================='
