import * as React from "react";
import _ from "lodash";
import Box from "@mui/material/Box";
import Grid from "@mui/material/Unstable_Grid2"; // Grid version 2
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import LinearProgress, {
  linearProgressClasses,
} from "@mui/material/LinearProgress";
import IconButton from "@mui/material/IconButton";
import PlayCircleIcon from "@mui/icons-material/PlayCircle";
import PauseCircleIcon from "@mui/icons-material/PauseCircle";
import ReplayCircleFilledIcon from "@mui/icons-material/ReplayCircleFilled";
import { useRouter } from "next/router";

import type { SvgIconProps } from "@mui/material/SvgIcon";

import {
  SteadilyGrowingIcon,
  SpikyWorkloadIcon,
  AnalyticalWorkloadIcon,
  SpikyWorkloadLine,
  NoCfgChangesRequiredIcon,
  SteadilyWorkloadLine,
  AnalyticalWorkloadLine,
  ClearIcon,
  APBucket,
  EmptyBucketIcon,
  DefaultBucket,
  CircleStack,
  VersusIcon,
} from "@/components/Sections/Scalable/Icons";
import { ProgressAlert } from "@/components/Sections/Scalable/EasyScaleContent_v2/Common";
import WorkloadSpikyLoad from "@/components/Sections/Scalable/EasyScaleContent_v2/SpikyWorkload";
import SteadilyWorkload from "@/components/Sections/Scalable/EasyScaleContent_v2/SteadilyWorkload";
import AnalyticalWorkload from "@/components/Sections/Scalable/EasyScaleContent_v2/AnalyticalWorkload";

const easyScaleItems: easyScaleItemType[] = [
  {
    id: "spiky-workload",
    order: 0,
    title: "Spiky",
    Icon: SpikyWorkloadIcon,
    Chart: SpikyWorkloadLine,
    breakPoints: [
      {
        id: "spiky-workload-0",
        title: "Spiky workload 0",
        progress: 49,
        nextSpeed: 0.1,
        actions: ["mysql-add-nodes", "mysql-check-cfg"],
      },
      // {
      //   id: "spiky-workload-1",
      //   title: "Spiky workload 1",
      //   progress: 52,
      //   nextSpeed: 0.1,
      //   actions: ["mysql-check-cfg"],
      // },
      {
        id: "spiky-workload-2",
        title: "Spiky workload 2",
        progress: 55,
        nextSpeed: 0.1,
      },
      {
        id: "spiky-workload-3",
        title: "Spiky workload 3",
        progress: 60,
        nextSpeed: 1,
      },
    ],
  },
  {
    id: "steadily-growing",
    order: 1,
    title: "Steadily",
    Icon: SteadilyGrowingIcon,
    Chart: SteadilyWorkloadLine,
  },
  {
    id: "analytical-workload",
    order: 2,
    title: "Analytical",
    Icon: AnalyticalWorkloadIcon,
    Chart: AnalyticalWorkloadLine,
    breakPoints: [
      {
        id: "analytical-workload-0",
        title: "Analytical workload 0",
        progress: 15,
        nextSpeed: 0.05,
      },
      {
        id: "analytical-workload-1",
        title: "Analytical workload 1",
        progress: 23,
        nextSpeed: 1,
      },
      {
        id: "analytical-workload-2",
        title: "Analytical workload 2",
        progress: 30,
        nextSpeed: 0.05,
      },
      {
        id: "analytical-workload-3",
        title: "Analytical workload 3",
        progress: 37,
        nextSpeed: 1,
      },
      {
        id: "analytical-workload-4",
        title: "Analytical workload 4",
        progress: 80,
        nextSpeed: 0.05,
      },
      {
        id: "analytical-workload-5",
        title: "Analytical workload 5",
        progress: 85,
        nextSpeed: 1,
      },
    ],
  },
];

type easyScaleItemType = {
  id: string;
  order: number;
  title: string;
  Icon: React.FC<SvgIconProps>;
  Chart: React.FC<SvgIconProps>;
  breakPoints?: easyScaleItemBreakPointType[];
};

type easyScaleItemBreakPointType = {
  id: string;
  title: string;
  progress: number;
  nextSpeed?: number;
  actions?: string[];
};

export default function EasyScaleContent() {
  const [selectedItemId, setSelectedItemId] = React.useState("spiky-workload");

  const router = useRouter();

  const handleChangeItem = React.useCallback(
    (target: string) => () => {
      router.push({
        pathname: router.asPath.split("#")[0].split("?")[0],
        query: {
          workload: target,
        },
        // hash: target,
      });
      // setSelectedItemId(target);
    },
    [router]
  );

  React.useEffect(() => {
    // old: /scalability/easy-scale-out-in#analytical-workload
    // new: /scalability/easy-scale-out-in?workload=analytical-workload
    // need to handle both
    const idList = easyScaleItems.map((item) => item.id);
    const hash = router.asPath.split("#")[1];
    const queryWorkload = (router.query.workload as string | undefined) || "";
    if (idList.includes(hash)) {
      handleChangeItem(hash)();
    }
    if (idList.includes(queryWorkload)) {
      setSelectedItemId(queryWorkload);
    }
  }, [handleChangeItem, router.asPath, router.query.workload]);

  const selected = easyScaleItems.find((item) => item.id === selectedItemId);

  return (
    <>
      <Grid container xs={12} spacing={2} minWidth="800px">
        <Player
          key={selectedItemId}
          selectedItemId={selectedItemId}
          selectedItem={selected as easyScaleItemType}
          handleChangeItem={handleChangeItem}
          disablePlay={selectedItemId === "steadily-growing"}
        />
      </Grid>
    </>
  );
}

export const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
  height: 68,
  borderRadius: 5,
  [`&.${linearProgressClasses.colorPrimary}`]: {
    backgroundColor: "#F7FFF7",
  },
  [`& .${linearProgressClasses.bar}`]: {
    borderRadius: 5,
    backgroundColor: "#E6FFDA",
    borderRight: "1px dashed #09D698",
  },
}));

export function PlayerCard(props: {
  item: easyScaleItemType;
  selected?: boolean;
  isPlaying?: boolean;
  progress?: number;
  onChange: (id: string) => () => void;
  handlePlay?: () => void;
  handleReset?: () => void;
  progressAlertEle?: React.ReactNode;
  hidePlay?: boolean;
}) {
  const {
    item,
    selected,
    isPlaying,
    progress,
    onChange,
    handlePlay,
    handleReset,
    progressAlertEle,
    hidePlay = false,
  } = props;

  return (
    <>
      <Grid key={item.id} xs={selected ? 6 : 3}>
        <Card
          variant="outlined"
          onClick={selected ? undefined : onChange(item.id)}
          sx={{
            cursor: selected ? "default" : "pointer",
            position: "relative",
            padding: "10px",
            height: "100%",
            display: "flex",
            "&:hover": {
              boxShadow: (theme) =>
                selected
                  ? undefined
                  : `0 0 0 1px ${theme.palette.primary.main}`,
            },
            ...(selected && {
              boxShadow: (theme) => `0 0 0 1px rgba(38, 38, 63, 0.5)`,
              overflow: "visible",
            }),
          }}
        >
          {!selected && (
            <Box
              width="100%"
              display="flex"
              alignItems="center"
              justifyContent="space-around"
              minHeight={32}
            >
              <Box>
                <Typography
                  component="div"
                  fontSize={16}
                  fontWeight={600}
                  color="#637599"
                >
                  {`Workload ${item.order + 1}`}
                </Typography>
                <Typography
                  component="div"
                  fontSize={12}
                  fontWeight={600}
                  color="#949EB7"
                >
                  {item.title}
                </Typography>
              </Box>

              <item.Icon
                sx={{
                  width: "120px",
                  height: "auto",
                  color: (theme) => theme.palette.background.paper,
                }}
              />
            </Box>
          )}
          {selected && (
            <>
              <Box
                component="div"
                height="2px"
                width="fit-content"
                overflow="hidden"
                fontSize={12}
                fontWeight={600}
                display="block"
                position="absolute"
                top="-2px"
                left="10px"
                px="6px"
                sx={{
                  background: (theme) => theme.palette.background.paper,
                  userSelect: "none",
                }}
              >
                {`Workload ${item.order + 1}: ${item.title}`}
              </Box>
              <Typography
                component="label"
                fontSize={12}
                fontWeight={600}
                position="absolute"
                top="-10px"
                left="16px"
              >
                {`Workload ${item.order + 1}: ${item.title}`}
              </Typography>
              <Box
                width="100%"
                display="flex"
                alignItems="center"
                justifyContent="space-between"
                minHeight={64}
                color="#000"
                gap={2}
              >
                <IconButton
                  color="inherit"
                  // aria-label={`play/${
                  //   isPlaying ? "pause" : progress === 100 ? "Replay" : "play"
                  // }`}
                  // disabled={!!(progress && progress < 100)}
                  // onClick={progress === 100 ? handleReset : handlePlay}
                  onClick={handleReset}
                >
                  {/* {!isPlaying && progress !== 100 && (
                      <PlayCircleIcon sx={{ height: 38, width: 38 }} />
                    )}
                    {!isPlaying && progress === 100 && (
                      <ReplayCircleFilledIcon sx={{ height: 38, width: 38 }} />
                    )}
                    {isPlaying && (
                      <PauseCircleIcon sx={{ height: 38, width: 38 }} />
                    )} */}
                  <ReplayCircleFilledIcon sx={{ height: 38, width: 38 }} />
                </IconButton>
                <Box width="100%" position="relative">
                  <BorderLinearProgress
                    variant="determinate"
                    value={hidePlay ? 0 : progress}
                  />
                  <item.Chart
                    sx={{
                      position: "absolute",
                      width: "100%",
                      height: "100%",
                      color: "transparent",
                      py: "8px",
                      top: 0,
                    }}
                  />
                  {progressAlertEle}
                  {/* {currentFrameMemo?.alert && isReachedCurrentFrame && (
                          <ProgressAlert
                            status={currentFrameMemo.alert.status}
                            content={currentFrameMemo.alert.title}
                            boxSx={{
                              position: "absolute",
                              top: "8px",
                              ...(progress < 75 && {
                                left: `${progress + 5}%`,
                              }),
                              ...(progress >= 75 && {
                                right: `${100 - progress + 5}%`,
                              }),
                              animation: "button-blink 2s infinite, shake 1s",
                            }}
                          />
                        )} */}
                </Box>
              </Box>
            </>
          )}
        </Card>
      </Grid>
    </>
  );
}

export function Player(props: {
  selectedItemId: string;
  selectedItem: easyScaleItemType;
  handleChangeItem: (id: string) => () => void;
  disablePlay?: boolean;
}) {
  const {
    selectedItemId,
    selectedItem,
    handleChangeItem,
    disablePlay = false,
  } = props;

  const [isPlaying, setIsPlaying] = React.useState(!disablePlay);
  const [progress, setProgress] = React.useState(0);
  const [playTimes, setPlayTimes] = React.useState(0);
  const [speed, setSpeed] = React.useState(1);
  const [approachingBreakpoint, setApproachingBreakpoint] = React.useState<
    number | null
  >(selectedItem?.breakPoints?.length ? 0 : null);
  const [completedActions, setCompletedActions] = React.useState<string[]>([]);

  const handlePlay = () => {
    setIsPlaying(true);
  };

  const handlePause = () => {
    setIsPlaying(false);
  };

  const handleReplay = () => {
    setProgress(0);
    setPlayTimes((prev) => prev + 1);
    setIsPlaying(true);
    setSpeed(1);
    setApproachingBreakpoint(selectedItem?.breakPoints?.length ? 0 : null);
    setCompletedActions([]);
  };

  const handleCompleteActions = (actions: string[]) => {
    setCompletedActions((prev) => [...prev, ...actions]);
  };

  const targetBreakpointItemMemo = React.useMemo(() => {
    if (!selectedItem?.breakPoints || _.isNull(approachingBreakpoint))
      return null;
    return selectedItem.breakPoints[approachingBreakpoint];
  }, [selectedItem, approachingBreakpoint]);

  const isTargetActionsCompleted = React.useMemo(() => {
    if (!targetBreakpointItemMemo?.actions) return true;
    return targetBreakpointItemMemo.actions.every((action) =>
      completedActions.includes(action)
    );
  }, [completedActions, targetBreakpointItemMemo]);

  React.useEffect(() => {
    if (isPlaying) {
      const timer = setInterval(() => {
        setProgress((prev) => {
          if (prev >= 100) {
            setIsPlaying(false);
            return 100;
          }
          return prev + speed;
        });
      }, 100);

      return () => clearInterval(timer);
    }
  }, [isPlaying, speed]);

  React.useEffect(() => {
    if (
      targetBreakpointItemMemo &&
      progress >= targetBreakpointItemMemo.progress
    ) {
      const newSpeed = targetBreakpointItemMemo.nextSpeed || 1;
      setSpeed(newSpeed);
      !isTargetActionsCompleted && handlePause();
      isTargetActionsCompleted &&
        setApproachingBreakpoint((prev) => (_.isNull(prev) ? null : prev + 1));
    }
  }, [
    isTargetActionsCompleted,
    progress,
    speed,
    targetBreakpointItemMemo,
    approachingBreakpoint,
  ]);

  // React.useEffect(() => {
  //   console.log("completedActions", completedActions);
  //   console.log("targetBreakpointItemMemo", targetBreakpointItemMemo);
  //   const isCompleted =  targetBreakpointItemMemo?.actions?.every((action) =>
  //     completedActions.includes(action)
  //   );
  //   if (isCompleted) {
  //     setIsPlaying(true);
  //   }
  // }, [completedActions, targetBreakpointItemMemo?.actions]);

  React.useEffect(() => {
    if (isTargetActionsCompleted && !disablePlay) {
      setIsPlaying(true);
    }
  }, [disablePlay, isTargetActionsCompleted]);

  return (
    <>
      <Grid
        container
        spacing={2}
        xs={12}
        position="relative"
        sx={{
          "@keyframes button-blink": {
            "0%": {
              opacity: 1,
            },
            "50%": {
              opacity: 0.5,
            },
            "100%": {
              opacity: 1,
            },
          },
        }}
      >
        {easyScaleItems.map((item) => (
          <PlayerCard
            key={item.id}
            hidePlay={disablePlay}
            item={item}
            selected={selectedItemId === item.id}
            isPlaying={isPlaying}
            progress={progress}
            onChange={handleChangeItem}
            handlePlay={handlePlay}
            handleReset={handleReplay}
            progressAlertEle={
              <>
                {selectedItemId === "spiky-workload" &&
                  progress >= 49 &&
                  progress <= 52 && (
                    <ProgressAlert
                      status="warning"
                      content="Peak load is approaching"
                      boxSx={{
                        position: "absolute",
                        top: "8px",
                        ...(progress < 75 && {
                          left: `${progress + 5}%`,
                        }),
                        ...(progress >= 75 && {
                          right: `${100 - progress + 5}%`,
                        }),
                        animation: "button-blink 2s infinite, shake 1s",
                      }}
                    />
                  )}
              </>
            }
          />
        ))}
      </Grid>
      <Grid container spacing={2} xs={12}>
        {selectedItemId === "spiky-workload" && (
          <WorkloadSpikyLoad
            key={`spiky-${playTimes}`}
            progress={progress}
            isPlaying={isPlaying}
            handleCompleteActions={handleCompleteActions}
          />
        )}
        {selectedItemId === "steadily-growing" && (
          <SteadilyWorkload key={`steadily-${playTimes}`} />
        )}
        {selectedItemId === "analytical-workload" && (
          <AnalyticalWorkload
            key={`analytical-${playTimes}`}
            progress={progress}
            isPlaying={isPlaying}
            handleCompleteActions={handleCompleteActions}
          />
        )}
      </Grid>
    </>
  );
}
