import React, { useState, useEffect } from "react";
import {
  getDeliveryAccessories,
  getDeliveryOrderDetails,
  updateDeliveryOrderRoute,
  getTotalOrder,
  getDeliveryOrder,
} from "../api.jsx";
import { useParams, useNavigate } from "react-router-dom";
import {
  MapContainer,
  TileLayer,
  Marker,
  Popup,
  Polyline,
} from "react-leaflet";
import { DivIcon } from "leaflet";
import polyline from "@mapbox/polyline";
import { getCoordinates } from "../geocoder.jsx";
import "./DeliveryOrderDetails.css";

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

const DeliveryOrderDetails = () => {
  const { id: deliveryOrderId } = useParams();
  const [deliveryAccessories, setDeliveryAccessories] = useState([]);
  const [loading, setLoading] = useState(true);
  const [coordinates, setCoordinates] = useState([]);
  const [route, setRoute] = useState([]);
  const [totalCost, setTotalCost] = useState(0);
  const [truckCount, setTruckCount] = useState(0);
  const [totalWeight, setTotalWeight] = useState(0);
  const [truckName, setTruckName] = useState("");
  const [truckCapacity, setTruckCapacity] = useState("");
  const [totalOrder, setTotalOrder] = useState(null);
  const [deliveryOrder, setDeliveryOrder] = useState(null);
  const [orderDuration, setOrderDuration] = useState(null);
  const navigate = useNavigate();

  useEffect(() => {
    fetchDeliveryOrder();
    fetchDeliveryAccessories();
  }, [deliveryOrderId]);

  const formatDuration = (minutes) => {
    const days = Math.floor(minutes / (24 * 60));
    const hours = Math.floor((minutes % (24 * 60)) / 60);
    const remainingMinutes = Math.floor(minutes % 60);

    return {
      days,
      hours,
      minutes: remainingMinutes,
    };
  };

  const fetchDeliveryOrder = async () => {
    try {
      const order = await getDeliveryOrder(deliveryOrderId);
      setDeliveryOrder(order);
      if (order) {
        fetchTotalOrder(order.total_order_id);
      }
    } catch (error) {
      console.error("Ошибка при загрузке deliveryOrder:", error);
    }
  };

  const fetchTotalOrder = async (orderId) => {
    try {
      const order = await getTotalOrder(orderId);
      setTotalOrder(order);
    } catch (error) {
      if (error.response && error.response.status === 401) {
        navigate("/login");
      }
      console.error("Ошибка при загрузке totalOrder:", error);
    }
  };

  const fetchDeliveryAccessories = async () => {
    try {
      const deliveryOrderDetails = await getDeliveryOrderDetails(
        deliveryOrderId
      );
      setTotalCost(Math.round(deliveryOrderDetails.price));
      setTruckCount(deliveryOrderDetails.count_trucks);
      setTruckName(deliveryOrderDetails.truck_name);
      setTruckCapacity(deliveryOrderDetails.truck_capacity);

      const accessories = await getDeliveryAccessories(deliveryOrderId);
      setDeliveryAccessories(accessories);

      const totalWeightCalculated = accessories.reduce((acc, accessory) => {
        return (
          acc + Math.round((accessory.accessory_weight * accessory.count) / 100)
        );
      }, 0);
      setTotalWeight(totalWeightCalculated);

      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,
            };
          }
        })
      );
      setCoordinates(coords);

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

      if (
        !deliveryOrderDetails.route ||
        deliveryOrderDetails.estimated_route_time_in_minutes === null
      ) {
        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);
            setRoute(decodedRoute);
            const duration = data.routes[0].duration;
            setOrderDuration(duration);

            await updateDeliveryOrderRoute(
              deliveryOrderId,
              duration / 60,
              decodedRoute
            );
          }
        }
      } else {
        const decodedRoute = deliveryOrderDetails.route;
        setOrderDuration(deliveryOrderDetails.estimated_route_time_in_minutes);
        setRoute(decodedRoute);
      }
    } catch (error) {
      if (error.response && error.response.status === 401) {
        navigate("/login");
      }
      console.error("Ошибка при загрузке доставок:", error);
    } finally {
      setLoading(false);
    }
  };

  const handleBack = () => {
    navigate("/");
  };

  return (
    <div className="delivery-order-details">
      {loading ? (
        <div className="spinner-border" role="status">
          <span className="visually-hidden"></span>
        </div>
      ) : (
        <div className="content-container">
          <button onClick={handleBack} className="btn btn-secondary mb-4">
            Назад
          </button>

          <h2 style={{ textAlign: "center" }}>Общая информация</h2>
          <table className="table table-bordered mb-5">
            <thead>
              <tr>
                <th scope="col">Общая стоимость</th>
                <th scope="col">Тип транспортного средства</th>
                <th scope="col">Количество транспортных средств</th>
                <th scope="col">Прогнозируемое время этапа</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>{totalCost} ₽</td>
                <td>
                  {truckName}
                  <br />
                  Грузоподъемность: {truckCapacity}кг
                </td>
                <td>{truckCount}</td>
                <td>
                  {deliveryOrder?.estimated_route_time_in_minutes && (
                    <>
                      {(() => {
                        const { days, hours, minutes } = formatDuration(
                          deliveryOrder?.estimated_route_time_in_minutes
                        );
                        return days > 0
                          ? `${days} дн. ${hours} ч.`
                          : `${hours} ч.`;
                      })()}
                    </>
                  )}
                </td>
              </tr>
            </tbody>
          </table>

          <h2 style={{ textAlign: "center" }}>Маршрут</h2>

          <table className="table table-bordered table-striped mb-5">
            <thead>
              <tr>
                <th scope="col">Город</th>
                <th scope="col">Комплектующие</th>
                <th scope="col">Объем, шт.</th>
                <th scope="col">Вес, кг</th>
              </tr>
            </thead>
            <tbody>
              {deliveryAccessories.map((accessory) => (
                <tr key={accessory.id}>
                  <td>{accessory.city_name}</td>
                  <td>{accessory.accessory_name}</td>
                  <td>
                    {Math.round(
                      (accessory.accessory_volume * accessory.count) / 100
                    )}
                  </td>
                  <td>
                    {Math.round(
                      (accessory.accessory_weight * accessory.count) / 100
                    )}
                  </td>
                </tr>
              ))}
              <tr>
                <td>{DELIVERY_CITY.name}</td>
                <td>Конечный пункт</td>
                <td>Итого:</td>
                <td>{totalWeight}</td>
              </tr>
            </tbody>
          </table>

          <h2 style={{ textAlign: "center" }}>Схема маршрута</h2>

          {coordinates.length > 0 && (
            <div className="map-container">
              <MapContainer
                center={[coordinates[0].latitude, coordinates[0].longitude]}
                zoom={5}
                style={{ height: "400px", width: "100%" }}
              >
                <TileLayer
                  url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                  attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                />
                {coordinates.map((coord, index) => (
                  <Marker
                    key={index}
                    position={[coord.latitude, coord.longitude]}
                    icon={
                      new DivIcon({
                        className: "custom-marker",
                        html: `<div class='marker-number'>${index + 1}</div>`,
                        iconSize: [30, 30],
                      })
                    }
                  >
                    <Popup>
                      {coord.city}
                      <br />
                      {coord.accessory_name}
                    </Popup>
                  </Marker>
                ))}
                <Marker
                  position={[DELIVERY_CITY.latitude, DELIVERY_CITY.longitude]}
                  icon={
                    new DivIcon({
                      className: "custom-marker",
                      html: `<div class='marker-number'>${
                        deliveryAccessories.length + 1
                      }</div>`,
                      iconSize: [30, 30],
                    })
                  }
                >
                  <Popup>
                    {DELIVERY_CITY.name}
                    <br />
                    Конечный пункт
                  </Popup>
                </Marker>
                {route.length > 0 && (
                  <Polyline positions={route} color="blue" />
                )}
              </MapContainer>
            </div>
          )}
        </div>
      )}
    </div>
  );
};

export default DeliveryOrderDetails;
