import { useRef, useEffect, useState } from "react";
import { Widgets } from "./Widgets";
import { extend } from "@pixi/react";
import {
  Container,
  Graphics,
  Sprite,
  Texture,
  TilingSprite,
  Text,
} from "pixi.js";
import { Box, Stack } from "@mui/material";
import { MapDataProvider, useMapData } from "./MapDataContext";
import { TransformProvider, useTransform } from "./TransformContext";

import { LeftSidebar } from "./LeftSidebar";
import { RightSidebar } from "./RightSidebar";

import { coordinatesToLocal } from "./utils";
import { observer } from "mobx-react-lite";
import { UP_SCALE } from "./Constants";
import { WebGLRouteMapPrototype } from "./webgl-prototype/WebGLRouteMapPrototype";
import { CircularProgress } from "@mui/material";

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

const Loading = () => {
  const { isRouteLoading, isStationLoading, isSightLoading } = useMapData();

  if (isRouteLoading || isStationLoading || isSightLoading) {
    return (
      <div className="fixed flex z-1000000000 items-center justify-center h-screen w-screen bg-[#111]">
        <CircularProgress />
      </div>
    );
  }

  return null;
};
export const RoutePreview = () => {
  const [isLeftSidebarOpen, setIsLeftSidebarOpen] = useState(true);
  return (
    <MapDataProvider>
      <TransformProvider>
        <Stack direction="row" height="100vh" width="100vw" overflow="hidden">
          <Loading />
          <Box
            sx={{
              position: "relative",
              width: isLeftSidebarOpen ? 300 : 0,
              transition: "width 0.3s ease",
              overflow: "visible",
              height: "100%",
              bgcolor: "primary.main",
              borderRight: isLeftSidebarOpen
                ? "1px solid rgba(255,255,255,0.08)"
                : "none",
              display: "flex",
              justifyContent: "flex-start",
              flexShrink: 0,
            }}
          >
            <LeftSidebar
              open={isLeftSidebarOpen}
              onToggle={() => setIsLeftSidebarOpen((prev) => !prev)}
            />
          </Box>
          <Stack direction="row" flex={1} position="relative" height="100%">
            <RouteMap />
            <Widgets />
            <RightSidebar />
          </Stack>
        </Stack>
      </TransformProvider>
    </MapDataProvider>
  );
};

export const RouteMap = observer(() => {
  const { setPosition, setTransform, screenCenter } = useTransform();
  const { routeData, stationData, sightData, originalRouteData } = useMapData();

  const [points, setPoints] = useState<{ x: number; y: number }[]>([]);
  const [isSetup, setIsSetup] = useState(false);

  const parentRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = "auto";
    };
  }, []);

  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) {
    return null;
  }

  return (
    <div style={{ width: "100%", height: "100%" }} ref={parentRef}>
      {/* <Application resizeTo={parentRef} background="#000" preference="webgl">
        <InfiniteCanvas>
          <TravelPath points={points} />
          {stationData[language].map((obj, index) => (
            <Station
              station={obj}
              key={obj.id}
              ruLabel={
                language === "ru"
                  ? stationData.ru[index].name
                  : stationData.ru[index].name
              }
            />
          ))}
          {originalSightData?.map((sight: SightData, index: number) => {
            return <Sight sight={sight} id={index} key={sight.id} />;
          })}
        </InfiniteCanvas>
      </Application> */}
      <WebGLRouteMapPrototype />
    </div>
  );
});
