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

function Compass({
  degrees,
  className,
}: {
  degrees: number;
  className?: string;
}) {
  const normalized = ((degrees % 360) + 360) % 360;

  // Отслеживаем накопленный угол поворота для циклического вращения и целевую букву
  const [accumulatedDegrees, setAccumulatedDegrees] = useState(normalized);
  const [targetLetter, setTargetLetter] = useState(() => {
    // Инициализируем букву на основе начального угла
    const initial = Math.round(normalized / 90) * 90;
    const normalizedInitial = initial === 360 ? 0 : initial;
    return normalizedInitial === 0
      ? "N"
      : normalizedInitial === 90
      ? "W"
      : normalizedInitial === 180
      ? "S"
      : "E";
  });
  const prevNormalizedRef = useRef(normalized);
  const isFirstRenderRef = useRef(true);

  useEffect(() => {
    const prevNormalized = prevNormalizedRef.current;

    // Обновляем ref для следующего раза
    prevNormalizedRef.current = normalized;

    // Пропускаем первый рендер, т.к. состояние уже инициализировано
    if (isFirstRenderRef.current) {
      isFirstRenderRef.current = false;
      return;
    }

    const diff = normalized - prevNormalized;

    // Если началось движение (разница достаточно большая), определяем целевую букву сразу
    if (Math.abs(diff) > 0.5) {
      let targetAngle: number;

      // Определяем направление движения и целевой угол
      if (diff > 180) {
        // Переход назад через 0 (например, 0 -> 270 при движении против часовой)
        targetAngle = Math.floor(normalized / 90) * 90;
      } else if (diff < -180) {
        // Переход вперед через 360 (например, 270 -> 0 при движении по часовой)
        targetAngle = Math.ceil(normalized / 90) * 90;
      } else if (diff > 0) {
        // Движение по часовой (увеличение угла)
        targetAngle = Math.ceil(normalized / 90) * 90;
      } else {
        // Движение против часовой (уменьшение угла)
        targetAngle = Math.floor(normalized / 90) * 90;
      }

      const normalizedTarget = ((targetAngle % 360) + 360) % 360;
      const newLetter =
        normalizedTarget === 0
          ? "N"
          : normalizedTarget === 90
          ? "W"
          : normalizedTarget === 180
          ? "S"
          : "E";

      setTargetLetter(newLetter);
    }

    // Определяем, произошел ли циклический переход
    if (diff > 180) {
      // Переход назад через 0 (например, 0 -> 270 при движении против часовой)
      setAccumulatedDegrees(
        (prev) => prev - (360 - normalized + prevNormalized)
      );
    } else if (diff < -180) {
      // Переход вперед через 360 (например, 270 -> 0 при движении по часовой)
      setAccumulatedDegrees(
        (prev) => prev + (360 - prevNormalized + normalized)
      );
    } else {
      // Обычный поворот
      setAccumulatedDegrees((prev) => prev + diff);
    }
  }, [normalized]);

  return (
    <div
      className={clsx(
        "select-none 2xl:p-[0.556vw]a 2xl:size-[5.556vw] size-10 aspect-square",
        className
      )}
    >
      <div
        style={{ rotate: `${accumulatedDegrees}deg` }}
        className="transition-[rotate] duration-300"
      >
        <svg
          viewBox="0 0 83 83"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          className="max-2xl:hidden"
        >
          <g filter="url(#a)">
            <circle
              cx={41.359}
              cy={41.359}
              r={27}
              fill="#363636"
              fillOpacity={0.15}
            />
          </g>
          <path
            d="M49.442 11.192a31.23 31.23 0 1 1-16.166 0"
            stroke="#fff"
            strokeWidth={"0.107vw"}
            strokeLinecap="round"
            strokeLinejoin="round"
          />
          <defs>
            <filter
              id="a"
              x={0}
              y={0}
              width={"5.744vw"}
              height={"5.744vw"}
              filterUnits="userSpaceOnUse"
              colorInterpolationFilters="sRGB"
            >
              <feFlood floodOpacity={0} result="BackgroundImageFix" />
              <feBlend
                in="SourceGraphic"
                in2="BackgroundImageFix"
                result="shape"
              />
              <feGaussianBlur
                stdDeviation={7.179}
                result="effect1_foregroundBlur_490_31649"
              />
            </filter>
          </defs>
        </svg>
        <svg
          className="2xl:hidden"
          width={40}
          height={40}
          viewBox="0 0 40 40"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M14.953 1.164a19.5 19.5 0 1 1 10.094 37.672A19.5 19.5 0 0 1 14.953 1.164"
            stroke="#fff"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        </svg>
      </div>
      <div className="2xl:hidden absolute inset-0 -translate-x-[13px] -translate-y-[13px]">
        <svg
          width={63}
          height={63}
          viewBox="0 0 63 63"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <g filter="url(#a)">
            <circle
              cx={31.359}
              cy={31.359}
              r={17}
              fill="#363636"
              fillOpacity={0.15}
            />
          </g>
          <defs>
            <filter
              id="a"
              x={0}
              y={0}
              width={62.718}
              height={62.718}
              filterUnits="userSpaceOnUse"
              colorInterpolationFilters="sRGB"
            >
              <feFlood floodOpacity={0} result="BackgroundImageFix" />
              <feBlend
                in="SourceGraphic"
                in2="BackgroundImageFix"
                result="shape"
              />
              <feGaussianBlur
                stdDeviation={7.179}
                result="effect1_foregroundBlur_11187_57936"
              />
            </filter>
          </defs>
        </svg>
      </div>
      <p className="absolute font-medium 2xl:text-[0.833vw] text-[10px] leading-none text-white left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 2xl:blur-[0.142vw]">
        {targetLetter}
      </p>
      <p className="absolute font-medium 2xl:text-[0.833vw] text-[10px] leading-none text-white left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2">
        {targetLetter}
      </p>
      <div
        style={{
          transform: `translateX(-50%)`,
        }}
        className="absolute left-1/2 h-full top-0 transition-[transform] duration-300 2xl:pt-[0.139vw] pt-1.5"
      >
        <div className="flex flex-col items-center 2xl:gap-[0.208vw]">
          <p className="font-medium text-[0.833vw] opacity-0 leading-none text-white text-center transition-[rotate] duration-300 max-2xl:hidden">
            N
          </p>
          <div className="2xl:size-[0.556vw] size-1.5 relative">
            <div className="absolute inset-0">
              <svg
                viewBox="0 0 7 6"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  d="M5.666 4.974H.513L3.09.512z"
                  fill="#fff"
                  stroke="#fff"
                  strokeWidth={"0.071vw"}
                />
              </svg>
            </div>
            <div className="absolute inset-0 2xl:blur-[0.142vw] blur-[2.05px]">
              <svg
                viewBox="0 0 7 6"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  d="M5.666 4.974H.513L3.09.512z"
                  fill="#fff"
                  stroke="#fff"
                  strokeWidth={"0.071vw"}
                />
              </svg>
            </div>
            <div className="absolute inset-0 2xl:blur-[0.142vw] blur-[2.05px]">
              <svg
                viewBox="0 0 7 6"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  d="M5.666 4.974H.513L3.09.512z"
                  fill="#fff"
                  stroke="#fff"
                  strokeWidth={"0.071vw"}
                />
              </svg>
            </div>
          </div>
        </div>
      </div>
      <div
        style={{
          transform: `translateX(-50%) rotate(${accumulatedDegrees}deg)`,
        }}
        className="absolute left-1/2 h-full top-0 transition-[transform] duration-300 2xl:pt-[0.139vw] pt-1.5"
      >
        <div className="flex flex-col items-center 2xl:gap-[0.208vw]">
          <p
            style={{ rotate: `${-accumulatedDegrees}deg` }}
            className="font-medium text-[0.833vw] leading-none text-white text-center transition-[rotate] duration-300 max-2xl:hidden"
          >
            N
          </p>
        </div>
      </div>
    </div>
  );
}

export default Compass;
