import { Button, Stack, TextField, Typography, Slider } from "@mui/material";
import { useMapData } from "./MapDataContext";
import { useEffect, useState } from "react";
import { useTransform } from "./TransformContext";
import { SCALE_FACTOR } from "./Constants";
import { toast } from "react-toastify";

export function RightSidebar() {
  const {
    routeData,
    setScaleRange,
    saveChanges,
    originalRouteData,
    setMapRotation,
    setIconSize: updateIconSize,
    setFontSize: updateFontSize,
  } = useMapData();
  const { rotation, rotateToAngle, scale, setScaleAtCenter } = useTransform();

  const [minScale, setMinScale] = useState<number>(1);
  const [maxScale, setMaxScale] = useState<number>(5);
  const [localCenter, setLocalCenter] = useState<{ x: number; y: number }>({
    x: 0,
    y: 0,
  });
  const [rotationDegrees, setRotationDegrees] = useState<number>(0);
  const [isUserEditing, setIsUserEditing] = useState<boolean>(false);
  const [iconSize, setIconSize] = useState<number>(100);
  const [fontSize, setFontSize] = useState<number>(100);

  useEffect(() => {
    if (originalRouteData) {
      const originalMinScale = originalRouteData.scale_min ?? 1;
      const resetMinScale = originalMinScale < 1 ? 1 : originalMinScale;

      const originalMaxScale = originalRouteData.scale_max ?? 5;
      const resetMaxScale = originalMaxScale < 3 ? 3 : originalMaxScale;

      setMinScale(resetMinScale);
      setMaxScale(resetMaxScale);
      setRotationDegrees(originalRouteData.rotate ?? 0);
      setLocalCenter({
        x: originalRouteData.center_latitude ?? 0,
        y: originalRouteData.center_longitude ?? 0,
      });
      setIconSize(originalRouteData.icon_size ?? 100);
      setFontSize(originalRouteData.font_size ?? 100);
    }
  }, [originalRouteData]);

  useEffect(() => {
    if (minScale && maxScale) {
      setScaleRange(minScale, maxScale);
    }
  }, [minScale, maxScale]);

  useEffect(() => {
    setRotationDegrees(
      ((Math.round((rotation * 180) / Math.PI) % 360) + 360) % 360
    );
  }, [rotation]);

  useEffect(() => {
    setMapRotation(rotationDegrees);
  }, [rotationDegrees]);

  useEffect(() => {
    if (isUserEditing) {
      return;
    }

    const latitude = routeData?.center_latitude ?? 0;
    const longitude = routeData?.center_longitude ?? 0;

    setLocalCenter((prev) => {
      if (
        Math.abs(prev.x - latitude) < 1e-6 &&
        Math.abs(prev.y - longitude) < 1e-6
      ) {
        return prev;
      }
      return { x: latitude, y: longitude };
    });
  }, [isUserEditing, routeData?.center_latitude, routeData?.center_longitude]);

  function setRotationFromDegrees(degrees: number) {
    rotateToAngle((degrees * Math.PI) / 180);
  }

  const handleIconSizeChange = (value: number) => {
    if (!Number.isFinite(value)) {
      return;
    }
    const clamped = Math.max(50, Math.min(300, Math.round(value)));
    setIconSize(clamped);
    updateIconSize(clamped);
  };

  const handleFontSizeChange = (value: number) => {
    if (!Number.isFinite(value)) {
      return;
    }
    const clamped = Math.max(50, Math.min(300, Math.round(value)));
    setFontSize(clamped);
    updateFontSize(clamped);
  };

  useEffect(() => {
    const next = routeData?.icon_size ?? originalRouteData?.icon_size ?? 100;
    setIconSize((prev) => (Math.abs(prev - next) > 0.5 ? next : prev));
  }, [routeData?.icon_size, originalRouteData?.icon_size]);

  useEffect(() => {
    const next = routeData?.font_size ?? originalRouteData?.font_size ?? 100;
    setFontSize((prev) => (Math.abs(prev - next) > 0.5 ? next : prev));
  }, [routeData?.font_size, originalRouteData?.font_size]);

  if (!routeData) {
    return null;
  }

  return (
    <Stack
      position="absolute"
      right={8}
      top={8}
      bottom={8}
      p={2}
      gap={1}
      minWidth="400px"
      bgcolor="primary.main"
      border="1px solid #e0e0e0"
      borderRadius={2}
    >
      <Typography variant="h6" sx={{ mb: 2, color: "#fff" }} textAlign="center">
        Настройка маршрута
      </Typography>

      <Stack spacing={2} direction="row" alignItems="center">
        <TextField
          type="number"
          label="Минимальный масштаб"
          variant="filled"
          value={minScale}
          onChange={(e) => {
            let newMinScale = Number(e.target.value);

            if (newMinScale < 10) {
              newMinScale = 10;
            }

            setMinScale(newMinScale);

            if (maxScale - newMinScale < 2) {
              let newMaxScale = newMinScale + 2;

              if (newMaxScale < 3) {
                newMaxScale = 3;
                setMinScale(1);
              }
              setMaxScale(newMaxScale);
            }

            if (newMinScale > scale * SCALE_FACTOR) {
              setScaleAtCenter(newMinScale / SCALE_FACTOR);
            }
          }}
          style={{ backgroundColor: "#222", borderRadius: 4 }}
          sx={{
            "& .MuiInputLabel-root": {
              color: "#fff",
            },
            "& .MuiInputBase-input": {
              color: "#fff",
            },
          }}
          slotProps={{
            input: {
              min: 1,
              max: 10,
            },
          }}
        />
        <TextField
          type="number"
          label="Максимальный масштаб"
          variant="filled"
          value={maxScale}
          onChange={(e) => {
            let newMaxScale = Number(e.target.value);

            if (newMaxScale < 13) {
              newMaxScale = 13;
            }

            if (newMaxScale > 300) {
              newMaxScale = 300;
            }

            setMaxScale(newMaxScale);

            if (newMaxScale - minScale < 2) {
              let newMinScale = newMaxScale - 2;

              if (newMinScale < 1) {
                newMinScale = 1;
                setMaxScale(3);
              }
              setMinScale(newMinScale);
            }

            if (newMaxScale < scale * SCALE_FACTOR) {
              setScaleAtCenter(newMaxScale / SCALE_FACTOR);
            }
          }}
          style={{ backgroundColor: "#222", borderRadius: 4, color: "#fff" }}
          sx={{
            "& .MuiInputLabel-root": {
              color: "#fff",
            },
            "& .MuiInputBase-input": {
              color: "#fff",
            },
          }}
          slotProps={{
            input: {
              min: 3,
              max: 300,
            },
          }}
        />
      </Stack>

      <Typography variant="body2" sx={{ color: "#fff", textAlign: "center" }}>
        Текущий масштаб: {Math.round(scale * SCALE_FACTOR * 100) / 100}
      </Typography>

      <Slider
        value={scale * SCALE_FACTOR}
        onChange={(_, newValue) => {
          if (typeof newValue === "number") {
            setScaleAtCenter(newValue / SCALE_FACTOR);
          }
        }}
        min={minScale}
        max={maxScale}
        step={0.1}
        sx={{
          color: "#fff",
          "& .MuiSlider-thumb": {
            backgroundColor: "#fff",
          },
          "& .MuiSlider-track": {
            backgroundColor: "#fff",
          },
          "& .MuiSlider-rail": {
            backgroundColor: "#666",
          },
        }}
      />

      <TextField
        type="number"
        label="Текущий масштаб"
        variant="filled"
        value={Math.round(scale * SCALE_FACTOR * 100) / 100}
        onChange={(e) => {
          const newScale = Number(e.target.value);
          if (
            !isNaN(newScale) &&
            newScale >= minScale &&
            newScale <= maxScale
          ) {
            setScaleAtCenter(newScale / SCALE_FACTOR);
          }
        }}
        style={{ backgroundColor: "#222", borderRadius: 4 }}
        sx={{
          "& .MuiInputLabel-root": {
            color: "#fff",
          },
          "& .MuiInputBase-input": {
            color: "#fff",
          },
        }}
        inputProps={{
          min: minScale,
          max: maxScale,
        }}
      />

      <Typography variant="body2" sx={{ color: "#fff", textAlign: "center" }}>
        Размер иконок: {iconSize}%
      </Typography>

      <Slider
        value={iconSize}
        onChange={(_, value) => {
          if (typeof value === "number") {
            handleIconSizeChange(value);
          }
        }}
        min={50}
        max={300}
        step={1}
        sx={{
          color: "#fff",
          "& .MuiSlider-thumb": {
            backgroundColor: "#fff",
          },
          "& .MuiSlider-track": {
            backgroundColor: "#fff",
          },
          "& .MuiSlider-rail": {
            backgroundColor: "#666",
          },
        }}
      />

      <Typography variant="body2" sx={{ color: "#fff", textAlign: "center" }}>
        Размер шрифта: {fontSize}%
      </Typography>

      <Slider
        value={fontSize}
        onChange={(_, value) => {
          if (typeof value === "number") {
            handleFontSizeChange(value);
          }
        }}
        min={50}
        max={300}
        step={1}
        sx={{
          color: "#fff",
          "& .MuiSlider-thumb": {
            backgroundColor: "#fff",
          },
          "& .MuiSlider-track": {
            backgroundColor: "#fff",
          },
          "& .MuiSlider-rail": {
            backgroundColor: "#666",
          },
        }}
      />

      <TextField
        type="number"
        label="Поворот (в градусах)"
        variant="filled"
        value={rotationDegrees}
        onChange={(e) => {
          const value = Number(e.target.value);
          if (!isNaN(value)) {
            setRotationFromDegrees(value);
          }
        }}
        onKeyDown={(e) => {
          if (e.key === "Enter") {
            e.currentTarget.blur();
          }
        }}
        style={{ backgroundColor: "#222", borderRadius: 4 }}
        sx={{
          "& .MuiInputLabel-root": {
            color: "#fff",
          },
          "& .MuiInputBase-input": {
            color: "#fff",
          },
        }}
        slotProps={{
          input: {
            min: 0,
            max: 360,
          },
        }}
      />

      <Stack direction="row" spacing={2}>
        <TextField
          type="number"
          label="Центр карты, широта"
          variant="filled"
          value={Math.round(localCenter.x * 1000) / 1000}
          onChange={(e) => {
            setIsUserEditing(true);
            setLocalCenter((prev) => ({ ...prev, x: Number(e.target.value) }));
          }}
          onBlur={() => {
            setIsUserEditing(false);
          }}
          style={{ backgroundColor: "#222", borderRadius: 4 }}
          sx={{
            "& .MuiInputLabel-root": {
              color: "#fff",
            },
            "& .MuiInputBase-input": {
              color: "#fff",
            },
          }}
          inputProps={{
            step: 0.001,
          }}
        />
        <TextField
          type="number"
          label="Центр карты, высота"
          variant="filled"
          value={Math.round(localCenter.y * 1000) / 1000}
          onChange={(e) => {
            setIsUserEditing(true);
            setLocalCenter((prev) => ({ ...prev, y: Number(e.target.value) }));
          }}
          onBlur={() => {
            setIsUserEditing(false);
          }}
          style={{ backgroundColor: "#222", borderRadius: 4 }}
          sx={{
            "& .MuiInputLabel-root": {
              color: "#fff",
            },
            "& .MuiInputBase-input": {
              color: "#fff",
            },
          }}
          inputProps={{
            step: 0.001,
          }}
        />
      </Stack>

      <Button
        variant="contained"
        color="secondary"
        sx={{ mt: 2 }}
        onClick={async () => {
          try {
            await saveChanges();
            toast.success("Изменения сохранены");
          } catch (error) {
            console.error(error);
            toast.error("Ошибка при сохранении изменений");
          }
        }}
      >
        Сохранить изменения
      </Button>
    </Stack>
  );
}
