import { useRef, useEffect, useState } from "react";

import { Application, ApplicationRef, extend } from "@pixi/react";
import {
  Container,
  Graphics,
  Sprite,
  Texture,
  TilingSprite,
  Text,
} from "pixi.js";
import { Stack } from "@mui/material";
import { MapDataProvider, useMapData } from "./MapDataContext";
import { TransformProvider, useTransform } from "./TransformContext";
import { InfiniteCanvas } from "./InfiniteCanvas";
import { Sight } from "./Sight";
import { UP_SCALE } from "./Constants";
import { Station } from "./Station";
import { TravelPath } from "./TravelPath";
import { LeftSidebar } from "./LeftSidebar";
import { RightSidebar } from "./RightSidebar";
import { Widgets } from "./Widgets";
import { coordinatesToLocal } from "./utils";
import { LanguageSwitch } from "@/components/LanguageSwitch";
import { languageStore } from "@stores";
import { observer } from "mobx-react-lite";

extend({
  Container,
  Graphics,
  Sprite,
  Texture,
  TilingSprite,
  Text,
});

export const RoutePreview = () => {
  return (
    <MapDataProvider>
      <TransformProvider>
        <Stack direction="row" height="100vh" width="100vw" overflow="hidden">
          <div
            style={{
              position: "absolute",
              top: 0,
              left: "50%",
              transform: "translateX(-50%)",
              zIndex: 1000,
            }}
          >
            <LanguageSwitch />
          </div>
          <LeftSidebar />
          <Stack direction="row" flex={1} position="relative" height="100%">
            <Widgets />
            <RouteMap />
            <RightSidebar />
          </Stack>
        </Stack>
      </TransformProvider>
    </MapDataProvider>
  );
};

export const RouteMap = observer(() => {
  const { language } = languageStore;
  const { setPosition, screenToLocal, setTransform, screenCenter } =
    useTransform();
  const { routeData, stationData, sightData, originalRouteData } = useMapData();
  console.log(stationData);
  const [points, setPoints] = useState<{ x: number; y: number }[]>([]);
  const [isSetup, setIsSetup] = useState(false);

  const parentRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (originalRouteData) {
      const path = originalRouteData?.path;
      const points =
        path?.map(([x, y]: [number, number]) => ({
          x: x * UP_SCALE,
          y: y * UP_SCALE,
        })) ?? [];
      setPoints(points);
    }
  }, [originalRouteData]);

  useEffect(() => {
    if (isSetup || !screenCenter) {
      return;
    }

    if (
      originalRouteData?.center_latitude ===
        originalRouteData?.center_longitude &&
      originalRouteData?.center_latitude === 0
    ) {
      if (points.length > 0) {
        let boundingBox = {
          from: { x: Infinity, y: Infinity },
          to: { x: -Infinity, y: -Infinity },
        };
        for (const point of points) {
          boundingBox.from.x = Math.min(boundingBox.from.x, point.x);
          boundingBox.from.y = Math.min(boundingBox.from.y, point.y);
          boundingBox.to.x = Math.max(boundingBox.to.x, point.x);
          boundingBox.to.y = Math.max(boundingBox.to.y, point.y);
        }
        const newCenter = {
          x: -(boundingBox.from.x + boundingBox.to.x) / 2,
          y: -(boundingBox.from.y + boundingBox.to.y) / 2,
        };
        setPosition(newCenter);
        setIsSetup(true);
      }
    } else if (
      originalRouteData?.center_latitude &&
      originalRouteData?.center_longitude
    ) {
      const coordinates = coordinatesToLocal(
        originalRouteData?.center_latitude,
        originalRouteData?.center_longitude
      );

      setTransform(
        coordinates.x,
        coordinates.y,
        originalRouteData?.rotate,
        originalRouteData?.scale_min
      );
      setIsSetup(true);
    }
  }, [
    points,
    originalRouteData?.center_latitude,
    originalRouteData?.center_longitude,
    originalRouteData?.rotate,
    isSetup,
    screenCenter,
  ]);

  if (!routeData || !stationData || !sightData) {
    console.error("routeData, stationData or sightData is null");
    return <div>Loading...</div>;
  }

  return (
    <div style={{ width: "100%", height: "100%" }} ref={parentRef}>
      <Application resizeTo={parentRef} background="#fff">
        <InfiniteCanvas>
          <TravelPath points={points} />
          {stationData[language].map((obj, index) => (
            <Station
              station={obj}
              key={obj.id}
              ruLabel={
                language === "ru"
                  ? stationData.en[index].name
                  : stationData.ru[index].name
              }
            />
          ))}

          <pixiGraphics
            draw={(g) => {
              g.clear();
              const localCenter = screenToLocal(0, 0);
              g.circle(localCenter.x, localCenter.y, 10);
              g.fill("#fff");
            }}
          />
        </InfiniteCanvas>
      </Application>
    </div>
  );
});
