-- =============================================================================
--  VERIFICAR PRECONDICIONES DEL CANAL INVERSO  —  SOLO LECTURA
--
--  Proyecto : CL032BACK (portal público)   ·   Esquema: asturias_api
--  Archivo  : docs/replicacion/sql/verificar_precondiciones.sql
--  Guía     : docs/replicacion/07-ACTIVACION-PASO-A-PASO.md
-- =============================================================================
--
--  QUÉ ES
--    El esquema puede estar perfecto y el canal fallar igual, porque hay
--    PRECONDICIONES DE DATOS que ningún `ALTER TABLE` arregla. Este script las mide.
--    No modifica nada: solo consulta.
--
--    Ejecútalo ANTES de encender la recepción. Si algo sale distinto de lo esperado,
--    la sección 6 trae la corrección.
--
--  CÓMO EJECUTAR
--    mysql -u USUARIO -p asturias_api < verificar_precondiciones.sql
-- =============================================================================


-- -----------------------------------------------------------------------------
-- 1. ESQUEMA — ¿están las columnas del canal inverso?
-- -----------------------------------------------------------------------------
SELECT 'ESQUEMA' AS bloque, 'columnas del canal inverso' AS comprueba,
       COUNT(*) AS encontradas, 6 AS esperadas,
       IF(COUNT(*) = 6, 'OK', 'FALTA: ejecuta activar_replica_inversa.sql') AS resultado
  FROM information_schema.COLUMNS
 WHERE TABLE_SCHEMA = DATABASE()
   AND ((TABLE_NAME = 'rsv_reservacion' AND COLUMN_NAME IN
            ('reservacionVersionReplica','reservacionHashReplica','reservacionFechaReplica'))
     OR (TABLE_NAME = 'rsv_reservacionhabitacion'        AND COLUMN_NAME = 'idReservacionHabitacionPrivado')
     OR (TABLE_NAME = 'rsv_reservacionhabitacionpaquete' AND COLUMN_NAME = 'idReservacionHabitacionPaquetePrivado')
     OR (TABLE_NAME = 'rsv_reservacionhabitacionextra'   AND COLUMN_NAME = 'idReservacionHabitacionExtraPrivado'));


-- -----------------------------------------------------------------------------
-- 2. LA FRONTERA — sin esto no hay canal, y el de ida se rompe
-- -----------------------------------------------------------------------------
SELECT 'FRONTERA' AS bloque, 'maestria + captura' AS comprueba,
       (SELECT COUNT(*) FROM information_schema.COLUMNS
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'rsv_reservacion'
           AND COLUMN_NAME IN ('reservacionMaestro','reservacionFechaMaestro')) AS columnas,
       (SELECT COUNT(*) FROM information_schema.TRIGGERS
         WHERE TRIGGER_SCHEMA = DATABASE() AND EVENT_OBJECT_TABLE LIKE 'rsv_reservacion%') AS triggers_,
       (SELECT COUNT(*) FROM information_schema.ROUTINES
         WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_NAME = 'sp_rsv_marcar_replicacion'
           AND ROUTINE_DEFINITION LIKE '%reservacionMaestro%') AS guarda,
       'esperado: 2 columnas, 12 triggers, 1 guarda' AS esperado;


-- -----------------------------------------------------------------------------
-- 3. ⚠ RIESGO A — privadas SIN puntero al maestro
--
--    `idReservacionPrivado` es LA CLAVE DE EMPAREJAMIENTO. El endpoint busca la
--    reservación local por ahí; si está NULL no la encuentra y la trata como ALTA:
--    CREA UNA RESERVACIÓN NUEVA. El socio vería la misma reservación DOS VECES.
--
--    Afecta a las selladas antes de que el veredicto trajera `idReservacionRemoto`.
--    DEBE SER 0.
-- -----------------------------------------------------------------------------
SELECT 'RIESGO A' AS bloque, 'privadas sin idReservacionPrivado' AS comprueba,
       COUNT(*) AS encontradas, 0 AS esperadas,
       IF(COUNT(*) = 0, 'OK', 'CORREGIR: ver seccion 6.1 — se DUPLICARIAN al activar') AS resultado
  FROM rsv_reservacion
 WHERE reservacionMaestro = 'Privado' AND idReservacionPrivado IS NULL;

-- El detalle de las afectadas, para cruzarlas a mano contra Reservaciones V2:
SELECT idReservacion, reservacionNo, reservacionEstado, reservacionFechaLlegada,
       reservacionImporte, idMembresia, reservacionFechaMaestro
  FROM rsv_reservacion
 WHERE reservacionMaestro = 'Privado' AND idReservacionPrivado IS NULL
 ORDER BY idReservacion;


-- -----------------------------------------------------------------------------
-- 4. ⚠ RIESGO B — canceladas que siguen en maestría 'Portal'
--
--    Si Reservaciones V2 manda el snapshot de una cancelada que aquí sigue marcada 'Portal',
--    el portal responde `409 maestria_portal`, que significa "hay una carrera con el
--    veredicto, reintenta". Pero la carrera NUNCA se resuelve: Reservaciones V2 REINTENTARÍA
--    PARA SIEMPRE, consumiendo ciclos y alimentando el cortacircuitos.
--
--    El backfill de maestría selló solo 'Reservado' y 'Finalizado' a propósito: por el
--    estado no se puede saber si una 'Cancelado' viene de 'Temporal' (nunca fue venta,
--    y entonces el portal SÍ es su maestro) o de 'Reservado' (sí lo fue).
--
--    Lo que las distingue es tener réplica PROCESADA: significa que Reservaciones V2 las conoce.
-- -----------------------------------------------------------------------------
SELECT 'RIESGO B' AS bloque, 'canceladas Portal que Reservaciones V2 conoce' AS comprueba,
       COUNT(DISTINCT r.idReservacion) AS encontradas, 0 AS esperadas,
       IF(COUNT(DISTINCT r.idReservacion) = 0, 'OK',
          'CORREGIR: ver seccion 6.2 — Reservaciones V2 reintentaria sin fin') AS resultado
  FROM rsv_reservacion r
  JOIN rsv_replicacion p ON p.idReservacion = r.idReservacion
 WHERE r.reservacionMaestro = 'Portal'
   AND r.reservacionEstado  = 'Cancelado'
   AND p.replicacionEstado  = 'Procesado';


-- -----------------------------------------------------------------------------
-- 5. INFORMATIVO — cuánto trabajo se ahorra por tener los punteros al día
--
--    Con `REPLICACION_INVERSA_PUNTEROS=true` las ventas nuevas ya llegan emparejadas.
--    Las que aparezcan aquí caerán UNA VEZ en la adopción por respaldo: se reemplaza
--    su detalle, se regeneran los ids visibles y se levanta una R12. Es correcto, pero
--    conviene saber cuántas son antes de encender.
-- -----------------------------------------------------------------------------
SELECT 'INFO' AS bloque, 'privadas que caerian en adopcion por respaldo' AS comprueba,
       COUNT(*) AS reservaciones
  FROM rsv_reservacion r
 WHERE r.reservacionMaestro = 'Privado'
   AND NOT EXISTS (SELECT 1 FROM rsv_reservacionhabitacion h
                    WHERE h.idReservacion = r.idReservacion
                      AND h.idReservacionHabitacionPrivado IS NOT NULL)
   AND EXISTS     (SELECT 1 FROM rsv_reservacionhabitacion h
                    WHERE h.idReservacion = r.idReservacion);

SELECT 'INFO' AS bloque, 'reparto por maestria y estado' AS comprueba,
       reservacionMaestro, reservacionEstado, COUNT(*) AS n,
       SUM(idReservacionPrivado IS NOT NULL) AS con_puntero
  FROM rsv_reservacion
 GROUP BY reservacionMaestro, reservacionEstado
 ORDER BY reservacionMaestro, reservacionEstado;


-- =============================================================================
--  6. CORRECCIONES  —  descomentar y ejecutar SOLO lo que haga falta
-- =============================================================================
--
--  6.1 · RIESGO A — rellenar `idReservacionPrivado`
--
--      NO HAY FORMA AUTOMÁTICA FIABLE de cruzarlas: el portal y Reservaciones V2 usan folios
--      distintos (`reservacionNo` propio vs `max+1` del maestro), así que no se pueden
--      emparejar por folio. Hay que hacerlo con acceso a las dos bases, cruzando por
--      membresía + fechas de llegada/salida + importe, y REVISANDO UNA POR UNA.
--
--      Consulta a correr en Reservaciones V2 para cada fila del listado de la sección 3:
--
--      -- SELECT idReservacion, reservacionNo, reservacionFechaLlegada, reservacionFechaSalida,
--      --        reservacionImporte
--      --   FROM rsv_reservacion
--      --  WHERE idMembresia = (el equivalente en Reservaciones V2 de la membresia del portal)
--      --    AND reservacionFechaLlegada = 'YYYY-MM-DD'
--      --    AND reservacionFechaSalida  = 'YYYY-MM-DD';
--
--      Y después, en el portal, una por una:
--
--      -- UPDATE `rsv_reservacion`
--      --    SET `idReservacionPrivado` = <id en Reservaciones V2>
--      --  WHERE `idReservacion` = <id en el portal>
--      --    AND `idReservacionPrivado` IS NULL;      -- la guarda evita pisar una ya resuelta
--
--      ⚠ NO lo automatices con un JOIN por atributos. Dos reservaciones del mismo socio
--        con las mismas fechas son legítimas, y emparejar mal es escribirle a un socio la
--        reservación de otro — el peor desenlace posible del canal.
--
--      SI SON MUCHAS Y NO SE PUEDEN CRUZAR: la alternativa segura es dejarlas fuera del
--      ámbito en Reservaciones V2 (`reservacionReplicaPortal = 'N'`) para que nunca se repliquen.
--      Pierdes que el socio las vea al día, pero no duplicas nada.
--
--
--  6.2 · RIESGO B — sellar las canceladas que Reservaciones V2 ya conoce
--
--      Su réplica está PROCESADA, así que el maestro las tiene. Sellarlas es reconocer
--      un hecho, no cambiar el gobierno del dato.
--
--      La fecha sale de la réplica procesada, no de NOW(): así la auditoría dice cuándo
--      pasó de verdad.
--
--      -- UPDATE `rsv_reservacion` r
--      --   JOIN (SELECT idReservacion, MAX(replicacionFechaProceso) AS f
--      --           FROM rsv_replicacion WHERE replicacionEstado = 'Procesado'
--      --          GROUP BY idReservacion) p ON p.idReservacion = r.idReservacion
--      --    SET r.`reservacionMaestro`      = 'Privado',
--      --        r.`reservacionFechaMaestro` = COALESCE(p.f, r.reservacionFecha, NOW())
--      --  WHERE r.`reservacionMaestro` = 'Portal'
--      --    AND r.`reservacionEstado`  = 'Cancelado';
--
--      ⚠ Este UPDATE dispara `trg_rsv_reservacion_au`, pero NO genera marcas: el trigger
--        corre después de la escritura y ya lee 'Privado', así que la guarda corta.
--        Verifícalo igual:
--        -- SELECT COUNT(*) AS debe_ser_0 FROM rsv_replicacion
--        --  WHERE replicacionEstado IN ('Pendiente','Error');
--
-- =============================================================================
--  FIN
-- =============================================================================
