-- Normaliza el case de cfdis.uuid y elimina duplicados generados por el
-- mismatch case-sensitive entre los dos paths de sync SAT:
--   - source='sat' (XML parser): insertaba UUIDs como venían del XML (lowercase)
--   - source='sat-metadata' (CSV parser): insertaba UUIDs del CSV (UPPERCASE)
-- La constraint UNIQUE(uuid) de Postgres es case-sensitive → ambos convivían
-- como filas distintas, duplicando el CFDI en todas las métricas.
--
-- Estrategia (idempotente — en tenants sin duplicados es no-op):
--   1. Propagar status=Cancelado de metadata→sat si corresponde (guard de
--      data loss; verificado que en Patito no aplica a ninguna fila, pero la
--      cláusula queda como protección para futuros despachos).
--   2. Borrar las filas 'sat-metadata' que tengan par 'sat' con el mismo UUID
--      (case-insensitive). Las filas sat-metadata sin par se conservan (son
--      legítimas: CFDIs cancelados sin XML).
--   3. Normalizar todos los UUIDs restantes a lowercase.
-- El código de saveCfdis/saveMetadata también fue actualizado para (a) matchear
-- case-insensitive, (b) insertar siempre en lowercase.

-- 1. Propagar Cancelado antes de borrar
UPDATE cfdis sat
SET status = 'Cancelado',
    fecha_cancelacion = COALESCE(sat.fecha_cancelacion, meta.fecha_cancelacion),
    actualizado_en = NOW()
FROM cfdis meta
WHERE LOWER(sat.uuid) = LOWER(meta.uuid)
  AND sat.id != meta.id
  AND sat.source = 'sat'
  AND meta.source = 'sat-metadata'
  AND meta.status = 'Cancelado'
  AND sat.status != 'Cancelado';

-- 2. Borrar duplicados sat-metadata
DELETE FROM cfdis meta
WHERE meta.source = 'sat-metadata'
  AND EXISTS (
    SELECT 1 FROM cfdis sat
    WHERE LOWER(meta.uuid) = LOWER(sat.uuid)
      AND sat.id != meta.id
      AND sat.source = 'sat'
  );

-- 3. Normalizar a lowercase
UPDATE cfdis SET uuid = LOWER(uuid) WHERE uuid IS NOT NULL AND uuid != LOWER(uuid);

INSERT INTO tenant_migrations (scope, version, name)
VALUES ('vertical-contable', 26, '026_normalize_cfdi_uuid_case')
ON CONFLICT (scope, version) DO NOTHING;
