import {
  useEffect,
  useState,
  forwardRef,
  useRef,
  useLayoutEffect,
} from "react";
import { observer } from "mobx-react-lite";
import { useGeolocationStore } from "../../stores";
import { apiStore } from "../../api/ApiStore/store";
import { useClickDetection } from "../../hooks/useClickDetection";
import { TouchableLayout } from "../TouchableLayout";
import { getMediaUrl } from "../../api/apiConfig";
import stationIcon from "../../assets/transport-icons/station.svg";

export const isMediaIdEmpty = (id) => {
  if (id == null || id === "") return true;
  const digits = id.replace(/-/g, "");
  return digits === "" || /^0+$/.test(digits);
};

const SightItem = ({
  sight,
  handlePointerDown,
  handlePointerUp,
  handleSightClick,
  localSelectedSightId,
  selectedLanguage,
  sightArticles,
  sightArticlesEn,
  sightArticlesZh,
  selectedSightId,
  onSightSelected,
  sightStationsCache,
}) => {
  const containerRef = useRef(null);
  const textRef = useRef(null);
  const [shouldAnimate, setShouldAnimate] = useState(false);
  const [isExpanded, setIsExpanded] = useState(false);

  // Получаем название для отображения
  const getSightName = () => {
    // Если есть короткое название, используем его
    if (sight.short_name) {
      return sight.short_name;
    }

    if (!sight.left_article) {
      return sight.name;
    }

    const leftArticleData =
      selectedLanguage === "ru"
        ? sightArticles.get(sight.left_article + "_ru")
        : selectedLanguage === "en"
          ? sightArticlesEn.get(sight.left_article + "_en")
          : sightArticlesZh.get(sight.left_article + "_zh");

    return leftArticleData?.heading || sight.name;
  };

  const sightName = getSightName();

  useLayoutEffect(() => {
    const checkWidth = () => {
      if (containerRef.current && textRef.current) {
        const containerWidth = containerRef.current.offsetWidth;
        const textWidth = textRef.current.scrollWidth;
        const shouldAnimateValue = textWidth > containerWidth;
        setShouldAnimate(shouldAnimateValue);

        // Устанавливаем CSS переменную для анимации
        if (shouldAnimateValue && containerRef.current) {
          containerRef.current.style.setProperty(
            "--container-width",
            `${containerWidth}px`,
          );
        }
      }
    };

    checkWidth();
    window.addEventListener("resize", checkWidth);
    return () => window.removeEventListener("resize", checkWidth);
  }, [sightName]);

  const handleClick = (e) => {
    const newExpanded = !isExpanded;
    setIsExpanded(newExpanded);

    // Всегда открываем виджет при клике на достопримечательность
    handleSightClick(sight.id);
  };

  const cacheKey = `${sight.id}_${selectedLanguage}`;
  const stations = sightStationsCache.get(cacheKey) || [];

  return (
    <div>
      <div
        ref={containerRef}
        id={`sight-${sight.id}`}
        onPointerDown={(e) => handlePointerDown(e, sight.id)}
        onPointerUp={(e) => handlePointerUp(e, sight.id, handleClick)}
        className={`side-menu-sight pointer ${
          localSelectedSightId === sight.id ? "selected" : ""
        }`}
      >
        <span ref={textRef} className={shouldAnimate ? "marquee-text" : ""}>
          {sightName}
        </span>
      </div>
      <div
        className={`side-menu-sight-transfer-list ${isExpanded ? "open" : ""}`}
      >
        {stations.length > 0 ? (
          stations.map((station, index) => {
            const iconSrc = isMediaIdEmpty(station.icon)
              ? stationIcon
              : getMediaUrl(station.icon);

            return (
              <div
                key={station.id}
                className="side-menu-sight-transfer"
                style={{
                  borderBottom:
                    index < stations.length - 1
                      ? "1px solid rgba(255, 255, 255, 0.2)"
                      : "none",
                  paddingBottom: index < stations.length - 1 ? "8px" : "6px",
                  marginBottom: index < stations.length - 1 ? "4px" : "0",
                }}
              >
                <img
                  src={iconSrc}
                  alt=""
                  style={{
                    width: "18px",
                    height: "18px",
                    marginRight: "5px",
                    verticalAlign: "middle",
                    flexShrink: 0,
                  }}
                />
                {station.name}
              </div>
            );
          })
        ) : (
          <div className="side-menu-sight-transfer-empty">
            {selectedLanguage === "ru"
              ? "Нет остановок"
              : selectedLanguage === "zh"
                ? "没有站"
                : "No stations"}
          </div>
        )}
      </div>
    </div>
  );
};

const SightsList = observer(
  forwardRef(
    (
      {
        style,
        className,
        onCloseSights,
        setWeatherVisible,
        setLocalSelectedSightId,
        localSelectedSightId,
        onSightTopChange,
        onSightSelected,
      },
      ref,
    ) => {
      const containerRef = useRef(null);
      const store = useGeolocationStore();
      const {
        sortingBy,
        contextData,
        isLoading: isGeolocationLoading,
        selectedLanguage,
        isLeftWidgetOpen,
        setIsLeftWidgetOpen,
      } = store;

      useLayoutEffect(() => {
        if (containerRef.current) {
          if (className === "slide-in") {
            // Применяем стили для slide-in
            requestAnimationFrame(() => {
              if (containerRef.current) {
                containerRef.current.style.transform = "translateY(0)";
                containerRef.current.style.opacity = "1";
              }
            });
          } else if (className === "slide-out") {
            // Очищаем inline стили, чтобы CSS transition работал
            containerRef.current.style.transform = "";
            // Принудительно применяем reflow для запуска transition
            void containerRef.current.offsetHeight;
          }
        }
      }, [className]);
      const {
        routeSights,
        routeSightsEn,
        routeSightsZh,
        sightArticles,
        sightArticlesEn,
        sightArticlesZh,
        sightStationsCache,
      } = apiStore;
      const [sightList, setSightList] = useState([]);
      const [error, setError] = useState(null);
      const [isSightListLoading, setIsSightListLoading] = useState(true);

      const { handlePointerDown, handlePointerUp, handleScroll } =
        useClickDetection();

      useEffect(() => {
        async function fetchSightList() {
          setIsSightListLoading(true);
          setError(null);
          try {
            const sights =
              selectedLanguage === "ru"
                ? routeSights
                : selectedLanguage === "en"
                  ? routeSightsEn
                  : routeSightsZh;
            // Функция для получения названия для сортировки
            const getSightNameForSort = (sight) => {
              if (sight.short_name) {
                return sight.short_name.trim();
              }

              if (!sight.left_article) {
                return sight.name.trim();
              }

              const leftArticleData =
                selectedLanguage === "ru"
                  ? sightArticles.get(sight.left_article + "_ru")
                  : selectedLanguage === "en"
                    ? sightArticlesEn.get(sight.left_article + "_en")
                    : sightArticlesZh.get(sight.left_article + "_zh");

              return (leftArticleData?.heading || sight.name).trim();
            };

            const sortedSights = [...(sights || [])].sort((a, b) => {
              const nameA = getSightNameForSort(a);
              const nameB = getSightNameForSort(b);

              if (sortingBy === "asc") {
                return nameA.localeCompare(
                  nameB,
                  selectedLanguage === "ru"
                    ? "ru"
                    : selectedLanguage === "zh"
                      ? "zh"
                      : "en",
                  {
                    sensitivity: "base",
                  },
                );
              } else {
                return nameB.localeCompare(
                  nameA,
                  selectedLanguage === "ru"
                    ? "ru"
                    : selectedLanguage === "zh"
                      ? "zh"
                      : "en",
                  {
                    sensitivity: "base",
                  },
                );
              }
            });
            setSightList(sortedSights);
          } catch (err) {
            setError(
              "Не удалось получить достопримечательности. Пожалуйста, попробуйте позже.",
            );
            setSightList([]);
            setIsLeftWidgetOpen(false);
          } finally {
            setIsSightListLoading(false);
          }
        }

        fetchSightList();
      }, [
        contextData?.routeId,
        isGeolocationLoading,
        selectedLanguage,
        sortingBy,
        setIsLeftWidgetOpen,
        setLocalSelectedSightId,
        sightArticles,
        sightArticlesEn,
        sightArticlesZh,
        routeSights,
        routeSightsEn,
        routeSightsZh,
      ]);

      const measureSelectedSight = () => {
        if (localSelectedSightId && onSightTopChange) {
          const element = document.getElementById(
            `sight-${localSelectedSightId}`,
          );
          if (element && containerRef.current) {
            const elementRect = element.getBoundingClientRect();
            const containerRect = containerRef.current.getBoundingClientRect();

            // Используем позицию элемента относительно viewport (elementRect.top)
            // чтобы верхняя граница виджета совпадала с верхней границей элемента
            const elementTop = elementRect.top;
            onSightTopChange(elementTop);
          } else {
            console.warn(
              "[SightsList] Element or container not found:",
              `sight-${localSelectedSightId}`,
              { element: !!element, container: !!containerRef.current },
            );
          }
        }
      };

      useEffect(() => {
        if (!localSelectedSightId) return;

        // Run measurement after render/update
        // Используем requestAnimationFrame для точности измерения после рендеринга
        const timer = setTimeout(() => {
          requestAnimationFrame(() => {
            requestAnimationFrame(measureSelectedSight);
          });
        }, 0);

        return () => clearTimeout(timer);
      }, [localSelectedSightId, sightList, className]);

      const handleSightClick = (sightId) => {
        // Открываем левый виджет
        if (isLeftWidgetOpen && localSelectedSightId !== sightId) {
          setLocalSelectedSightId(sightId);
          setIsLeftWidgetOpen(true);
          if (onSightSelected) {
            onSightSelected(sightId);
          }
        } else if (!isLeftWidgetOpen) {
          setLocalSelectedSightId(sightId);
          setIsLeftWidgetOpen(true);
          if (onSightSelected) {
            onSightSelected(sightId);
          }
        } else {
          // Если виджет уже открыт для этой достопримечательности, просто обновляем список остановок
          if (onSightSelected) {
            onSightSelected(sightId);
          }
        }
      };

      const handleClose = () => {
        setIsLeftWidgetOpen(false);
        setWeatherVisible(true);
        onCloseSights();
      };

      return (
        <div
          ref={containerRef}
          style={style}
          className={`side-menu-sights ${className || ""}`}
        >
          <div
            className="side-menu-sights-title"
            onPointerUp={() => {
              handleClose();
            }}
          >
            <p>
              {" "}
              {selectedLanguage === "ru"
                ? "Достопримечательности"
                : selectedLanguage === "zh"
                  ? "景点"
                  : "Attractions"}
            </p>

            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="21"
              height="12"
              viewBox="0 0 21 12"
              fill="none"
              style={{
                transform: "translateY(-50%) rotate(180deg)",
                position: "absolute",
                right: "20px",
                top: "50%",
                transition: "transform 0.15s ease-in-out",
              }}
            >
              <g clipPath="url(#clip0_658_91932)">
                <path
                  d="M10.4257 3.53158C10.2908 3.71878 10.2229 3.84702 10.1248 3.9453C7.63081 6.43048 5.13303 8.91098 2.63903 11.3962C2.19286 11.8408 1.67878 12.0186 1.06565 11.8361C0.0337182 11.5281 -0.339817 10.2776 0.349713 9.45295C0.425175 9.36309 0.510069 9.28165 0.593077 9.19928C3.45496 6.35279 6.31778 3.50537 9.18060 0.659815C10.0654 -0.219125 10.854 -0.218188 11.7397 0.661687C14.6365 3.54 17.538 6.41457 20.4196 9.30786C20.6706 9.55966 20.88 9.91441 20.962 10.2561C21.1167 10.9019 20.7781 11.515 20.2131 11.8193C19.6462 12.1263 18.9387 12.0392 18.4482 11.5806C18.0709 11.2286 17.7125 10.8561 17.3474 10.491C15.1439 8.29601 12.9405 6.10193 10.7389 3.90599C10.6559 3.82362 10.5889 3.72721 10.4267 3.53158L10.4257 3.53158Z"
                  fill="white"
                />
              </g>
              <defs>
                <clipPath id="clip0_658_91932">
                  <rect
                    width="21"
                    height="12"
                    fill="white"
                    transform="translate(21 12) rotate(-180)"
                  />
                </clipPath>
              </defs>
            </svg>
          </div>
          <TouchableLayout className="side-menu-sights-block" ref={ref}>
            {isSightListLoading ? (
              <div>
                {selectedLanguage === "ru"
                  ? "Загрузка..."
                  : selectedLanguage === "zh"
                    ? "正在加载..."
                    : "Loading..."}
              </div>
            ) : error ? (
              <div className="error-message">{error}</div>
            ) : sightList.length === 0 ? (
              <div style={{ paddingLeft: "20px" }}>
                {selectedLanguage === "ru"
                  ? "Ничего не найдено"
                  : selectedLanguage === "zh"
                    ? "没有找到"
                    : "Nothing found"}
              </div>
            ) : (
              sightList.map((sight) => (
                <SightItem
                  key={sight.id}
                  sight={sight}
                  handlePointerDown={handlePointerDown}
                  handlePointerUp={handlePointerUp}
                  handleSightClick={handleSightClick}
                  localSelectedSightId={localSelectedSightId}
                  selectedLanguage={selectedLanguage}
                  sightArticles={sightArticles}
                  sightArticlesEn={sightArticlesEn}
                  sightArticlesZh={sightArticlesZh}
                  selectedSightId={localSelectedSightId}
                  onSightSelected={onSightSelected}
                  sightStationsCache={sightStationsCache}
                />
              ))
            )}
          </TouchableLayout>
        </div>
      );
    },
  ),
);

export default SightsList;
