import {
  getDeliveryOrders,
  updateDeliveryOrderRoute,
  getDeliveryOrderDetails,
  getDeliveryAccessories,
} from "../api.jsx";
import { getCoordinates } from "../geocoder.jsx";
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import polyline from "@mapbox/polyline";
import "./DeliveryOrdersList.css";

const DELIVERY_CITY = {
  name: "Челябинск",
  latitude: 55.159902,
  longitude: 61.402554,
};

const DeliveryOrdersList = ({
  totalOrderId,
  onSubOrderClick,
  setDeliveryOrdersCount,
  setTotalEstimatedTime,
}) => {
  const [deliveryOrders, setDeliveryOrders] = useState([]);
  const [loadingDeliveryOrders, setLoadingDeliveryOrders] = useState(true);
  const [calculatingRoutes, setCalculatingRoutes] = useState([]);
  const [hoveredOrderId, setHoveredOrderId] = useState(null);
  const navigate = useNavigate();

  useEffect(() => {
    fetchDeliveryOrders();
  }, [totalOrderId]);

  const formatPrice = (price) => {
    if (!price) {
      return "не указана";
    }
    return `${price.toFixed(2)} ₽`;
  };

  const fetchDeliveryOrders = async () => {
    try {
      const orders = await getDeliveryOrders(totalOrderId);
      setDeliveryOrdersCount(orders.length);
      setDeliveryOrders(orders);

      const totalTime = orders.reduce((sum, order) => {
        return sum + (order.estimated_route_time_in_minutes || 0);
      }, 0);
      setTotalEstimatedTime(totalTime);
    } catch (error) {
      if (error.response && error.response.status === 401) {
        navigate("/login");
      }
      console.error("Ошибка при загрузке подзаказов:", error);
    } finally {
      setLoadingDeliveryOrders(false);
    }
  };

  const formatTimeInHours = (minutes) => {
    if (!minutes || minutes === 0) {
      return "ещё не рассчитывалось";
    }
    return (minutes / 60).toFixed(2) + " час.";
  };

  const calculateRoutes = async () => {
    const ordersToCalculate = deliveryOrders.filter(
      (order) => !order.estimated_route_time_in_minutes
    );

    setCalculatingRoutes(ordersToCalculate.map((order) => order.id));

    await Promise.all(
      ordersToCalculate.map(async (order) => {
        try {
          const deliveryOrderDetails = await getDeliveryOrderDetails(order.id);
          const accessories = await getDeliveryAccessories(
            deliveryOrderDetails.id
          );

          const coords = await Promise.all(
            accessories.map(async (accessory) => {
              if (accessory.latitude && accessory.longitude) {
                return {
                  city: accessory.city_name,
                  latitude: accessory.latitude,
                  longitude: accessory.longitude,
                  accessory_name:
                    accessory.accessory_name +
                    Math.round(
                      (accessory.accessory_volume * accessory.count) / 100
                    ) +
                    "шт.",
                };
              } else {
                const coords = await getCoordinates(accessory.city_name);
                return {
                  city: accessory.city_name,
                  accessory_name:
                    accessory.accessory_name +
                    ": " +
                    Math.round(
                      (accessory.accessory_volume * accessory.count) / 100
                    ) +
                    "шт.",
                  ...coords,
                };
              }
            })
          );

          const fullCoordinates = [...coords, DELIVERY_CITY];

          if (fullCoordinates.length > 1) {
            const waypoints = fullCoordinates
              .map(({ longitude, latitude }) => `${longitude},${latitude}`)
              .join(";");

            const routeUrl = `https://router.project-osrm.org/route/v1/driving/${waypoints}?overview=full`;

            const response = await fetch(routeUrl);
            const data = await response.json();

            if (data.routes && data.routes.length > 0) {
              const geometry = data.routes[0].geometry;
              const decodedRoute = polyline.decode(geometry);
              const duration = data.routes[0].duration;

              await updateDeliveryOrderRoute(
                order.id,
                duration / 60,
                decodedRoute
              );
            }
          }
        } catch (error) {
          console.error("Ошибка при расчете маршрута для подзаказа:", error);
        }
      })
    );

    await fetchDeliveryOrders();
    setCalculatingRoutes([]);
  };

  const ordersToCalculate = deliveryOrders.filter(
    (order) => !order.estimated_route_time_in_minutes
  );

  return (
    <div>
      {loadingDeliveryOrders ? (
        <div className="spinner-border" role="status">
          <span className="visually-hidden"></span>
        </div>
      ) : (
        <>
          {ordersToCalculate.length > 0 && (
            <button onClick={calculateRoutes} className="btn btn-primary mb-3">
              Рассчитать все
            </button>
          )}
          {deliveryOrders.map((order, index) => (
            <div
              key={order.id}
              className="card mb-1"
              onClick={() => onSubOrderClick(order.id)}
              onMouseEnter={() => setHoveredOrderId(order.id)}
              onMouseLeave={() => setHoveredOrderId(null)}
            >
              <div className="card-body">
                <p>Этап №{index + 1}</p>
                <p>
                  Прогнозируемое время этапа:{" "}
                  {formatTimeInHours(order.estimated_route_time_in_minutes)}
                </p>
                <p>Стоимость: {formatPrice(order.price)}</p>
                {calculatingRoutes.includes(order.id) && (
                  <div className="spinner-border" role="status">
                    <span className="visually-hidden"></span>
                  </div>
                )}
                {hoveredOrderId === order.id && (
                  <p className="hover-info">
                    Нажмите, чтобы посмотреть подробную информацию
                  </p>
                )}
              </div>
            </div>
          ))}
        </>
      )}
    </div>
  );
};

export default DeliveryOrdersList;
