USE peluqueria;

DELIMITER $$

DROP PROCEDURE IF EXISTS spu_atencion_servicios_agregar $$
CREATE PROCEDURE spu_atencion_servicios_agregar(
  IN p_atn_id INT,
  IN p_servicios JSON
)
BEGIN
  DECLARE v_idx INT DEFAULT 0;
  DECLARE v_len INT DEFAULT 0;
  DECLARE v_ser_id INT;
  DECLARE v_tra_id INT;
  DECLARE v_cantidad DECIMAL(12,2);
  DECLARE v_precio DECIMAL(12,2);
  DECLARE v_precio_json DECIMAL(12,2);
  DECLARE v_comision DECIMAL(5,2);
  DECLARE v_estado VARCHAR(20);

  SELECT atn_estado INTO v_estado
  FROM atenciones
  WHERE atn_id = p_atn_id
  LIMIT 1;

  IF v_estado IS NULL THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'La atencion no existe';
  END IF;

  IF v_estado = 'PAGADO' THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No puede agregar servicios a una atencion pagada';
  END IF;

  SET v_len = COALESCE(JSON_LENGTH(p_servicios), 0);

  IF v_len = 0 THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Debe enviar al menos un servicio';
  END IF;

  WHILE v_idx < v_len DO
    SET v_ser_id = CAST(JSON_UNQUOTE(JSON_EXTRACT(p_servicios, CONCAT('$[', v_idx, '].ser_id'))) AS UNSIGNED);
    SET v_tra_id = CAST(JSON_UNQUOTE(JSON_EXTRACT(p_servicios, CONCAT('$[', v_idx, '].tra_id'))) AS UNSIGNED);
    SET v_cantidad = COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(p_servicios, CONCAT('$[', v_idx, '].cantidad'))) AS DECIMAL(12,2)), 1);
    SET v_precio_json = COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(p_servicios, CONCAT('$[', v_idx, '].precio'))) AS DECIMAL(12,2)), 0);

    SELECT CASE WHEN v_precio_json > 0 THEN v_precio_json ELSE ser_precio END, ser_comision_pct
      INTO v_precio, v_comision
      FROM servicios
     WHERE ser_id = v_ser_id;

    INSERT INTO atencion_detalle_servicios(atn_id, ser_id, tra_id, ads_cantidad, ads_precio, ads_total, ads_comision_pct)
    VALUES(p_atn_id, v_ser_id, v_tra_id, v_cantidad, v_precio, v_cantidad * v_precio, v_comision);

    SET v_idx = v_idx + 1;
  END WHILE;

  SELECT * FROM atenciones WHERE atn_id = p_atn_id;
END $$

DROP PROCEDURE IF EXISTS spu_atencion_lis $$
CREATE PROCEDURE spu_atencion_lis(IN p_suc_id INT, IN p_fecha DATE, IN p_estado VARCHAR(20))
BEGIN
  SELECT
    a.atn_id,
    a.atn_codigo,
    a.atn_fecha,
    a.atn_estado,
    a.cli_id,
    a.ven_id,
    COALESCE(NULLIF(TRIM(CONCAT_WS(' ', pc.per_nombres, pc.per_apepat, pc.per_apemat)), ''), 'Cliente sin nombre') AS cliente,
    COALESCE(GROUP_CONCAT(DISTINCT s.ser_nombre ORDER BY s.ser_nombre SEPARATOR ', '), 'Sin servicios asignados') AS servicios,
    COALESCE(GROUP_CONCAT(DISTINCT CONCAT_WS(' ', pt.per_nombres, pt.per_apepat) ORDER BY pt.per_nombres SEPARATOR ', '), '') AS trabajadores,
    COALESCE(SUM(CASE WHEN d.ads_estado <> 'ANULADO' THEN d.ads_total ELSE 0 END), 0) AS total
  FROM atenciones a
  LEFT JOIN clientes c ON c.cli_id = a.cli_id
  LEFT JOIN personas pc ON pc.per_id = c.per_id
  LEFT JOIN atencion_detalle_servicios d ON d.atn_id = a.atn_id
  LEFT JOIN servicios s ON s.ser_id = d.ser_id
  LEFT JOIN trabajadores t ON t.tra_id = d.tra_id
  LEFT JOIN personas pt ON pt.per_id = t.per_id
  WHERE a.suc_id = p_suc_id
    AND DATE(a.atn_fecha) = p_fecha
    AND (p_estado IS NULL OR p_estado = '' OR a.atn_estado = p_estado)
  GROUP BY a.atn_id, a.atn_codigo, a.atn_fecha, a.atn_estado, a.cli_id, a.ven_id, cliente
  ORDER BY FIELD(a.atn_estado, 'EN_PROGRESO','FINALIZADO','REGISTRADO','PAGADO','ANULADO'), a.atn_id DESC;
END $$

DROP PROCEDURE IF EXISTS spu_caja_cierre_ticket $$
CREATE PROCEDURE spu_caja_cierre_ticket(IN p_caj_id INT)
BEGIN
  SELECT
    c.*,
    s.suc_nombre,
    COALESCE(SUM(CASE WHEN cm.cam_tipo = 'INGRESO' THEN cm.cam_monto ELSE 0 END), 0) AS ingresos,
    COALESCE(SUM(CASE WHEN cm.cam_tipo = 'EGRESO' THEN cm.cam_monto ELSE 0 END), 0) AS egresos,
    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) AS saldo_calculado
  FROM caja c
  INNER JOIN sucursales s ON s.suc_id = c.suc_id
  LEFT JOIN caja_movimientos cm ON cm.caj_id = c.caj_id
  WHERE c.caj_id = p_caj_id
  GROUP BY c.caj_id;

  SELECT m.mpa_nombre, COALESCE(SUM(vp.vpa_monto), 0) AS total
  FROM venta_pagos vp
  INNER JOIN metodos_pago m ON m.mpa_id = vp.mpa_id
  INNER JOIN ventas v ON v.ven_id = vp.ven_id
  INNER JOIN caja_movimientos cm ON cm.ven_id = v.ven_id AND cm.mpa_id = vp.mpa_id
  WHERE cm.caj_id = p_caj_id
  GROUP BY m.mpa_id, m.mpa_nombre
  ORDER BY m.mpa_nombre;

  SELECT
    v.ven_id,
    v.ven_fecha,
    ti.tip_nombre,
    COALESCE(s.ser_nombre, p.pro_nombre) AS item,
    GROUP_CONCAT(DISTINCT NULLIF(TRIM(CONCAT_WS(' ', pe.per_apepat, pe.per_apemat, pe.per_nombres)), '') ORDER BY pe.per_apepat, pe.per_apemat, pe.per_nombres SEPARATOR ' / ') AS trabajador,
    CASE
      WHEN ti.tip_nombre = 'SERVICIO' THEN 1
      ELSE COALESCE(SUM(vd.vde_cantidad), 0)
    END AS vde_cantidad,
    COALESCE(SUM(vd.vde_total), 0) AS vde_total
  FROM caja_movimientos cm
  INNER JOIN ventas v ON v.ven_id = cm.ven_id
  INNER JOIN venta_detalle vd ON vd.ven_id = v.ven_id
  INNER JOIN tipo_item ti ON ti.tip_id = vd.tip_id
  LEFT JOIN servicios s ON s.ser_id = vd.ser_id
  LEFT JOIN productos p ON p.pro_id = vd.pro_id
  LEFT JOIN trabajadores t ON t.tra_id = vd.tra_id
  LEFT JOIN personas pe ON pe.per_id = t.per_id
  WHERE cm.caj_id = p_caj_id
  GROUP BY v.ven_id, v.ven_fecha, ti.tip_nombre, COALESCE(vd.ser_id, 0), COALESCE(vd.pro_id, 0), item
  ORDER BY v.ven_fecha, v.ven_id;

  SELECT cam_id, cam_fecha, cam_monto, cam_observacion
  FROM caja_movimientos
  WHERE caj_id = p_caj_id
    AND cam_tipo = 'EGRESO'
  ORDER BY cam_id;
END $$

DELIMITER ;
