-- =====================================================
-- DATOS DE EJEMPLO - FLUJO COMPLETO DE TRAZABILIDAD
-- =====================================================
-- Este script crea un ejemplo completo del flujo de café desde
-- ingreso de uva hasta secado final, incluyendo ajustes y correcciones.
--
-- Flujo principal:
-- Ingreso uva → Despulpado → Oreado → Ajuste merma → Ajuste tipo →
-- Presecado → Reposo → Secado (mezcla con otro reposo)

-- Limpiar datos existentes (solo para demo/desarrollo)
DO $$
BEGIN
  RAISE NOTICE 'Limpiando datos de ejemplo previos...';
END $$;

TRUNCATE TABLE operacion_lotes, operaciones, lotes CASCADE;

-- =====================================================
-- PASO 1: INGRESO DE UVA
-- =====================================================
-- Llega café uva de un productor

DO $$
DECLARE
  op_ingreso_id UUID;
  lote_uva_id UUID;
BEGIN
  RAISE NOTICE 'Creando ingreso de uva...';

  -- Crear operación de ingreso
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'ingreso',
    NOW() - INTERVAL '10 days',
    '{"productor": "Finca El Roble", "lote_productor": "2024-11-A"}'::jsonb
  )
  RETURNING id INTO op_ingreso_id;

  -- Crear lote de uva
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'UVA-001',
    'uva',
    NOW() - INTERVAL '10 days',
    2086,
    '{"variedad": "Caturra", "procedencia": "Finca El Roble"}'::jsonb
  )
  RETURNING id INTO lote_uva_id;

  -- Relacionar: operación de ingreso → lote de uva (output)
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES (op_ingreso_id, lote_uva_id, 'output', 2086);

END $$;


-- =====================================================
-- PASO 2: DESPULPADO
-- =====================================================
-- Se despulpa la uva y se obtienen tres lotes: primera, segunda y rechazos

DO $$
DECLARE
  op_despulpado_id UUID;
  lote_uva_id UUID;
  lote_primera_id UUID;
  lote_segunda_id UUID;
  lote_rechazos_id UUID;
BEGIN
  RAISE NOTICE 'Creando despulpado...';

  -- Obtener ID del lote de uva
  SELECT id INTO lote_uva_id FROM lotes WHERE codigo = 'UVA-001';

  -- Crear operación de despulpado
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'despulpado',
    NOW() - INTERVAL '9 days',
    '{"pila": 2, "operador": "Juan Pérez"}'::jsonb
  )
  RETURNING id INTO op_despulpado_id;

  -- Crear lotes de salida
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES ('PRIM-001', 'despulpado_primera', NOW() - INTERVAL '9 days', 1500, '{"calidad": "A"}'::jsonb)
  RETURNING id INTO lote_primera_id;

  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES ('SEG-001', 'despulpado_segunda', NOW() - INTERVAL '9 days', 400, '{"calidad": "B"}'::jsonb)
  RETURNING id INTO lote_segunda_id;

  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES ('RECH-001', 'despulpado_rechazos', NOW() - INTERVAL '9 days', 150, '{"destino": "compost"}'::jsonb)
  RETURNING id INTO lote_rechazos_id;

  -- Relacionar: uva → despulpado (input)
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES (op_despulpado_id, lote_uva_id, 'input', 2086);

  -- Relacionar: despulpado → primera, segunda, rechazos (outputs)
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES
    (op_despulpado_id, lote_primera_id, 'output', 1500),
    (op_despulpado_id, lote_segunda_id, 'output', 400),
    (op_despulpado_id, lote_rechazos_id, 'output', 150);

END $$;


-- =====================================================
-- PASO 3: OREADO (con error en registro)
-- =====================================================
-- Se orea el lote de primera calidad, pero se registra mal la cantidad

DO $$
DECLARE
  op_oreado_id UUID;
  lote_primera_id UUID;
  lote_oreado_id UUID;
BEGIN
  RAISE NOTICE 'Creando oreado (con error de registro)...';

  -- Obtener ID del lote de primera
  SELECT id INTO lote_primera_id FROM lotes WHERE codigo = 'PRIM-001';

  -- Crear operación de oreado
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'oreado',
    NOW() - INTERVAL '8 days',
    '{"patio": 1, "inicio": "06:00", "fin": "18:00"}'::jsonb
  )
  RETURNING id INTO op_oreado_id;

  -- Crear lote oreado (cantidad mal registrada: debería ser menos por merma)
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'ORE-001',
    'oreado',
    NOW() - INTERVAL '8 days',
    1500,  -- Error: debería ser 1480 kg
    '{"humedad_inicial": 55, "humedad_final": 45}'::jsonb
  )
  RETURNING id INTO lote_oreado_id;

  -- Relacionar
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES
    (op_oreado_id, lote_primera_id, 'input', 1500),
    (op_oreado_id, lote_oreado_id, 'output', 1500);

END $$;


-- =====================================================
-- PASO 4: AJUSTE DE MERMA
-- =====================================================
-- Se corrige la cantidad: realmente hubo merma de 20 kg

DO $$
DECLARE
  op_ajuste_id UUID;
  lote_oreado_id UUID;
  lote_oreado_corr_id UUID;
BEGIN
  RAISE NOTICE 'Aplicando ajuste de merma...';

  -- Obtener ID del lote oreado
  SELECT id INTO lote_oreado_id FROM lotes WHERE codigo = 'ORE-001';

  -- Crear operación de ajuste
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'ajuste_merma',
    NOW() - INTERVAL '7 days',
    '{"motivo": "Corrección de pesaje", "merma_kg": 20}'::jsonb
  )
  RETURNING id INTO op_ajuste_id;

  -- Crear lote corregido
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'ORE-001A',
    'oreado',
    NOW() - INTERVAL '7 days',
    1480,
    '{"humedad": 45, "corregido": true}'::jsonb
  )
  RETURNING id INTO lote_oreado_corr_id;

  -- Relacionar
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES
    (op_ajuste_id, lote_oreado_id, 'input', 1500),
    (op_ajuste_id, lote_oreado_corr_id, 'output', 1480);

END $$;


-- =====================================================
-- PASO 5: AJUSTE DE TIPO
-- =====================================================
-- Se descubre que en realidad era presecado, no oreado

DO $$
DECLARE
  op_ajuste_tipo_id UUID;
  lote_oreado_corr_id UUID;
  lote_presecado_id UUID;
BEGIN
  RAISE NOTICE 'Aplicando ajuste de tipo...';

  -- Obtener ID del lote oreado corregido
  SELECT id INTO lote_oreado_corr_id FROM lotes WHERE codigo = 'ORE-001A';

  -- Crear operación de ajuste de tipo
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'ajuste_tipo',
    NOW() - INTERVAL '6 days',
    '{"motivo": "Revisión de proceso", "tipo_anterior": "oreado", "tipo_nuevo": "presecado"}'::jsonb
  )
  RETURNING id INTO op_ajuste_tipo_id;

  -- Crear lote con tipo correcto
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'PRE-001',
    'presecado',
    NOW() - INTERVAL '6 days',
    1480,
    '{"humedad": 45, "tipo_corregido": true}'::jsonb
  )
  RETURNING id INTO lote_presecado_id;

  -- Relacionar
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES
    (op_ajuste_tipo_id, lote_oreado_corr_id, 'input', 1480),
    (op_ajuste_tipo_id, lote_presecado_id, 'output', 1480);

END $$;


-- =====================================================
-- PASO 6: REPOSO
-- =====================================================
-- El presecado pasa a reposo

DO $$
DECLARE
  op_reposo_id UUID;
  lote_presecado_id UUID;
  lote_reposo_id UUID;
BEGIN
  RAISE NOTICE 'Creando reposo...';

  -- Obtener ID del lote presecado
  SELECT id INTO lote_presecado_id FROM lotes WHERE codigo = 'PRE-001';

  -- Crear operación de reposo
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'reposo',
    NOW() - INTERVAL '5 days',
    '{"area": "Bodega A", "dias_reposo": 3}'::jsonb
  )
  RETURNING id INTO op_reposo_id;

  -- Crear lote en reposo
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'REP-001',
    'reposo',
    NOW() - INTERVAL '5 days',
    1480,
    '{"humedad": 43}'::jsonb
  )
  RETURNING id INTO lote_reposo_id;

  -- Relacionar
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES
    (op_reposo_id, lote_presecado_id, 'input', 1480),
    (op_reposo_id, lote_reposo_id, 'output', 1480);

END $$;


-- =====================================================
-- PASO 7: SEGUNDO FLUJO (para mezclar en secado)
-- =====================================================
-- Crear otro lote de reposo de un proceso paralelo

DO $$
DECLARE
  lote_reposo2_id UUID;
BEGIN
  RAISE NOTICE 'Creando segundo lote de reposo (proceso paralelo)...';

  -- Crear lote de reposo directamente (proceso simplificado)
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'REP-002',
    'reposo',
    NOW() - INTERVAL '4 days',
    520,
    '{"humedad": 42, "origen": "Proceso B"}'::jsonb
  )
  RETURNING id INTO lote_reposo2_id;

END $$;


-- =====================================================
-- PASO 8: SECADO (MEZCLA DE DOS REPOSOS)
-- =====================================================
-- Se mezclan REP-001 y REP-002 para el secado final

DO $$
DECLARE
  op_secado_id UUID;
  lote_reposo1_id UUID;
  lote_reposo2_id UUID;
  lote_secado_id UUID;
BEGIN
  RAISE NOTICE 'Creando secado (mezcla de reposos)...';

  -- Obtener IDs de los lotes de reposo
  SELECT id INTO lote_reposo1_id FROM lotes WHERE codigo = 'REP-001';
  SELECT id INTO lote_reposo2_id FROM lotes WHERE codigo = 'REP-002';

  -- Crear operación de secado
  INSERT INTO operaciones (tipo, fecha, meta)
  VALUES (
    'secado',
    NOW() - INTERVAL '2 days',
    '{"secadora": "Solar 1", "temperatura_max": 45, "dias": 7}'::jsonb
  )
  RETURNING id INTO op_secado_id;

  -- Crear lote secado final
  INSERT INTO lotes (codigo, tipo, fecha_creado, cantidad_kg, meta)
  VALUES (
    'SEC-001',
    'secado',
    NOW() - INTERVAL '2 days',
    2000,
    '{"humedad_final": 11.5, "calidad": "Pergamino seco"}'::jsonb
  )
  RETURNING id INTO lote_secado_id;

  -- Relacionar: dos reposos como input
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES
    (op_secado_id, lote_reposo1_id, 'input', 1480),
    (op_secado_id, lote_reposo2_id, 'input', 520);

  -- Relacionar: secado como output
  INSERT INTO operacion_lotes (operacion_id, lote_id, rol, cantidad_kg)
  VALUES (op_secado_id, lote_secado_id, 'output', 2000);

END $$;


-- =====================================================
-- RESUMEN DE DATOS CREADOS
-- =====================================================
DO $$
DECLARE
  total_lotes INTEGER;
  total_operaciones INTEGER;
  total_relaciones INTEGER;
BEGIN
  SELECT COUNT(*) INTO total_lotes FROM lotes;
  SELECT COUNT(*) INTO total_operaciones FROM operaciones;
  SELECT COUNT(*) INTO total_relaciones FROM operacion_lotes;

  RAISE NOTICE '';
  RAISE NOTICE '✓ Datos de ejemplo creados exitosamente';
  RAISE NOTICE '  - % lotes creados', total_lotes;
  RAISE NOTICE '  - % operaciones creadas', total_operaciones;
  RAISE NOTICE '  - % relaciones lote-operación creadas', total_relaciones;
  RAISE NOTICE '';
  RAISE NOTICE 'Lote final: SEC-001 (Secado)';
  RAISE NOTICE 'Puedes consultar su trazabilidad completa con:';
  RAISE NOTICE '  SELECT * FROM get_trazabilidad((SELECT id FROM lotes WHERE codigo = ''SEC-001''));';
END $$;
