-- Parche 061
-- Corrige el DNI del docente PANDURO SILVA HENRY CARLOS y consolida sus
-- relaciones academicas si en algun servidor quedaron dos docentes por el
-- cambio de DNI.
--
-- DNI incorrecto inicial: 42086285
-- DNI correcto:            42361656
--
-- El parche es idempotente. Puede ejecutarse mas de una vez.
-- No elimina notas. Las calificaciones de nota_estudiante se mantienen porque estan
-- vinculadas a matricula, periodo, area y competencia; no al DNI del docente.
-- Los aportes transversales y demas registros vinculados a id_docente se
-- reasignan al docente canonico para que el acceso con el DNI correcto los vea.

START TRANSACTION;

SET @dni_anterior := '42086285';
SET @dni_correcto := '42361656';
SET @hash_dni_correcto := '$2y$10$mrwXfd5Ean9oRkBUdgzei.HKIAA/P6pSP2U7RrGNqy2MCbBdigPyq';

SET @persona_correcta := (
    SELECT id_persona
    FROM persona
    WHERE numero_documento = @dni_correcto
    ORDER BY id_persona
    LIMIT 1
);

SET @persona_anterior := (
    SELECT id_persona
    FROM persona
    WHERE numero_documento = @dni_anterior
    ORDER BY id_persona
    LIMIT 1
);

-- Si aun no existe persona con el DNI correcto, corrige la persona antigua.
UPDATE persona
SET numero_documento = @dni_correcto
WHERE id_persona = @persona_anterior
  AND @persona_correcta IS NULL;

SET @persona_docente := (
    SELECT id_persona
    FROM persona
    WHERE numero_documento = @dni_correcto
    ORDER BY id_persona
    LIMIT 1
);

SET @docente_id := (
    SELECT candidato.id_docente
    FROM (
        SELECT us.id_docente, 0 prioridad, us.estado, us.id_usuario orden
        FROM usuario_sistema us
        WHERE us.usuario = @dni_correcto
          AND us.id_docente IS NOT NULL

        UNION ALL

        SELECT us.id_docente, 1 prioridad, us.estado, us.id_usuario orden
        FROM usuario_sistema us
        WHERE us.usuario = @dni_anterior
          AND us.id_docente IS NOT NULL

        UNION ALL

        SELECT d.id_docente, 2 prioridad, d.estado, d.id_docente orden
        FROM docente d
        INNER JOIN persona p ON p.id_persona = d.id_persona
        WHERE p.numero_documento = @dni_correcto

        UNION ALL

        SELECT d.id_docente, 3 prioridad, d.estado, d.id_docente orden
        FROM docente d
        INNER JOIN persona p ON p.id_persona = d.id_persona
        WHERE p.numero_documento = @dni_anterior

        UNION ALL

        SELECT h.id_docente, 4 prioridad, 1 estado, h.id_horario orden
        FROM docente_horario_clase h
        WHERE h.dni_docente = @dni_anterior
          AND h.id_docente IS NOT NULL
    ) candidato
    ORDER BY candidato.prioridad, candidato.estado DESC, candidato.orden DESC
    LIMIT 1
);

DROP TEMPORARY TABLE IF EXISTS tmp_docente_dni_fix;
CREATE TEMPORARY TABLE tmp_docente_dni_fix (
    id_docente INT UNSIGNED NOT NULL PRIMARY KEY
) ENGINE=MEMORY;

INSERT IGNORE INTO tmp_docente_dni_fix (id_docente)
SELECT d.id_docente
FROM docente d
INNER JOIN persona p ON p.id_persona = d.id_persona
WHERE p.numero_documento IN (@dni_correcto, @dni_anterior);

INSERT IGNORE INTO tmp_docente_dni_fix (id_docente)
SELECT us.id_docente
FROM usuario_sistema us
WHERE us.usuario IN (@dni_correcto, @dni_anterior)
  AND us.id_docente IS NOT NULL;

INSERT IGNORE INTO tmp_docente_dni_fix (id_docente)
SELECT h.id_docente
FROM docente_horario_clase h
WHERE h.dni_docente IN (@dni_correcto, @dni_anterior)
  AND h.id_docente IS NOT NULL;

INSERT IGNORE INTO tmp_docente_dni_fix (id_docente)
SELECT @docente_id
WHERE @docente_id IS NOT NULL;

-- Si el docente quedo apuntando a la persona del DNI antiguo y ya existe la persona correcta,
-- se mantiene el mismo id_docente para no perder asignaciones, sesiones ni trazabilidad.
UPDATE docente
SET id_persona = @persona_docente,
    estado = 1
WHERE id_docente = @docente_id
  AND @persona_docente IS NOT NULL;

SET @nombre_docente := (
    SELECT COALESCE(NULLIF(p.nombre_completo, ''), TRIM(CONCAT_WS(' ', p.apellido_paterno, p.apellido_materno, p.nombres)))
    FROM docente d
    INNER JOIN persona p ON p.id_persona = d.id_persona
    WHERE d.id_docente = @docente_id
    LIMIT 1
);

-- Si solo existe el usuario antiguo, lo convierte al usuario correcto.
UPDATE usuario_sistema
SET usuario = @dni_correcto,
    password_hash = @hash_dni_correcto,
    nombres = COALESCE(NULLIF(@nombre_docente, ''), nombres),
    rol = 'DOCENTE',
    id_docente = @docente_id,
    id_persona = @persona_docente,
    estado = 1,
    requiere_cambio_clave = 1,
    clave_actualizada_en = NULL
WHERE usuario = @dni_anterior
  AND @docente_id IS NOT NULL
  AND @persona_docente IS NOT NULL
  AND NOT EXISTS (
      SELECT 1
      FROM (
          SELECT id_usuario
          FROM usuario_sistema
          WHERE usuario = @dni_correcto
      ) usuario_correcto
  );

-- Si ya existe el usuario correcto, lo vincula al docente y restablece su clave al DNI correcto.
UPDATE usuario_sistema
SET password_hash = @hash_dni_correcto,
    nombres = COALESCE(NULLIF(@nombre_docente, ''), nombres),
    rol = 'DOCENTE',
    id_docente = @docente_id,
    id_persona = @persona_docente,
    estado = 1,
    requiere_cambio_clave = 1,
    clave_actualizada_en = NULL
WHERE usuario = @dni_correcto
  AND @docente_id IS NOT NULL
  AND @persona_docente IS NOT NULL;

-- Si quedaron ambos usuarios, desactiva el acceso con el DNI antiguo.
UPDATE usuario_sistema
SET estado = 0,
    requiere_cambio_clave = 1
WHERE usuario = @dni_anterior
  AND EXISTS (
      SELECT 1
      FROM (
          SELECT id_usuario
          FROM usuario_sistema
          WHERE usuario = @dni_correcto
            AND estado = 1
      ) usuario_correcto_activo
  );

-- Reasigna informacion academica y administrativa desde posibles id_docente
-- duplicados hacia el id_docente que usara el acceso con DNI correcto.
UPDATE IGNORE docente_area_cargo da
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = da.id_docente
SET da.id_docente = @docente_id,
    da.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND da.id_docente <> @docente_id;

UPDATE docente_area_cargo da
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = da.id_docente
SET da.estado = 0,
    da.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND da.id_docente <> @docente_id;

UPDATE docente_cuadro_horas ch
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = ch.id_docente
SET ch.id_docente = @docente_id,
    ch.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND ch.id_docente <> @docente_id;

UPDATE docente_perfil_laboral pl
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = pl.id_docente
SET pl.id_docente = @docente_id,
    pl.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND pl.id_docente <> @docente_id;

UPDATE docente_programacion_archivo pa
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = pa.id_docente
SET pa.id_docente = @docente_id,
    pa.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND pa.id_docente <> @docente_id;

UPDATE IGNORE docente_tutoria dt
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = dt.id_docente
SET dt.id_docente = @docente_id,
    dt.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND dt.id_docente <> @docente_id;

UPDATE docente_tutoria dt
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = dt.id_docente
SET dt.estado = 0,
    dt.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND dt.id_docente <> @docente_id;

UPDATE eval_auxiliar_sesion eas
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = eas.id_docente
SET eas.id_docente = @docente_id,
    eas.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND eas.id_docente <> @docente_id;

UPDATE mon_cuaderno_campo cc
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = cc.id_docente
SET cc.id_docente = @docente_id,
    cc.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND cc.id_docente <> @docente_id;

UPDATE mon_monitoreo mm
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = mm.id_docente
SET mm.id_docente = @docente_id,
    mm.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND mm.id_docente <> @docente_id;

UPDATE mon_observacion_aula oa
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = oa.id_docente
SET oa.id_docente = @docente_id,
    oa.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND oa.id_docente <> @docente_id;

UPDATE IGNORE nota_transversal_docente nt
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = nt.id_docente
SET nt.id_docente = @docente_id,
    nt.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND nt.id_docente <> @docente_id;

UPDATE portal_familia_comunicado pc
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = pc.id_docente
SET pc.id_docente = @docente_id,
    pc.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND pc.id_docente <> @docente_id;

UPDATE aula_virtual_actividad ava
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = ava.id_docente
SET ava.id_docente = @docente_id,
    ava.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND ava.id_docente <> @docente_id;

UPDATE conectaie_clase_trabajo ct
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = ct.id_docente
SET ct.id_docente = @docente_id,
    ct.actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND ct.id_docente <> @docente_id;

UPDATE conectaie_retroalimentacion cr
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = cr.id_docente
SET cr.id_docente = @docente_id
WHERE @docente_id IS NOT NULL
  AND cr.id_docente <> @docente_id;

-- Corrige horarios importados antiguos, incluso si la fila quedo sin id_docente pero con el DNI antiguo.
UPDATE docente_horario_clase
SET id_docente = @docente_id,
    dni_docente = @dni_correcto,
    docente_nombre = COALESCE(NULLIF(@nombre_docente, ''), docente_nombre),
    actualizado_en = NOW()
WHERE @docente_id IS NOT NULL
  AND (
        id_docente = @docente_id
        OR dni_docente = @dni_anterior
        OR (
            UPPER(docente_nombre) LIKE '%PANDURO%'
            AND UPPER(docente_nombre) LIKE '%SILVA%'
            AND UPPER(docente_nombre) LIKE '%HENRY%'
        )
  )
  AND (dni_docente IS NULL OR dni_docente <> @dni_correcto);

-- Normaliza cualquier horario vinculado a un docente cuyo DNI haya cambiado en persona.
UPDATE docente_horario_clase h
INNER JOIN docente d ON d.id_docente = h.id_docente
INNER JOIN persona p ON p.id_persona = d.id_persona
SET h.dni_docente = p.numero_documento,
    h.docente_nombre = COALESCE(NULLIF(p.nombre_completo, ''), TRIM(CONCAT_WS(' ', p.apellido_paterno, p.apellido_materno, p.nombres))),
    h.actualizado_en = NOW()
WHERE h.id_docente IS NOT NULL
  AND p.numero_documento <> ''
  AND (h.dni_docente IS NULL OR h.dni_docente <> p.numero_documento);

UPDATE docente d
INNER JOIN tmp_docente_dni_fix t ON t.id_docente = d.id_docente
SET d.estado = CASE WHEN d.id_docente = @docente_id THEN 1 ELSE 0 END
WHERE @docente_id IS NOT NULL;

DROP TEMPORARY TABLE IF EXISTS tmp_docente_dni_fix;

COMMIT;
