import * as React from "react";
import _ from "lodash";
import Box, { BoxProps } from "@mui/material/Box";
import ReactEcharts from "echarts-for-react";
import Switch from "@mui/material/Switch";
import Grid from "@mui/material/Unstable_Grid2"; // Grid version 2
import Card, { CardProps } from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import CircularProgress, {
  circularProgressClasses,
  CircularProgressProps,
} from "@mui/material/CircularProgress";
import LinearProgress, {
  linearProgressClasses,
} from "@mui/material/LinearProgress";
import IconButton from "@mui/material/IconButton";
import PlayCircleIcon from "@mui/icons-material/PlayCircle";
import StopCircleIcon from "@mui/icons-material/StopCircle";
import PauseCircleIcon from "@mui/icons-material/PauseCircle";
import ReplayCircleFilledIcon from "@mui/icons-material/ReplayCircleFilled";
import WarningIcon from "@mui/icons-material/Warning";
import Button, { ButtonProps } from "@mui/material/Button";
import Collapse from "@mui/material/Collapse";
import Grow from "@mui/material/Grow";
import Stack from "@mui/material/Stack";
import CheckIcon from "@mui/icons-material/Check";
import type { SvgIconProps } from "@mui/material/SvgIcon";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import AddIcon from "@mui/icons-material/Add";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import AccessTimeIcon from "@mui/icons-material/AccessTime";
import Fade from "@mui/material/Fade";

import { cards as cardsCfg } from "@/components/Sections/Scalable/_config";
import { config as navCfg } from "@/components/Layout2/_config";
import SQL from "@/components/Sections/RealTimeAnalytics/SQL";
import ContentTemplate from "@/components/Sections/Common/ContentTemplate";
import ARTComparisonChart from "@/components/Sections/Scalable/ARTComparisonChart";
import ARTSwitchCard from "@/components/Sections/Scalable/ARTSwitchCard";
import {
  SteadilyGrowingIcon,
  SpikyWorkloadIcon,
  AnalyticalWorkloadIcon,
  SpikyWorkloadLine,
  NoCfgChangesRequiredIcon,
  SteadilyWorkloadLine,
  AnalyticalWorkloadLine,
  ClearIcon,
  APBucket,
  EmptyBucketIcon,
  DefaultBucket,
  CircleStack,
  VersusIcon,
} from "@/components/Sections/Scalable/Icons";
import {
  UnifiedCodeDiffHighlight,
  UnifiedCodeDiffHighlightProps,
} from "@/components/CodeBlock";
import {
  animationKeyframesProps,
  DefaultBucketAnimation,
  DangerBucketAnimation,
  ResourcePoolExtensionAnimation,
  ClickArrowAnimation,
} from "@/components/Sections/Scalable/Animation";
import CustomCollapse from "@/components/Transform/Collapse";
import YoutubePlayer from "@/components/Sections/Scalable/Player";
import { TiDBLogoRed } from '@/components/Icons';

export function ResultCardHeader(props: {
  type?: "default" | "mysql" | "tidb";
  theme?: "default" | "mysql" | "tidb";
  title?: string | React.ReactNode;
  children?: React.ReactNode;
  boxSx?: BoxProps["sx"];
}) {
  const { type = "default", theme = "default", title, children, boxSx } = props;

  return (
    <Box
      sx={{
        backgroundColor: (theme) => theme.palette.background?.paper,
        borderRadius: "6px",
        padding: 1,
        // mb: 1,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        gap: 1,
        ...(theme === "tidb" && {
          color: "#FFFFFF",
          backgroundColor: "#0066FF",
        }),
        ...(theme === "mysql" && {
          color: "#FFFFFF",
          backgroundColor: "#FE8F29",
        }),
        ...boxSx,
      }}
    >
      {type === "mysql" && <CircleStack />}
      {type === "tidb" && (
        <TiDBLogoRed />
      )}
      {typeof title === "string" ? (
        <Typography
          component="h3"
          fontWeight={700}
          fontSize={16}
          color="inherit"
        >
          {title}
        </Typography>
      ) : (
        title
      )}
      {children}
    </Box>
  );
}

export const PlayContentTemplate = (props: {
  title: string;
  type?: "mysql" | "tidb";
  configFile: string;
  configFileChildren?: React.ReactNode;
  codeProps?: Partial<UnifiedCodeDiffHighlightProps>;
  codeMinHeight?: string;
  chartEle?: React.ReactNode;
  animationEle?: React.ReactNode;
  conclusionsEle?: React.ReactNode;
  animationBoxSx?: BoxProps["sx"];
}) => {
  const {
    title,
    type = "mysql",
    configFile,
    configFileChildren,
    codeProps,
    codeMinHeight,
    chartEle,
    animationEle,
    conclusionsEle,
    animationBoxSx,
  } = props;

  const [isExpanded, setIsExpanded] = React.useState<boolean>(true);

  const commonInnerBoxSx: BoxProps["sx"] = {
    background: "#FFFFFF",
    border: "1px solid #E1E1E1",
    borderRadius: "6px",
    padding: 1,
    mb: 1,
    position: "relative",
  };

  return (
    <Box
      sx={{
        background: "#FFFFFF",
        boxShadow: "0px 4px 4px rgba(0, 0, 0, 0.25)",
        p: 1,
      }}
    >
      <ResultCardHeader
        type={type}
        theme={type}
        title={title}
        boxSx={{
          mb: 1,
        }}
      />
      {conclusionsEle && <Box>{conclusionsEle}</Box>}
      <Box
        sx={{
          ...commonInnerBoxSx,
        }}
      >
        <Typography component="h4" fontWeight={600} fontSize={14} gutterBottom>
          Config file
        </Typography>
        <CustomCollapse collapsedSize={60}>
          <Box minHeight={codeMinHeight || "256px"}>
            <UnifiedCodeDiffHighlight
              language="yaml"
              text={configFile}
              showLineNumbers
              wrapLines
              {...codeProps}
            />
          </Box>
        </CustomCollapse>
        {configFileChildren}
      </Box>
      <Box
        sx={{
          ...commonInnerBoxSx,
        }}
      >
        <Typography component="h4" fontWeight={600} fontSize={14} gutterBottom>
          Database Status
        </Typography>
        <Box
          height={120}
          sx={{
            // background: "#FFFFFF",
            // border: "1px solid #EAEAEA",
            // borderRadius: "6px",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",

            ...(animationBoxSx as any),
            ...animationKeyframesProps,
          }}
        >
          {animationEle}
        </Box>
        {chartEle && (
          <>
            {/* <Typography
              component="h4"
              fontSize={12}
              gutterBottom
              color="text.secondary"
            >
              Average Query Duration
            </Typography> */}
            <Box height={250} width="100%">
              {chartEle}
            </Box>
          </>
        )}
      </Box>
    </Box>
  );
};

export function AnimationVerticleWrapper(props: {
  children: React.ReactNode;
  title?: string | React.ReactNode;
  status?: "success" | "loading";
}) {
  const { children, title, status } = props;

  return (
    <Box
      display="flex"
      alignItems="center"
      justifyContent="center"
      flexDirection="column"
      gap={2}
      position="relative"
    >
      {children}

      <Typography
        variant="body2"
        textAlign="center"
        fontWeight={600}
        fontSize={16}
        display="inline-flex"
        alignItems="center"
        gap={1}
      >
        {status === "success" && (
          <CheckCircleIcon fontSize="inherit" color="success" />
        )}
        {status === "loading" && <CircularProgress size={20} />}
        {title}
      </Typography>
    </Box>
  );
}

export const BlinkButtonSx = {
  outline: "1px dashed #0F8CFF",
  outlineOffset: "4px",
  transition: "outline-offset 200ms ease",
  "&:hover": {
    outlineOffset: "2px",
  },
  opacity: 0.8,
  animation: "button-blink 2s infinite",
};

export const ProgressAlert = (props: {
  status: "info" | "warning" | string;
  content: string | React.ReactNode;
  boxSx?: BoxProps["sx"];
}) => {
  const { status, content, boxSx } = props;

  return (
    <>
      <Box
        sx={{
          padding: "8px 16px",
          background: "#FFFFFF",
          border: "1px solid #EAEAEA",
          boxShadow: "inset 4px 4px 4px rgba(255, 138, 0, 0.1)",
          borderRadius: "6px",
          display: "flex",
          alignItems: "center",
          gap: "8px",
          userSelect: "none",
          ...boxSx,
        }}
      >
        {status === "warning" && (
          <WarningIcon fontSize="inherit" color="warning" />
        )}
        <Typography
          fontWeight={600}
          fontSize={12}
          lineHeight={1.25}
          component="div"
        >
          {content}
        </Typography>
      </Box>
    </>
  );
};

export const CfgModification = (props: {
  changedFiles?: number;
  addedLines?: number;
  deletedLines?: number;
  noChange?: boolean;
}) => {
  const { changedFiles, addedLines = 0, deletedLines = 0, noChange } = props;

  const ChangedChildren = (
    <>
      {changedFiles && (
        <>
          {`Changed`}
          <Typography
            component="span"
            fontSize="inherit"
            fontWeight="inherit"
            color="success.main"
          >
            {changedFiles}
          </Typography>
          {`file(s),`}
        </>
      )}
      <Typography
        component="span"
        fontSize="inherit"
        fontWeight="inherit"
        color="success.main"
      >
        {`+${addedLines}`}
      </Typography>
      /
      <Typography
        component="span"
        fontSize="inherit"
        fontWeight="inherit"
        color="error.main"
      >
        {`-${deletedLines}`}
      </Typography>
      {`lines`}
    </>
  );

  return (
    <>
      <Typography
        component="div"
        fontWeight={600}
        fontSize={14}
        gutterBottom
        color="#7C7C7C"
        display="inline-flex"
        alignItems="center"
        gap={0.5}
      >
        <CheckCircleIcon fontSize="inherit" color="success" />
        {noChange ? "No config file changed" : ChangedChildren}
      </Typography>
    </>
  );
};

export const Conclusions = (props: {
  type: "mysql" | "tidb";
  items: (string | React.ReactNode)[];
}) => {
  const { type, items } = props;

  return (
    <Box mb={1}>
      {items.map((item, index) => (
        <Box
          key={index}
          width="100%"
          sx={{
            padding: "4px 16px",
            // mb: 1,
            backgroundColor:
              type === "mysql"
                ? "rgba(254, 143, 41, 0.07)"
                : "rgba(0, 102, 255, 0.05)",
          }}
        >
          <Typography
            component="div"
            fontSize={16}
            // display="inline-flex"
            // alignItems="center"
            // gap={0.5}
          >
            {!!item ? `${index + 1}. ` : <br />}
            {item}
          </Typography>
        </Box>
      ))}
    </Box>
  );
};

export const commonOption = {
  // tooltip: {
  //   order: "valueDesc",
  //   trigger: "axis",
  // },
  xAxis: {
    name: "Time",
    type: "category",
    splitLine: {
      show: false,
    },
    axisLabel: {
      show: false,
    },
    axisLine: {
      symbol: ["none", "none"],
    },
    min: 0,
  },
  yAxis: {
    name: "Latency",
    type: "value",
    nameTextStyle: {
      fontWeight: "bold",
      color: "#212121",
    },
    splitLine: {
      show: false,
    },
    axisLabel: {
      show: false,
    },
    axisLine: {
      show: true,
      symbol: ["none", "arrow"],
    },
    min: 0,
    max: 170,
    // max: function (value: any) {
    //   if (value.max < 100) {
    //     return 100;
    //   }
    //   return "dataMax";
    // },
  },
};

export const VersusEle = () => {
  return (
    <>
      <Box
        sx={{
          width: "64px",
          height: "64px",
          background: "#F5FAFF",
          borderRadius: "50%",
          border: "6px solid #FFFFFF",
          boxShadow: "0px 4px 4px rgba(0, 0, 0, 0.25)",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",

          position: "absolute",
          left: "calc(50% - 32px)",
        }}
      >
        <VersusIcon
          sx={{
            width: "32px",
            height: "32px",
          }}
        />
      </Box>
    </>
  );
};

export function AnimationServerlessAutoScaledOut(props: {
  timeout?: number;
  reverse?: boolean;
  isAp?: boolean;
}) {
  const { timeout = 2000, reverse = false, isAp } = props;

  const [isScaling, setIsScaling] = React.useState(true);

  React.useEffect(() => {
    if (isScaling) {
      setTimeout(() => {
        setIsScaling(false);
      }, timeout);
    }
  }, [isScaling, timeout]);

  const scalingText = reverse
    ? `Auto scaling in${isAp ? " 1 analytic node" : ""}`
    : `Auto scaling out${isAp ? " 1 analytic node" : ""}`;
  const scaledText = reverse
    ? `Auto scaled in${isAp ? " 1 analytic node" : ""}`
    : `Auto scaled out${isAp ? " 1 analytic node" : ""}`;

  return (
    <>
      <AnimationVerticleWrapper
        title={isScaling ? scalingText : scaledText}
        status={isScaling ? "loading" : "success"}
      >
        <Box
          display="flex"
          alignItems="center"
          justifyContent="center"
          flexDirection="row"
          gap={8}
        >
          <DefaultBucketAnimation />
          <ResourcePoolExtensionAnimation play reverse={reverse} isAP={isAp} />
        </Box>
      </AnimationVerticleWrapper>
    </>
  );
}

export function AddMysqlNode(props: {
  unitDuration?: number;
  unitLabel?: string;
  items?: {
    id: string;
    unit: number;
    title: string;
  }[];
  postAddNode?: {
    id: string;
    title: string;
    requiredActions?: string[];
  }[];
  postFinishItems?: () => void;
  finishedActions?: string[];
}) {
  const {
    unitDuration = 1000,
    items = [],
    postAddNode = [],
    finishedActions = [],
    postFinishItems,
    unitLabel = "Day",
  } = props;

  const [hasAddedBucket, setHasAddedBucket] = React.useState(false);
  const [addBucketComplete, setAddBucketComplete] = React.useState(false);
  const [step, setStep] = React.useState(0);

  const [totalSteps, itemsWithSteps] = React.useMemo(() => {
    const data = items.reduce(
      (
        acc: {
          totalSteps: number;
          items: {
            id: string;
            unit: number;
            title: string;
            startStep: number;
            endStep: number;
          }[];
        },
        cur
      ) => {
        return {
          totalSteps: acc.totalSteps + cur.unit,
          items: [
            ...acc.items,
            {
              ...cur,
              startStep: acc.totalSteps,
              endStep: acc.totalSteps + cur.unit,
            },
          ],
        };
      },
      {
        totalSteps: 0,
        items: [],
      }
    );
    return [data.totalSteps, data.items];
  }, [items]);

  React.useEffect(() => {
    if (hasAddedBucket) {
      const timer = setInterval(() => {
        setStep((prev) => {
          if (prev >= totalSteps) {
            setAddBucketComplete(true);
            postFinishItems && postFinishItems();
            return totalSteps;
          }
          return prev + 1;
        });
      }, unitDuration);

      return () => clearInterval(timer);
    }
  }, [hasAddedBucket, unitDuration, totalSteps, postFinishItems]);

  const isPostAddNodesComplete = React.useMemo(() => {
    return (
      addBucketComplete &&
      postAddNode.every((item) => {
        const required = item.requiredActions || [];
        return required.every((action) => finishedActions.includes(action));
      })
    );
  }, [addBucketComplete, finishedActions, postAddNode]);

  return (
    <>
      <Box
        display="flex"
        alignItems="center"
        justifyContent="center"
        flexDirection="column"
        gap={2}
      >
        <Box
          display="flex"
          flexDirection="row"
          alignItems="center"
          justifyContent="center"
          gap={1}
        >
          <DefaultBucketAnimation />
          {isPostAddNodesComplete && <DefaultBucketAnimation />}
          {/* <Fade in={isPostAddNodesComplete}>
            <Box>
              <DefaultBucketAnimation />
            </Box>
          </Fade> */}
        </Box>

        <Box position="relative">
          <Button
            variant="contained"
            size="small"
            disabled={hasAddedBucket}
            endIcon={hasAddedBucket && <CheckIcon fontSize="inherit" />}
            onClick={() => {
              // handleCompleteActions(["mysql-add-nodes"]);
              setHasAddedBucket(true);
            }}
            sx={{
              position: "relative",
              // ...(!hasAddedBucket && BlinkButtonSx),
              ...(hasAddedBucket && {
                display: "none",
              }),
            }}
          >
            Click to add a node
          </Button>
          {!hasAddedBucket && <ClickArrowAnimation />}
        </Box>

        {hasAddedBucket && (
          <Typography
            fontWeight={600}
            fontSize={16}
            display="inline-flex"
            alignItems="center"
            gap={0.5}
          >
            <AccessTimeIcon />
            {step} {unitLabel}
            {step > 1 ? "s" : ""}
          </Typography>
        )}
      </Box>
      {hasAddedBucket && (
        <Stack ml={4} spacing={0.5}>
          {itemsWithSteps.map((item) => (
            <Box
              key={item.id}
              display="inline-flex"
              alignItems="center"
              gap={1}
            >
              {step < item.endStep ? (
                <CircularProgress size={18} />
              ) : (
                <CheckIcon fontSize="small" />
              )}
              <Typography variant="body2" component="div">
                {item.title}({item.unit}
                {unitLabel}
                {item.unit > 1 ? "s" : ""})
              </Typography>
            </Box>
          ))}
          {postAddNode.map((item) => (
            <Box
              key={item.id}
              display="inline-flex"
              alignItems="center"
              gap={1}
            >
              {!item.requiredActions?.every((i) =>
                finishedActions.includes(i)
              ) ? (
                <CircularProgress size={18} />
              ) : (
                <CheckIcon fontSize="small" />
              )}
              <Typography variant="body2" component="div">
                {item.title}
              </Typography>
            </Box>
          ))}
        </Stack>
      )}
    </>
  );
}
