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 ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
import CloseIcon from "@mui/icons-material/Close";

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,
  ConclusionAnalyticalMySQL,
  ConclusionAnalyticalTiDB,
} 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 {
  PlayContentTemplate,
  AnimationVerticleWrapper,
  BlinkButtonSx,
  ProgressAlert,
  CfgModification,
  Conclusions,
  commonOption,
  VersusEle,
  AnimationServerlessAutoScaledOut,
} from "@/components/Sections/Scalable/EasyScaleContent_v2/Common";

const analyticalWorkloadMeta = {
  mysql: {
    cfg: `spring:
  datasource:
    url: jdbc:mysql://localhost:4000/sharding_plan?username=root
    driver-class-name: com.mysql.cj.jdbc.Driver`,
    modifiedCfg: `spring:
  datasource:
    # point to sharding config file and wrapper class
    url: jdbc:shardingsphere:classpath:shardingsphere-config.yml
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver

# NEW sharding library which depends on Zookeeper
mode:
  type: Cluster
  repository:
    type: ZooKeeper
    props:
      namespace: governance
      server-lists: localhost:2181
      retryIntervalMilliseconds: 500
      timeToLiveSeconds: 60

dataSources:
  shardingsphere_0:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/shardingsphere_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
  shardingsphere_1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/shardingsphere_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456

rules:
  - !SHARDING
    # Shards manually, relocate hard
    tables:
      github_events:
        actualDataNodes: shardingsphere_\${0..1}.github_events
        databaseStrategy:
          standard:
            shardingColumn: repo_id
            shardingAlgorithmName: repo_id_sharding_inline
      github_repos:
        actualDataNodes: shardingsphere_\${0..1}.github_repos
        databaseStrategy:
          standard:
            shardingColumn: repo_id
            shardingAlgorithmName: repo_id_sharding_inline
    # Hard to change this algorithm
    shardingAlgorithms:
      repo_id_sharding_inline:
        type: INLINE
        props:
          algorithm-expression: shardingsphere_\${repo_id % 2}

props:
  sql-show: true`,
    added: [...new Array(54).fill(0).map((_, i) => i + 4)],
    conclusion: [
      "Manual data relocation",
      "Complex code & arch",
      "Higher cost(hardware & human resource)",
    ],
  },
  tidb: {
    cfg: `spring: 
  datasource: 
    url: jdbc:mysql://localhost:4000/tidb_plan 
    username: root 
    driver-class-name: com.mysql.cj.jdbc.Driver`,
    conclusion: [
      "Automatic data relocation and zero down time",
      "Simple code & arch",
      "Lower cost(pay as you go)",
    ],
  },
};

function randomData(min = 0, max = 100) {
  return Math.round(Math.random() * (max - min) + min);
}

const workloadAnalyticalChartMysqlData = [
  ...new Array(15).fill(0).map((_, i) => ({
    name: i,
    value: 60 + randomData(0, 10) - 5,
  })),
  ...new Array(14).fill(0).map((_, i) => ({
    name: i + 15,
    value: 80 + (i + 39 - 45) / 30 + randomData(0, 10) - 5,
  })),
  ...new Array(4).fill(0).map((_, i) => ({
    name: i + 29,
    value: 150 + (i + 50 - 49) / 80 + randomData(0, 10) - 5,
  })),
  ...new Array(5).fill(0).map((_, i) => ({
    name: i + 33,
    value: 150 + (59 - i - 55) / 80 + randomData(0, 10) - 5,
  })),
  ...new Array(70).fill(0).map((_, i) => ({
    name: i + 37,
    value: null,
  })),
];

const workloadAnalyticalChartTiDBData = [
  ...new Array(100).fill(0).map((_, i) => ({
    name: i,
    value: randomData(30, 40),
  })),
  // ...new Array(10).fill(0).map((_, i) => ({
  //   name: i + 50,
  //   value: randomData(45, 60),
  // })),
  // ...new Array(40).fill(0).map((_, i) => ({
  //   name: i + 60,
  //   value: randomData(30, 40),
  // })),
];

export default function AnalyticalWorkload(props: {
  progress: number;
  isPlaying?: boolean;
  handleCompleteActions: (actions: string[]) => void;
}) {
  const { progress, isPlaying, handleCompleteActions } = props;

  const [chartDataMysqlMemo, chartDataTiDBMemo] = React.useMemo(() => {
    let result1: any[] = [];
    let result2: any[] = [];
    const result1Tmp = workloadAnalyticalChartMysqlData.filter(
      (i) => i.name <= progress
    );
    const result2Tmp = workloadAnalyticalChartTiDBData.filter(
      (i) => i.name <= progress
    );
    if (result1Tmp.length < 100) {
      result1 = [
        ...new Array(100 - result1Tmp.length).fill(null),
        ...result1Tmp,
      ];
    } else {
      result1 = result1Tmp;
    }
    if (result2Tmp.length < 100) {
      result2 = [
        ...new Array(100 - result2Tmp.length).fill(null),
        ...result2Tmp,
      ];
    } else {
      result2 = result2Tmp;
    }
    return [result1, result2];
  }, [progress]);

  return (
    <>
      <VersusEle />
      <Grid xs={6}>
        <PlayContentTemplate
          title="MySQL RDS"
          configFile={analyticalWorkloadMeta.mysql.cfg}
          animationEle={
            <>
              {progress <= 15 && isPlaying && <DefaultBucketAnimation />}
              {progress > 15 && progress < 22 && LoadHighEle}
              {progress >= 22 && progress < 29 && (
                <AnimationVerticleWrapper
                  status="success"
                  title="Comes to rated load"
                >
                  <DefaultBucketAnimation />
                </AnimationVerticleWrapper>
              )}
              {progress >= 29 && progress < 33 && LoadHighEle}
              {progress >= 33 && progress < 34.5 && (
                <AnimationVerticleWrapper title="🚨🚨🚨 Overload">
                  <DangerBucketAnimation />
                </AnimationVerticleWrapper>
              )}
              {progress >= 34.5 && progress < 100 && (
                <AnimationVerticleWrapper title="🚨 Service down">
                  <DangerBucketAnimation />
                  <ClearIcon
                    sx={{
                      width: 50,
                      height: 50,
                      position: "absolute",
                      top: "-10px",
                      left: "calc(50% - 25px)",
                    }}
                  />
                </AnimationVerticleWrapper>
              )}
              {progress >= 100 && (
                <ConclusionAnalyticalMySQL
                  sx={{
                    color: "transparent",
                    width: "75%",
                    maxWidth: 256,
                    height: "auto",
                  }}
                />
              )}
            </>
          }
          conclusionsEle={
            progress >= 100 && (
              <Conclusions
                type="mysql"
                items={[
                  <>
                    <b>Can&apos;t</b> handle unpredictable analytical queries
                  </>,
                  <>
                    <b>Complex</b> tool chain
                  </>,
                  null,
                ]}
              />
            )
          }
          chartEle={
            <ReactEcharts
              option={{
                ...commonOption,
                series: [
                  {
                    name: "Fake Data",
                    type: "line",
                    showSymbol: false,
                    data: chartDataMysqlMemo,
                    // markPoint: progress >= 100 && {
                    //   silent: true,
                    //   label: {
                    //     show: true,
                    //     position: "insideBottom",
                    //   },
                    //   itemStyle: {
                    //     color: "transparent",
                    //   },
                    //   animationDelay: 3000,
                    //   data: [
                    //     {
                    //       name: "peak load",
                    //       value: "⚠️",
                    //       yAxis:
                    //         workloadSpikyLoadChartMysqlData.find(
                    //           (i) => i.name === 49
                    //         )?.value || 0,
                    //       xAxis: 49,
                    //     },
                    //   ],
                    // },
                    markLine: progress >= 100 && {
                      silent: true,
                      showSymbol: false,
                      symbol: "none",
                      data: [
                        {
                          name: "30%",
                          xAxis: 30,
                          label: {
                            formatter: "Workload peak",
                            position: "insideEnd",
                            rotate: 0,
                          },
                        },
                        {
                          name: "34%",
                          xAxis: 37,
                          label: {
                            formatter: "⚠️ No metrics captured",
                            position: "insideEnd",
                            rotate: 0,
                            offset: [123, 0],
                          },
                        },
                      ],
                    },
                  },
                  progress >= 100 && {
                    name: "line",
                    type: "line",
                    stack: "all",
                    showSymbol: false,
                    markLine: {
                      symbol: "none",
                      silent: true,
                      label: {
                        position: "start",
                      },
                      data: [
                        {
                          name: "Horizontal line with Y value at 100",
                          yAxis: 100,
                        },
                      ],
                    },
                  },
                ],
              }}
            />
          }
        />
      </Grid>

      <Grid xs={6}>
        <PlayContentTemplate
          title="TiDB Cloud Starter"
          type="tidb"
          configFile={analyticalWorkloadMeta.tidb.cfg}
          configFileChildren={
            <>
              {progress > 15 && (
                <Box
                  sx={{
                    position: "absolute",
                    top: "8px",
                    right: "8px",
                  }}
                >
                  <CfgModification noChange />
                </Box>
              )}
            </>
          }
          animationEle={
            <>
              {progress <= 15 && isPlaying && <DefaultBucketAnimation />}
              {progress > 15 && progress < 19 && (
                <AnimationServerlessAutoScaledOut isAp />
              )}
              {progress >= 19 && progress < 32 && (
                <AnimationServerlessAutoScaledOut isAp reverse />
              )}
              {progress >= 32 && progress < 36 && (
                <AnimationServerlessAutoScaledOut isAp />
              )}
              {progress >= 36 && progress < 80 && (
                <AnimationServerlessAutoScaledOut isAp reverse />
              )}
              {progress >= 80 && progress < 84 && (
                <AnimationServerlessAutoScaledOut isAp />
              )}
              {progress >= 84 && progress < 100 && (
                <AnimationServerlessAutoScaledOut isAp reverse />
              )}
              {progress >= 100 && (
                <ConclusionAnalyticalTiDB
                  sx={{
                    color: "transparent",
                    width: "75%",
                    height: "auto",
                  }}
                />
              )}
            </>
          }
          conclusionsEle={
            progress >= 100 && (
              <Conclusions
                type="tidb"
                items={[
                  <>
                    <b>Easy</b> to handle unpredictable analytical queries
                  </>,
                  <>
                    <b>ONE Database</b> for hybrid workload
                  </>,
                  <>
                    <b>Auto</b> scaling out/in
                  </>,
                ]}
              />
            )
          }
          chartEle={
            <ReactEcharts
              option={{
                ...commonOption,
                series: [
                  {
                    name: "Fake Data",
                    type: "line",
                    showSymbol: false,
                    data: chartDataTiDBMemo,
                    // markPoint: progress >= 100 && {
                    //   silent: true,
                    //   label: {
                    //     show: true,
                    //     position: "insideBottom",
                    //   },
                    //   itemStyle: {
                    //     color: "transparent",
                    //   },
                    //   animationDelay: 3000,
                    //   data: [
                    //     {
                    //       name: "peak load",
                    //       value: "⚠️",
                    //       yAxis:
                    //         workloadSpikyLoadChartTiDBData.find(
                    //           (i) => i.name === 49
                    //         )?.value || 0,
                    //       xAxis: 49,
                    //     },
                    //   ],
                    // },
                    markLine: progress >= 100 && {
                      silent: true,
                      showSymbol: false,
                      symbol: "none",
                      data: [
                        {
                          name: "30%",
                          xAxis: 30,
                          label: {
                            formatter: "Workload peak",
                            position: "insideEnd",
                            rotate: 0,
                          },
                        },
                      ],
                    },
                  },
                  progress >= 100 && {
                    name: "line",
                    type: "line",
                    stack: "all",
                    showSymbol: false,
                    markLine: {
                      symbol: "none",
                      silent: true,
                      label: {
                        position: "start",
                      },
                      data: [
                        {
                          name: "Horizontal line with Y value at 100",
                          yAxis: 100,
                        },
                      ],
                    },
                  },
                ],
              }}
            />
          }
        />
      </Grid>
    </>
  );
}

const LoadHighEle = (
  <AnimationVerticleWrapper title="🚨 Load high">
    <Box display="flex" flexDirection="row" gap={4} alignItems="center">
      <DangerBucketAnimation warning />
      {/* <Stack component="ul" p={1} border="1px solid #D9D9D9">
        <Typography
          component="li"
          variant="body2"
          fontSize={14}
          fontWeight={600}
          display="inline-flex"
          justifyContent="space-between"
          gap={2}
        >
          Average query duration
          <ArrowUpwardIcon fontSize="small" color="error" />
        </Typography>
        <Typography
          component="li"
          variant="body2"
          fontSize={14}
          fontWeight={600}
          display="inline-flex"
          justifyContent="space-between"
          gap={2}
        >
          Failed SQL
          <ArrowUpwardIcon fontSize="small" color="error" />
        </Typography>
      </Stack> */}
    </Box>
  </AnimationVerticleWrapper>
);
