import {Box, ButtonGroup, FormControl, Grid, IconButton, MenuItem, Select, SelectChangeEvent} from "@mui/material";
import React, {useCallback, useMemo, useState} from "react";
import {ChartOneWindowIcon, ChartTwoVerticalWindowsIcon, ChartTwoHorizontalWindowsIcon, ChartForWindowsIcon} from "../icons";
import KLineChart from "./KLineChart";
import {MarketChartsProps} from "./MarketCharts.props";

interface ChartIntervalProps {
  windowChart: number;
  interval: string;
  handleIntervalChange: (event: SelectChangeEvent<string>, chart: number) => void
}

const MarketCharts = React.memo(({symbol}: MarketChartsProps) => {
  const [windowsChart, setWindowsChart] = useState<"one" | "twoVertical" | "twoHorizontal" | "for">("for");

  const [IntervalFirstChart, setIntervalFirstChart] = useState("4h");
  const [IntervalSecondChart, setIntervalSecondChart] = useState("1d");
  const [IntervalThirdtChart, setIntervalThirdChart] = useState("5m");
  const [IntervalFourthChart, setIntervalFourthChart] = useState("15m");

  const handleIntervalChange = useCallback((event: SelectChangeEvent<string>, chart: number) => {
    const value = event.target.value;

    switch (chart) {
    case 1:
      setIntervalFirstChart(value);
      break;
    case 2:
      setIntervalSecondChart(value);
      break;
    case 3:
      setIntervalThirdChart(value);
      break;
    case 4:
      setIntervalFourthChart(value);
      break;
    default:
      break;
    }
  },
  []
  );
  
  const ChartDuration: React.FC<ChartIntervalProps> = React.memo(({windowChart, interval, handleIntervalChange}) => {
    return useMemo(
      () => (
        <Box height="calc(100% - 4px)" p={.5} width="calc(100% - 4px)" borderRadius="8px" sx={{bgcolor: "#fff"}} >
          <FormControl sx={{
            mb: 1, " & .MuiSelect-select": {paddingY: 1}, "& fieldset": {border: "none"}, height: 31,
            backgroundColor: "#eeeeee", color: "#191919", padding: "0", borderRadius: "8px",
          }}>
            <Select sx={{fontSize: "12px"}} value={interval} onChange={(e) => handleIntervalChange(e, windowChart)}>
              <MenuItem value="1m">1м</MenuItem>
              <MenuItem value="5m">5м</MenuItem>
              <MenuItem value="15m">15м</MenuItem>
              <MenuItem value="1h">1ч</MenuItem>
              <MenuItem value="4h">4ч</MenuItem>
              <MenuItem value="1d">1д</MenuItem>
              <MenuItem value="1w">1н</MenuItem>
            </Select>
          </FormControl>
          <KLineChart symbol={symbol} interval={interval} />
        </Box>
      ),
      []
    );
  });

  ChartDuration.displayName = "ChartDuration";

  return (
    <Grid container height="72%" borderRadius="8px" position="relative">
      <Box position="absolute" top={4} right={8} borderRadius={1} border="1px solid #d4d4d4" height={31} >
        <ButtonGroup>
          <IconButton onClick={() => setWindowsChart("one")} sx={{m: .3, height: 23, width: 23}}><ChartOneWindowIcon sx={{fill: windowsChart === "one" ? "#B41C18" : "#d4d4d4"}} /> </IconButton>
          <IconButton onClick={() => setWindowsChart("twoVertical")} sx={{m: .3, height: 23, width: 23}}><ChartTwoVerticalWindowsIcon sx={{fill: windowsChart === "twoVertical" ? "#B41C18" : "#d4d4d4"}} /></IconButton>
          <IconButton onClick={() => setWindowsChart("twoHorizontal")} sx={{m: .3, height: 23, width: 23}}><ChartTwoHorizontalWindowsIcon sx={{fill: windowsChart === "twoHorizontal" ? "#B41C18" : "#d4d4d4"}} /></IconButton>
          <IconButton onClick={() => setWindowsChart("for")} sx={{m: .3, height: 23, width: 23}}><ChartForWindowsIcon sx={{fill: windowsChart === "for" ? "#B41C18" : "#d4d4d4"}} /></IconButton>
        </ButtonGroup>
      </Box>
      {
        windowsChart === "one" ?
          <Grid item xs={12} height={690}>
            <ChartDuration windowChart={1} interval={IntervalFirstChart} handleIntervalChange={handleIntervalChange} />
          </Grid>
          : windowsChart === "twoVertical" ?
            <>
              <Grid item xs={6} height={690}>
                <ChartDuration windowChart={1} interval={IntervalFirstChart} handleIntervalChange={handleIntervalChange} />
              </Grid><Grid item xs={6} height={690}>
                <ChartDuration windowChart={2} interval={IntervalSecondChart} handleIntervalChange={handleIntervalChange} />
              </Grid>
            </>
            : windowsChart === "twoHorizontal" ?
              <>
                <Grid item xs={12} height={345}>
                  <ChartDuration windowChart={1} interval={IntervalFirstChart} handleIntervalChange={handleIntervalChange} />
                </Grid><Grid item xs={12} height={345}>
                  <ChartDuration windowChart={2} interval={IntervalSecondChart} handleIntervalChange={handleIntervalChange} />
                </Grid>
              </>
              :
              <>
                <Grid item xs={6} height={345}>
                  <ChartDuration windowChart={1} interval={IntervalFirstChart} handleIntervalChange={handleIntervalChange} />
                </Grid><Grid item xs={6} height={345}>
                  <ChartDuration windowChart={2} interval={IntervalSecondChart} handleIntervalChange={handleIntervalChange} />
                </Grid><Grid item xs={6} height={345}>
                  <ChartDuration windowChart={3} interval={IntervalThirdtChart} handleIntervalChange={handleIntervalChange} />
                </Grid><Grid item xs={6} height={345}>
                  <ChartDuration windowChart={4} interval={IntervalFourthChart} handleIntervalChange={handleIntervalChange} />
                </Grid>
              </>
      }
    </Grid>
  );
});

MarketCharts.displayName = "MarketCharts";

export default MarketCharts;

const KLineChart: React.FC<KLineChartProps> = React.memo(({symbol, interval}) => {
  const ref = useRef<HTMLDivElement>(null);
  const [chart, setChart] = useState<Chart|null>(null);
  const [candlesticks, setCandlesticks] = useState<KLineData[]>([]);
  const [kline, setKline] = useState<KLineData>();
  const price = useSelector((state: AppState) => state);
  const [waiting, setWaiting] = useState(false);
  const {enqueueSnackbar} = useSnackbar();
  //   binanceSymbolSlice
  // sseOpenOrderSlice
  // sseNewTradeSlice
  // sseBalanceUpdateSlice
  // ssePositionUpdateSlice
  const {futuresSubscribe, futuresUnsubscribe, futuresReadyState,
    spotSubscribe,
    spotUnsubscribe, spotReadyState} = useBinanceWsProvider();

  // console.log(spotSubscribe(symbol));
  // console.log(price);
  // console.log(futuresReadyState);
  // console.log(symbol,price);
    
  const onWindowResize = () => chart?.resize();

  useEffect(() => {
    window.addEventListener("resize", onWindowResize);
    onWindowResize();
    window.devicePixelRatio = 3;

    return () => {
      window.removeEventListener("resize", onWindowResize);
    };
  }, [ref]);

  // useEffect(() => {
  //   console.log();
    
  //   spotSubscribe(symbol);
    
  //   return () => spotSubscribe(symbol);
  // }, []);

  useEffect(() => {
    if (chart) {
      chart.applyNewData(candlesticks);
    }
  }, [chart, candlesticks]);

  useEffect(() => {
    if (ref && ref.current && !chart) {
      const kLineChart = init(ref.current, {styles: chartStyles});
      setChart(kLineChart);
    }
  }, [ref, chart]);

  useEffect(() => {
    if (kline && chart) {
      chart.updateData(kline);
    }
  }, [kline, chart]);
  
  const connectToWs = () => {
    const webSocket = new WebSocket(
      `wss://fstream.binance.com/ws/${symbol}@kline_${interval}`
    );

    webSocket.onmessage = (message) => {
      const data = JSON.parse(message.data);
      const candleData = data.k;
      const newCandel = {
        timestamp: candleData.t,
        open: parseFloat(candleData.o),
        high: parseFloat(candleData.h),
        low: parseFloat(candleData.l),
        close: parseFloat(candleData.c),
        volume: parseFloat(candleData.v),
      };
      setKline(newCandel);
    };
  };

  const fetchCandlesticks = () => {
    fetchSymbolsKlines(symbol, interval)?.then((response) => {
      setCandlesticks(
        response.data.map((candlestick: Array<number | string>) => {
          return {
            timestamp: dayjs.utc(candlestick[0]).valueOf(),
            open: parseFloat(candlestick[1].toString()),
            high: parseFloat(candlestick[2].toString()),
            low: parseFloat(candlestick[3].toString()),
            close: parseFloat(candlestick[4].toString()),
            volume: parseFloat(candlestick[5].toString()),
          };
        })
      );
  
      connectToWs();
    });
  };

  useEffect(() => {
    fetchCandlesticks();
  }, []);
  
  useEffect(() => {
    if (candlesticks.length === 0) return;
    chart?.subscribeAction(ActionType.OnScroll, onScrollbarPositionChanged);

    return (() => {
      chart?.unsubscribeAction(ActionType.OnScroll, onScrollbarPositionChanged);
    });
  }, [chart, candlesticks]);

  let isLoading = false;

  let onScrollbarPositionChanged = () => {
    const dataList = chart?.getDataList();
    const from = chart?.getVisibleRange().realFrom;

    if (!dataList || isLoading) return;

    if (from === 0) {
      let endTime = dataList[0].timestamp;
      let prevTime: number | null = null;
      isLoading = true;
      setWaiting(true);

      fetchSymbolsKlines(symbol, interval, undefined, endTime)?.then((data) => {
        const newCandles = data.data?.map((item: any[]) => ({
          timestamp: item[0],
          open: item[1],
          high: item[2],
          low: item[3],
          close: item[4],
          volume: item[5],
        }));
          
        if (!newCandles || newCandles.length === 0) {
          return;
        } else {
          if (prevTime === newCandles[newCandles.length - 1].timestamp) {
            isLoading = false;
            setWaiting(false);

            return;
          }

          if (newCandles[newCandles.length - 1].timestamp === dataList[dataList.length - 1].timestamp) {
            isLoading = false;
            setWaiting(false);

            return;
          }

          prevTime = newCandles[newCandles.length - 1].timestamp;
          chart?.applyMoreData(newCandles);
        }

        isLoading = false;
        setWaiting(false);
      })
        .catch((error) => {
          enqueueSnackbar(error.message, {variant: "error"});
          isLoading = false; 
          setWaiting(false);
        });
    }
  };

  return (
    <>
      {
        waiting ? (
          <CircularProgress
            style={{position: "absolute", marginLeft: "1rem"}}
            color="inherit"
            size={32}
          />
        ) : (<></>)
      }
      <Box
        ref={ref}
        id={`chart-${symbol}`}
        style={{width: "100%", height: "calc(100% - 50px)"}}
      />
    </>
  );
});
KLineChart.displayName = "KLineChart"; 
  
export default KLineChart;
  
нужно сделать так, чтобы при изменении интервала у одного графика, остальные 3 не перерисовывались