import { useEffect, useState, useRef, useLayoutEffect } from "react";
import { observer } from "mobx-react-lite";
import ContentAPI from "../../api/content/content.api";
import { useGeolocationStore } from "../../stores";
import "../../styles/LeftWidget.css";
import { apiStore } from "../../api/ApiStore/store";
import { apiBaseURL } from "../../api/apiConfig";

const LeftWidget = observer(
  ({ selectedSightId, onClose, isVisible, sightTop }) => {
    const [selectedSightData, setSelectedSightData] = useState(null);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(null);
    const [shouldAnimateIn, setShouldAnimateIn] = useState(false);
    const [isImageLoaded, setIsImageLoaded] = useState(false);
    const [widgetHeight, setWidgetHeight] = useState(0);

    const textRef = useRef(null);
    const activeTouch = useRef(null);
    const widgetRef = useRef(null);

    const store = useGeolocationStore();
    const { selectedLanguage, isLeftWidgetOpen } = store;
    const {
      sightArticles,
      sightArticlesEn,
      sightArticlesZh,
      routeSights,
      routeSightsEn,
      routeSightsZh,
    } = apiStore;

    useLayoutEffect(() => {
      if (widgetRef.current) {
        setWidgetHeight(widgetRef.current.getBoundingClientRect().height);
      }
    }, [selectedSightData, isImageLoaded, isVisible, isLoading, error]);

    useEffect(() => {
      const scrollContainer = textRef.current;
      if (!scrollContainer) return;

      const handleTouchStart = (e) => {
        e.stopPropagation();
        if (e.touches.length === 1) {
          activeTouch.current = {
            identifier: e.touches[0].identifier,
            lastY: e.touches[0].clientY,
          };
        }
      };

      const handleTouchMove = (e) => {
        e.preventDefault();
        if (activeTouch.current) {
          for (const touch of e.changedTouches) {
            if (touch.identifier === activeTouch.current.identifier) {
              const deltaY = touch.clientY - activeTouch.current.lastY;
              scrollContainer.scrollTop -= deltaY;
              activeTouch.current.lastY = touch.clientY;
              break;
            }
          }
        }
      };

      const handleTouchEnd = (e) => {
        for (const touch of e.changedTouches) {
          if (
            activeTouch.current &&
            touch.identifier === activeTouch.current.identifier
          ) {
            activeTouch.current = null;
            break;
          }
        }
      };

      scrollContainer.addEventListener("touchstart", handleTouchStart, {
        passive: true,
      });
      scrollContainer.addEventListener("touchmove", handleTouchMove, {
        passive: false,
      });
      scrollContainer.addEventListener("touchend", handleTouchEnd, {
        passive: true,
      });
      scrollContainer.addEventListener("touchcancel", handleTouchEnd, {
        passive: true,
      });

      return () => {
        scrollContainer.removeEventListener("touchstart", handleTouchStart);
        scrollContainer.removeEventListener("touchmove", handleTouchMove);
        scrollContainer.removeEventListener("touchend", handleTouchEnd);
        scrollContainer.removeEventListener("touchcancel", handleTouchEnd);
      };
    }, [selectedSightData]);

    useEffect(() => {
      if (!selectedSightId) {
        setSelectedSightData(null);
        setError(null);
        setIsLoading(false);
        setShouldAnimateIn(false);
        setIsImageLoaded(false);
        return;
      }

      async function fetchData() {
        if (!isLeftWidgetOpen) {
          setIsLoading(true);
          setError(null);
          setIsImageLoaded(false);
          setShouldAnimateIn(false);
        }

        try {
          const sight =
            selectedLanguage === "ru"
              ? routeSights.find((sight) => sight.id === selectedSightId)
              : selectedLanguage === "en"
                ? routeSightsEn.find((sight) => sight.id === selectedSightId)
                : routeSightsZh.find((sight) => sight.id === selectedSightId);

          if (!sight) return;

          const leftArticle = sight.left_article;

          const leftArticleData =
            selectedLanguage === "ru"
              ? sightArticles.get(leftArticle + "_" + selectedLanguage)
              : selectedLanguage === "en"
                ? sightArticlesEn.get(leftArticle + "_" + selectedLanguage)
                : sightArticlesZh.get(leftArticle + "_" + selectedLanguage);

          if (!leftArticleData?.media?.length) return;

          const media = await ContentAPI.getMediaPreview(
            leftArticleData.media[0].id,
            selectedLanguage,
          );

          const response = {
            mediaPath: media.path,
            mediaType: media.type,
            title: leftArticleData.heading,
            text: leftArticleData.body,
            address: sight.address,
          };

          setSelectedSightData(response);
        } catch (err) {
          console.error("Ошибка отображения левого виджета:", err);
          setError("Не удалось загрузить информацию о достопримечательности.");
          setSelectedSightData(null);
          setShouldAnimateIn(false);
        } finally {
          if (!isLeftWidgetOpen) {
            setIsLoading(false);
          }
        }
      }

      if (isLeftWidgetOpen && isVisible) {
        fetchData();
      } else if (!isLeftWidgetOpen) {
        setShouldAnimateIn(false);
      }
    }, [selectedSightId, isLeftWidgetOpen, selectedLanguage, isVisible]);

    const handleImageLoad = () => {
      setIsImageLoaded(true);
      if (isVisible) {
        setTimeout(() => {
          setShouldAnimateIn(true);
        }, 50);
      }
    };

    const handleImageError = () => {
      setIsImageLoaded(false);
      console.error(
        "Ошибка загрузки изображения для достопримечательности:",
        selectedSightId,
      );
      if (isVisible) {
        setTimeout(() => {
          setShouldAnimateIn(true);
        }, 50);
      }
    };

    const getTopPosition = () => {
      if (!sightTop) return "500px";
      if (!widgetHeight) return `${sightTop}px`;

      const windowHeight = window.innerHeight;
      const margin = 90;
      const maxBottom = windowHeight - margin;

      const projectedBottom = sightTop + widgetHeight;

      if (projectedBottom > maxBottom) {
        return `${maxBottom - widgetHeight}px`;
      }
      return `${sightTop}px`;
    };

    const widgetTransformStyle = {
      top: getTopPosition(),
    };

    return (
      <div ref={widgetRef} style={widgetTransformStyle} className="left-widget">
        {isLoading ? (
          <div>Загрузка информации...</div>
        ) : error ? (
          <div className="error-message">{error}</div>
        ) : selectedSightData ? (
          <>
            {selectedSightData.mediaType == 1 ||
            selectedSightData.mediaType == 3 ? (
              <img
                key={selectedSightId}
                className="left-widget-image"
                src={`${selectedSightData.mediaPath}`}
                alt="Sight image"
                onLoad={handleImageLoad}
                onError={handleImageError}
                style={{ display: isImageLoaded ? "block" : "none" }}
              />
            ) : (
              <></>
            )}
            <div className="left-widget-content">
              <div className="left-widget-title">{selectedSightData.title}</div>
              <div className="left-widget-address">
                {selectedSightData.address}
              </div>
              <div ref={textRef} className="left-widget-text">
                {selectedSightData.text}
              </div>
            </div>
          </>
        ) : (isVisible || selectedSightData) && !isLoading ? (
          <div>
            {selectedLanguage === "ru"
              ? "Выберите достопримечательность для просмотра деталей."
              : selectedLanguage === "zh"
                ? "选择一个地标来查看详细信息。"
                : "Select a landmark to view details."}
          </div>
        ) : null}
      </div>
    );
  },
);

export default LeftWidget;
