import { FederatedMouseEvent, Graphics } from "pixi.js";
import {
  BACKGROUND_COLOR,
  PATH_COLOR,
  STATION_RADIUS,
  STATION_OUTLINE_WIDTH,
  UP_SCALE,
} from "./Constants";
import { useTransform } from "./TransformContext";
import { useCallback, useEffect, useRef, useState } from "react";
import { StationData } from "./types";
import { useMapData } from "./MapDataContext";
import { coordinatesToLocal } from "./utils";
import { observer } from "mobx-react-lite";
import { languageStore } from "@stores";

interface StationProps {
  station: StationData;
  ruLabel: string | null;
}

export const Station = observer(
  ({ station, ruLabel }: Readonly<StationProps>) => {
    const draw = useCallback((g: Graphics) => {
      g.clear();
      const coordinates = coordinatesToLocal(
        station.latitude,
        station.longitude
      );
      g.circle(
        coordinates.x * UP_SCALE,
        coordinates.y * UP_SCALE,
        STATION_RADIUS
      );
      g.fill({ color: PATH_COLOR });
      g.stroke({ color: BACKGROUND_COLOR, width: STATION_OUTLINE_WIDTH });
    }, []);

    return (
      <pixiContainer>
        <pixiGraphics draw={draw} />
        <StationLabel station={station} ruLabel={ruLabel} />
      </pixiContainer>
    );
  }
);

export const StationLabel = observer(
  ({ station, ruLabel }: Readonly<StationProps>) => {
    const { language } = languageStore;
    const { rotation, scale } = useTransform();
    const { setStationOffset } = useMapData();

    const [position, setPosition] = useState({
      x: station.offset_x,
      y: station.offset_y,
    });
    const [isDragging, setIsDragging] = useState(false);
    const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
    const [startMousePosition, setStartMousePosition] = useState({
      x: 0,
      y: 0,
    });

    if (!station) {
      console.error("station is null");
      return null;
    }

    const handlePointerDown = (e: FederatedMouseEvent) => {
      setIsDragging(true);
      setStartPosition({
        x: position.x,
        y: position.y,
      });
      setStartMousePosition({
        x: e.globalX,
        y: e.globalY,
      });

      e.stopPropagation();
    };
    const handlePointerMove = (e: FederatedMouseEvent) => {
      if (!isDragging) return;
      const dx = e.globalX - startMousePosition.x;
      const dy = e.globalY - startMousePosition.y;
      const newPosition = {
        x: startPosition.x + dx,
        y: startPosition.y + dy,
      };
      setPosition(newPosition);
      setStationOffset(station.id, newPosition.x, newPosition.y);
      e.stopPropagation();
    };

    const handlePointerUp = (e: FederatedMouseEvent) => {
      setIsDragging(false);
      e.stopPropagation();
    };
    const coordinates = coordinatesToLocal(station.latitude, station.longitude);

    return (
      <pixiContainer
        eventMode="static"
        interactive
        onPointerDown={handlePointerDown}
        onGlobalPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
        onPointerUpOutside={handlePointerUp}
        width={48}
        height={48}
        x={coordinates.x * UP_SCALE}
        y={coordinates.y * UP_SCALE}
        rotation={-rotation}
      >
        <pixiText
          anchor={{ x: 0.5, y: 0.5 }}
          text={station.name}
          position={{
            x: position.x / scale,
            y: position.y / scale,
          }}
          style={{
            fontSize: 26,
            fontWeight: "bold",
            fill: "#ffffff",
          }}
        />

        {ruLabel && (
          <pixiText
            anchor={{ x: 0.5, y: -1 }}
            text={ruLabel}
            position={{
              x: position.x / scale,
              y: position.y / scale,
            }}
            style={{
              fontSize: 16,
              fontWeight: "bold",
              fill: "#CCCCCC",
            }}
          />
        )}
      </pixiContainer>
    );
  }
);
