import moment from "moment";
import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material";
import { LineChart } from "@mui/x-charts";

import type { FC } from "react";
import type { GeneralResponse } from "@api/statistic";

type GeneralItemsProps = {
  title: string;
  general: Record<string, number>;
  color: string;
  numberType: "sum" | "percent" | "time";
  calculateTime?: boolean;
  conversionValue?: number;
  day: boolean;
};

type GeneralProps = {
  data: GeneralResponse | null;
  day: boolean;
};

const getCalculatedTime = (time: number) => {
  const hours = String(Math.floor(time / 3600)).padStart(2, "0");
  const minutes = String(Math.floor((time % 3600) / 60)).padStart(2, "0");
  const seconds = String(Math.floor((time % 3600) % 60)).padStart(2, "0");

  return `${hours}:${minutes}:${seconds}`;
};

const GeneralItem = ({
  title,
  general,
  color,
  numberType,
  calculateTime = false,
  conversionValue,
  day,
}: GeneralItemsProps) => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down(700));

  const numberValue =
    numberType === "sum"
      ? Object.values(general).reduce((total, item) => total + item, 0)
      : title === "Конверсия"
        ? conversionValue
        : 0;

  if (
    Object.keys(general).length === 0 ||
    Object.values(general).every((x) => x === 0)
  ) {
    return (
      <Typography textAlign="center">{`${title} - нет данных`}</Typography>
    );
  }

  const getCalculatedTime = (time: number) => {
    const hours = String(Math.floor(time / 3600)).padStart(2, "0");
    const minutes = String(Math.floor((time % 3600) / 60)).padStart(2, "0");
    const seconds = String(Math.floor((time % 3600) % 60)).padStart(2, "0");

    return `${hours}:${minutes}:${seconds}`;
  };

  return (
    <Paper
      sx={{
        overflow: "hidden",
        borderRadius: "12px",
        boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
      }}
    >
      <Typography sx={{ margin: "20px 20px 0" }}>{title}</Typography>
      <Typography sx={{ margin: "10px 20px 0", fontWeight: "bold" }}>
        {numberType === "percent" ? `${numberValue?.toFixed(2)}%` : numberValue}
      </Typography>
      <LineChart
        xAxis={[
          {
            data: Object.keys(general),
            valueFormatter: (value) =>
              moment.unix(Number(value)).format("DD/MM/YYYY HH") + "ч",
          },
        ]}
        series={[
          {
            data: Object.values(general),
            valueFormatter: (value) =>
              calculateTime
                ? getCalculatedTime(value)
                : String(value.toFixed(2)),
          },
        ]}
        height={220}
        colors={[color]}
        sx={{
          transform: isMobile ? "scale(1.1)" : "scale(1.2)",
          "& .MuiChartsAxis-tickContainer": { display: "none" },
        }}
      />
    </Paper>
  );
};

const GeneralItemTimeConv = ({
  title,
  general,
  color,
  numberType,
  calculateTime = false,
  conversionValue,
}: GeneralItemsProps) => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down(700));

  const data = Object.entries(general).sort((a, b) => a[0] - b[0]);

  const days = [...data].map((e) => e[0]);

  let buffer = 0;

  const time = [...data].map((e) => {
    if (e[1] > 0) {
      buffer = e[1];
    }
    return buffer;
  });

  console.log("data", data);
  console.log(
    "time",
    time.reduce((a, b) => Number(a) + Number(b), 0),
  );
  console.log(
    "time",
    getCalculatedTime(time.reduce((a, b) => Number(a) + Number(b), 0)),
  );
  console.log("days", days.length);
  const numberValue = calculateTime
    ? time.reduce((a, b) => Number(a) + Number(b), 0) / days.length || 0
    : conversionValue;

  if (
    Object.keys(general).length === 0 ||
    Object.values(general).every((x) => x === 0)
  ) {
    return (
      <Typography textAlign="center">{`${title} - нет данных`}</Typography>
    );
  }

  return (
    <Paper
      sx={{
        overflow: "hidden",
        borderRadius: "12px",
        boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
      }}
    >
      <Typography sx={{ margin: "20px 20px 0" }}>{title}</Typography>
      <Typography sx={{ margin: "10px 20px 0", fontWeight: "bold" }}>
        {calculateTime
          ? `${getCalculatedTime(numberValue)} с`
          : `${numberValue.toFixed(2)}%`}
      </Typography>
      <LineChart
        xAxis={[
          {
            data: days,
            valueFormatter: (value) =>
              moment.utc(Number(value) * 1000).format("DD/MM/YYYY"),
          },
        ]}
        series={[
          {
            data: Object.values(time),
            valueFormatter: (value) => {
              console.log("log", value);
              return calculateTime
                ? getCalculatedTime(value)
                : String((value * 100).toFixed(2)) + "%";
            },
          },
        ]}
        height={220}
        colors={[color]}
        sx={{
          transform: isMobile ? "scale(1.1)" : "scale(1.2)",
          "& .MuiChartsAxis-tickContainer": { display: "none" },
        }}
      />
    </Paper>
  );
};

export const General: FC<GeneralProps> = ({ data, day }) => {
  const theme = useTheme();
  const isTablet = useMediaQuery(theme.breakpoints.down(1000));
  const isMobile = useMediaQuery(theme.breakpoints.down(700));

  if (!data) {
    return (
      <Typography textAlign="center" m="10px 0">
        нет данных о ключевых метриках
      </Typography>
    );
  }

  const currentDate = moment().unix();

  const generalResponse = Object.entries(data).reduce(
    (total, [fatherKey, values]) => {
      const value = Object.keys(values).reduce((totalValue, key) => {
        if (Number(key) - currentDate < 0) {
          return { ...totalValue, [key]: values[key] };
        }

        return totalValue;
      }, {});

      return { ...total, [fatherKey]: value };
    },
    {} as GeneralResponse,
  );

  const resultSum = Object.values(generalResponse.Result).reduce(
    (total, item) => total + item,
    0,
  );
  const openSum = Object.values(generalResponse.Open).reduce(
    (total, item) => total + item,
    0,
  );
  const conversionValue = (resultSum / openSum) * 100;

  return (
    <Box sx={{ marginTop: "45px" }}>
      <Typography
        component="h3"
        sx={{
          fontSize: "24px",
          fontWeight: "bold",
          color: theme.palette.text.primary,
        }}
      >
        Ключевые метрики
      </Typography>
      <Box
        sx={{
          display: "grid",
          gridTemplateColumns: isTablet
            ? isMobile
              ? "1fr"
              : "1fr 1fr"
            : "1fr 1fr 1fr",
          gap: "20px",
          marginTop: "40px",
        }}
      >
        <GeneralItem
          title="Открыли квиз"
          numberType="sum"
          general={generalResponse.Open}
          color="#61BB1A"
          day={day}
        />
        <GeneralItem
          title="Получено заявок"
          numberType="sum"
          general={generalResponse.Result}
          color="#7E2AEA"
          day={day}
        />
        <GeneralItemTimeConv
          title="Конверсия"
          numberType="percent"
          conversionValue={conversionValue}
          general={generalResponse.Conversion}
          color="#FB5607"
          day={day}
        />
        <GeneralItemTimeConv
          title="Среднее время прохождения квиза"
          numberType="time"
          calculateTime
          general={generalResponse.AvTime}
          color="#0886FB"
          day={day}
        />
      </Box>
    </Box>
  );
};
