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;
  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,
  calculateTime = false,
  conversionValue,
}: GeneralItemsProps) => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down(700));
  const statiscticsResult = Boolean(calculateTime || conversionValue);

  const data = Object.entries(general).sort(
    ([nextValue], [currentValue]) => Number(nextValue) - Number(currentValue),
  );
  const days = data.map(([value]) => value);

  const numberValue = calculateTime
    ? Object.values(general).reduce((total, value) => total + value, 0) / Object.values(general).length
    : conversionValue
      ? conversionValue
      : Object.values(general).reduce((total, item) => total + item, 0);

  if (
    Object.keys(general).length === 0 ||
    Object.values(general).every((item) => item === 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 ?? 0)} с`
          : `${conversionValue ? numberValue?.toFixed(2) : numberValue} ${conversionValue ? "%" : ""}`}
      </Typography>
      <LineChart
        xAxis={[
          {
            data: Object.keys(general),
            valueFormatter: (value) => {
              const timestamp = Number(value);
              if (isNaN(timestamp)) return 'Invalid Date';
              return moment.unix(timestamp).format("DD/MM/YYYY");
            },
          },
        ]}
        series={[
          {
            data: Object.values(general),
            valueFormatter: (value) =>
              calculateTime
                ? getCalculatedTime(value)
                : statiscticsResult
                  ? String((value * 100).toFixed(2)) + "%"
                  : String(value.toFixed(2)),
          },
        ]}
        // dataset={Object.entries(general).map(([, v]) => moment.unix(v).format("ss:mm:HH")).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})}
        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) => {
        const keyTimestamp = Number(key);
        const todayStart = moment().startOf('day').unix();
        const todayEnd = moment().endOf('day').unix();
        
        // Включаем данные за сегодня и прошлые дни, исключаем будущие дни
        if (keyTimestamp >= todayStart && keyTimestamp <= todayEnd) {
          // Сегодняшний день - включаем
          return { ...totalValue, [key]: values[key] };
        } else if (keyTimestamp < todayStart) {
          // Прошлые дни - включаем
          return { ...totalValue, [key]: values[key] };
        } else {
          // Будущие дни - исключаем
          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="Открыли квиз"
          general={generalResponse.Open}
          color="#61BB1A"
          day={day}
        />
        <GeneralItem
          title="Получено заявок"
          general={generalResponse.Result}
          color="#7E2AEA"
          day={day}
        />
        <GeneralItem
          title="Конверсия"
          conversionValue={conversionValue}
          general={generalResponse.Conversion}
          color="#FB5607"
          day={day}
        />
        <GeneralItem
          title="Среднее время прохождения квиза"
          calculateTime
          general={generalResponse.AvTime}
          color="#0886FB"
          day={day}
        />
      </Box>
    </Box>
  );
};
