-- ============================================
-- rioCata - Tests de Triggers
-- ============================================
-- Tests que verifican el funcionamiento correcto
-- de los triggers automáticos
-- ============================================

\echo '=========================================='
\echo 'Tests de Triggers'
\echo '=========================================='
\echo ''

-- ============================================
-- TEST: Trigger updated_at se actualiza automáticamente
-- ============================================
\echo '[TRIGGER 1] Validando trigger updated_at...'

DO $$
DECLARE
  test_sesion_id uuid := gen_random_uuid();
  test_user_id uuid := gen_random_uuid();
  test_participante_id uuid := gen_random_uuid();
  test_muestra_id uuid := gen_random_uuid();
  test_eval_id uuid;
  initial_updated_at timestamptz;
  new_updated_at timestamptz;
BEGIN
  -- Crear datos de prueba
  INSERT INTO auth.users (id, email, nombre)
  VALUES (test_user_id, 'test_trigger1@test.com', 'Test User');

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

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

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

  -- Crear evaluación
  INSERT INTO evaluacion (
    muestra_id, sesion_participante_id, intensidades
  ) VALUES (
    test_muestra_id, test_participante_id,
    '{"fragancia":{"descriptiva":5,"afectiva":5}}'::jsonb
  ) RETURNING id, updated_at INTO test_eval_id, initial_updated_at;

  RAISE NOTICE '  ✓ Evaluación creada con updated_at: %', initial_updated_at;

  -- Esperar 0.1 segundos (suficiente para clock_timestamp)
  PERFORM pg_sleep(0.1);

  -- Actualizar la evaluación
  UPDATE evaluacion
  SET intensidades = '{"fragancia":{"descriptiva":6,"afectiva":6}}'::jsonb
  WHERE id = test_eval_id;

  -- Verificar que updated_at cambió
  SELECT updated_at INTO new_updated_at
  FROM evaluacion
  WHERE id = test_eval_id;

  IF new_updated_at > initial_updated_at THEN
    RAISE NOTICE '  ✓ updated_at se actualizó automáticamente (% -> %)',
      initial_updated_at, new_updated_at;
  ELSE
    RAISE EXCEPTION '  ✗ updated_at NO se actualizó (% == %)',
      initial_updated_at, new_updated_at;
  END IF;

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

  RAISE NOTICE '✓ Trigger updated_at funciona correctamente';
END $$;

\echo ''

-- ============================================
-- TEST: Trigger puntaje_final se calcula automáticamente
-- ============================================
\echo '[TRIGGER 2] Validando trigger puntaje_final (cálculo automático)...'

DO $$
DECLARE
  test_sesion_id uuid := gen_random_uuid();
  test_user_id uuid := gen_random_uuid();
  test_participante_id uuid := gen_random_uuid();
  test_muestra_id uuid := gen_random_uuid();
  calculated_score int;
  expected_score int;
BEGIN
  -- Crear datos de prueba
  INSERT INTO auth.users (id, email, nombre)
  VALUES (test_user_id, 'test_trigger2@test.com', 'Test User');

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

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

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

  -- Test 1: Crear evaluación con todos los parámetros
  -- Suma esperada: 5+6+7+8+9+10+8+7 = 60
  expected_score := 60;

  INSERT INTO evaluacion (
    muestra_id, sesion_participante_id, intensidades
  ) VALUES (
    test_muestra_id, test_participante_id,
    '{
      "fragancia": {"descriptiva": 5, "afectiva": 5},
      "aroma": {"descriptiva": 6, "afectiva": 6},
      "sabor": {"descriptiva": 7, "afectiva": 7},
      "saborResidual": {"descriptiva": 8, "afectiva": 8},
      "acidez": {"descriptiva": 9, "afectiva": 9},
      "dulzor": {"descriptiva": 10, "afectiva": 10},
      "sensacionBoca": {"descriptiva": 8, "afectiva": 8},
      "impresionGlobal": {"descriptiva": null, "afectiva": 7}
    }'::jsonb
  );

  SELECT puntaje_final INTO calculated_score
  FROM evaluacion
  WHERE muestra_id = test_muestra_id;

  IF calculated_score = expected_score THEN
    RAISE NOTICE '  ✓ Puntaje calculado correctamente: % (esperado: %)',
      calculated_score, expected_score;
  ELSE
    RAISE EXCEPTION '  ✗ Puntaje incorrecto: % (esperado: %)',
      calculated_score, expected_score;
  END IF;

  -- Test 2: Actualizar intensidades y verificar recálculo
  DELETE FROM evaluacion WHERE muestra_id = test_muestra_id;

  -- Suma esperada: 1+1+1+1+1+1+1+1 = 8
  expected_score := 8;

  INSERT INTO evaluacion (
    muestra_id, sesion_participante_id, intensidades
  ) VALUES (
    test_muestra_id, test_participante_id,
    '{
      "fragancia": {"descriptiva": 1, "afectiva": 1},
      "aroma": {"descriptiva": 1, "afectiva": 1},
      "sabor": {"descriptiva": 1, "afectiva": 1},
      "saborResidual": {"descriptiva": 1, "afectiva": 1},
      "acidez": {"descriptiva": 1, "afectiva": 1},
      "dulzor": {"descriptiva": 1, "afectiva": 1},
      "sensacionBoca": {"descriptiva": 1, "afectiva": 1},
      "impresionGlobal": {"descriptiva": null, "afectiva": 1}
    }'::jsonb
  );

  SELECT puntaje_final INTO calculated_score
  FROM evaluacion
  WHERE muestra_id = test_muestra_id;

  IF calculated_score = expected_score THEN
    RAISE NOTICE '  ✓ Puntaje mínimo calculado correctamente: % (esperado: %)',
      calculated_score, expected_score;
  ELSE
    RAISE EXCEPTION '  ✗ Puntaje mínimo incorrecto: % (esperado: %)',
      calculated_score, expected_score;
  END IF;

  -- Test 3: Puntaje máximo
  DELETE FROM evaluacion WHERE muestra_id = test_muestra_id;

  -- Suma esperada: 10+10+10+10+10+10+10+10 = 80
  expected_score := 80;

  INSERT INTO evaluacion (
    muestra_id, sesion_participante_id, intensidades
  ) VALUES (
    test_muestra_id, test_participante_id,
    '{
      "fragancia": {"descriptiva": 15, "afectiva": 10},
      "aroma": {"descriptiva": 15, "afectiva": 10},
      "sabor": {"descriptiva": 15, "afectiva": 10},
      "saborResidual": {"descriptiva": 15, "afectiva": 10},
      "acidez": {"descriptiva": 15, "afectiva": 10},
      "dulzor": {"descriptiva": 15, "afectiva": 10},
      "sensacionBoca": {"descriptiva": 15, "afectiva": 10},
      "impresionGlobal": {"descriptiva": null, "afectiva": 10}
    }'::jsonb
  );

  SELECT puntaje_final INTO calculated_score
  FROM evaluacion
  WHERE muestra_id = test_muestra_id;

  IF calculated_score = expected_score THEN
    RAISE NOTICE '  ✓ Puntaje máximo calculado correctamente: % (esperado: %)',
      calculated_score, expected_score;
  ELSE
    RAISE EXCEPTION '  ✗ Puntaje máximo incorrecto: % (esperado: %)',
      calculated_score, expected_score;
  END IF;

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

  RAISE NOTICE '✓ Trigger puntaje_final funciona correctamente';
END $$;

\echo ''

-- ============================================
-- TEST: Trigger puntaje_final se recalcula en UPDATE
-- ============================================
\echo '[TRIGGER 3] Validando trigger puntaje_final (recálculo en UPDATE)...'

DO $$
DECLARE
  test_sesion_id uuid := gen_random_uuid();
  test_user_id uuid := gen_random_uuid();
  test_participante_id uuid := gen_random_uuid();
  test_muestra_id uuid := gen_random_uuid();
  test_eval_id uuid;
  initial_score int;
  updated_score int;
  expected_updated_score int := 40;
BEGIN
  -- Crear datos de prueba
  INSERT INTO auth.users (id, email, nombre)
  VALUES (test_user_id, 'test_trigger3@test.com', 'Test User');

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

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

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

  -- Crear evaluación con puntaje inicial 24 (8*3)
  INSERT INTO evaluacion (
    muestra_id, sesion_participante_id, intensidades
  ) VALUES (
    test_muestra_id, test_participante_id,
    '{
      "fragancia": {"descriptiva": 5, "afectiva": 3},
      "aroma": {"descriptiva": 5, "afectiva": 3},
      "sabor": {"descriptiva": 5, "afectiva": 3},
      "saborResidual": {"descriptiva": 5, "afectiva": 3},
      "acidez": {"descriptiva": 5, "afectiva": 3},
      "dulzor": {"descriptiva": 5, "afectiva": 3},
      "sensacionBoca": {"descriptiva": 5, "afectiva": 3},
      "impresionGlobal": {"descriptiva": null, "afectiva": 3}
    }'::jsonb
  ) RETURNING id, puntaje_final INTO test_eval_id, initial_score;

  RAISE NOTICE '  ✓ Puntaje inicial: %', initial_score;

  -- Actualizar a puntaje 40 (8*5)
  UPDATE evaluacion
  SET intensidades = '{
    "fragancia": {"descriptiva": 5, "afectiva": 5},
    "aroma": {"descriptiva": 5, "afectiva": 5},
    "sabor": {"descriptiva": 5, "afectiva": 5},
    "saborResidual": {"descriptiva": 5, "afectiva": 5},
    "acidez": {"descriptiva": 5, "afectiva": 5},
    "dulzor": {"descriptiva": 5, "afectiva": 5},
    "sensacionBoca": {"descriptiva": 5, "afectiva": 5},
    "impresionGlobal": {"descriptiva": null, "afectiva": 5}
  }'::jsonb
  WHERE id = test_eval_id;

  SELECT puntaje_final INTO updated_score
  FROM evaluacion
  WHERE id = test_eval_id;

  IF updated_score = expected_updated_score THEN
    RAISE NOTICE '  ✓ Puntaje recalculado correctamente en UPDATE: % -> % (esperado: %)',
      initial_score, updated_score, expected_updated_score;
  ELSE
    RAISE EXCEPTION '  ✗ Puntaje no se recalculó correctamente: % -> % (esperado: %)',
      initial_score, updated_score, expected_updated_score;
  END IF;

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

  RAISE NOTICE '✓ Trigger puntaje_final se recalcula correctamente en UPDATE';
END $$;

\echo ''

\echo '=========================================='
\echo 'Tests de Triggers completados'
\echo '=========================================='
