DELIMITER $$

DROP PROCEDURE IF EXISTS spu_caja_cerrar $$
CREATE PROCEDURE spu_caja_cerrar(IN p_suc_id INT, IN p_fecha DATE)
BEGIN
  DECLARE v_caj_id INT;
  DECLARE v_caj_fecha DATE;
  DECLARE v_cierre DECIMAL(12,2);

  SELECT caj_id, caj_fecha
    INTO v_caj_id, v_caj_fecha
  FROM caja
  WHERE suc_id = p_suc_id
    AND caj_estado = 'ABIERTA'
    AND (p_fecha IS NULL OR caj_fecha = p_fecha)
  ORDER BY caj_fecha DESC, caj_id DESC
  LIMIT 1;

  IF v_caj_id IS NULL THEN
    SELECT caj_id, caj_fecha
      INTO v_caj_id, v_caj_fecha
    FROM caja
    WHERE suc_id = p_suc_id
      AND caj_estado = 'ABIERTA'
    ORDER BY caj_fecha DESC, caj_id DESC
    LIMIT 1;
  END IF;

  IF v_caj_id IS NULL THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No existe caja abierta para cerrar';
  END IF;

  IF EXISTS (
    SELECT 1
    FROM atenciones
    WHERE suc_id = p_suc_id
      AND DATE(atn_fecha) = v_caj_fecha
      AND atn_estado IN ('REGISTRADO','EN_PROGRESO','FINALIZADO')
  ) THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No puede cerrar caja con atenciones pendientes o finalizadas sin cobrar.';
  END IF;

  SELECT c.caj_apertura + COALESCE(SUM(CASE WHEN cm.cam_tipo = 'INGRESO' THEN cm.cam_monto WHEN cm.cam_tipo = 'EGRESO' THEN -cm.cam_monto ELSE 0 END), 0)
    INTO v_cierre
  FROM caja c
  LEFT JOIN caja_movimientos cm ON cm.caj_id = c.caj_id
  WHERE c.caj_id = v_caj_id
  GROUP BY c.caj_id, c.caj_apertura;

  UPDATE caja
     SET caj_cierre = v_cierre,
         caj_estado = 'CERRADA',
         caj_conforme = 0
   WHERE caj_id = v_caj_id;

  INSERT INTO caja_movimientos(caj_id, cam_tipo, cam_monto, cam_observacion)
  VALUES(v_caj_id, 'CIERRE', v_cierre, 'Cierre de caja pendiente de conformidad');

  SELECT * FROM caja WHERE caj_id = v_caj_id;
END $$

DELIMITER ;
