import Giscus from "@giscus/react";
import { GitHub } from "@mui/icons-material";
import {
  Avatar,
  Box,
  Container,
  Divider,
  List,
  ListItem,
  ListItemAvatar,
  ListItemButton,
  ListItemIcon,
  ListItemText,
  Paper,
  Skeleton,
  styled,
  Typography,
} from "@mui/material";
import { blue, green, red, yellow } from "@mui/material/colors";
import Grid from "@mui/material/Grid";
import { useTheme } from "@mui/material/styles";
import dayjs from "dayjs";
import i18next from "i18next";
import { useCallback, useEffect, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { CSSTransition, SwitchTransition } from "react-transition-group";
import { CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
import { getDashboardSummary } from "../../../api/api.ts";
import { HomepageSummary } from "../../../api/dashboard.ts";
import { useAppDispatch } from "../../../redux/hooks.ts";
import FacebookCircularProgress from "../../Common/CircularProgress.tsx";
import { SecondaryButton, SquareChip } from "../../Common/StyledComponents.tsx";
import TimeBadge from "../../Common/TimeBadge.tsx";
import Book from "../../Icons/Book.tsx";
import BoxMultipleFilled from "../../Icons/BoxMultipleFilled.tsx";
import Discord from "../../Icons/Discord.tsx";
import DocumentCopyFilled from "../../Icons/DocumentCopyFilled.tsx";
import HomeIcon from "../../Icons/Home.tsx";
import OpenFilled from "../../Icons/OpenFilled.tsx";
import PeopleFilled from "../../Icons/PeopleFilled.tsx";
import ShareFilled from "../../Icons/ShareFilled.tsx";
import SparkleFilled from "../../Icons/SparkleFilled.tsx";
import Telegram from "../../Icons/Telegram.tsx";
import PageContainer from "../../Pages/PageContainer.tsx";
import PageHeader from "../../Pages/PageHeader.tsx";
import ProDialog from "../../Admin/Common/ProDialog.tsx";
import SiteUrlWarning from "./SiteUrlWarning.tsx";
import CommentMultiple from "../../Icons/CommentMultiple.tsx";
import LinearProgress from "@mui/material/LinearProgress";

const StyledPaper = styled(Paper)(({ theme }) => ({
  padding: theme.spacing(3),
  boxShadow: "initial",
  border: "1px solid " + theme.palette.divider,
}));

const StyledListItemIcon = styled(ListItemIcon)(() => ({
  minWidth: 0,
}));

const Home = () => {
  const { t } = useTranslation("dashboard");
  const theme = useTheme();
  const dispatch = useAppDispatch();
  const [summary, setSummary] = useState<HomepageSummary | undefined>();
  const [chartLoading, setChartLoading] = useState(false);
  const [siteUrlWarning, setSiteUrlWarning] = useState(false);
  const [proDialogOpen, setProDialogOpen] = useState(false);
  useEffect(() => {
    loadSummary(false);
  }, []);

  const loadSummary = useCallback((loadChart?: boolean) => {
    if (loadChart) {
      setChartLoading(true);
    }
    dispatch(getDashboardSummary(loadChart))
      .then((r) => {
        setSummary(r);
        if (!loadChart) {
          const target = r.site_urls.find((site) => site == window.location.origin);
          if (!target) {
            setSiteUrlWarning(true);
          }
        }
      })
      .finally(() => {
        setChartLoading(false);
      });
  }, []);

  return (
    <PageContainer>
      <ProDialog open={proDialogOpen} onClose={() => setProDialogOpen(false)} />
      <SiteUrlWarning
        open={siteUrlWarning}
        onClose={() => setSiteUrlWarning(false)}
        existingUrls={summary?.site_urls ?? []}
      />
      <Container maxWidth="xl">
        <PageHeader title={t("nav.summary")} />
        <Grid container spacing={3}>
          <Grid alignContent={"stretch"} item xs={12} md={8} lg={9}>
            <StyledPaper>
              <Typography
                variant={"subtitle1"}
                fontWeight={500}
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                }}
              >
                {t("summary.trend")}
                <Typography variant={"body2"} color={"text.secondary"}>
                  {summary?.metrics_summary?.generated_at && (
                    <Trans
                      i18nKey={"summary.generatedAt"}
                      ns={"dashboard"}
                      components={[<TimeBadge datetime={summary?.metrics_summary?.generated_at} variant={"inherit"} />]}
                    />
                  )}
                </Typography>
              </Typography>
              <Divider sx={{ mb: 2, mt: 1 }} />
              <SwitchTransition>
                <CSSTransition
                  addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
                  classNames="fade"
                  key={`${!!summary?.metrics_summary}-${!!chartLoading}`}
                >
                  <Box>
                    {summary?.metrics_summary && (
                      <ResponsiveContainer width="100%" height={300}>
                        <LineChart
                          height={350}
                          data={summary?.metrics_summary.dates.map((i, d) => ({
                            name: dayjs(i).format("MM-DD"),
                            user: summary?.metrics_summary?.users[d] ?? 0,
                            file: summary?.metrics_summary?.files[d] ?? 0,
                            share: summary?.metrics_summary?.shares[d] ?? 0,
                          }))}
                        >
                          <CartesianGrid strokeDasharray="3 3" />
                          <XAxis dataKey="name" />
                          <YAxis
                            allowDecimals={false}
                            width={(() => {
                              const yAxisValue = [
                                ...(summary?.metrics_summary?.users ?? []),
                                ...(summary?.metrics_summary?.files ?? []),
                                ...(summary?.metrics_summary?.shares ?? []),
                              ];
                              const yAxisUpperLimit = yAxisValue.length ? Math.max(...yAxisValue) / 0.8 - 1 : 0;
                              const yAxisDigits = yAxisUpperLimit > 1 ? Math.floor(Math.log10(yAxisUpperLimit)) + 1 : 1;
                              return 3 + yAxisDigits * 9;
                            })()}
                          />
                          <Tooltip />
                          <Legend />
                          <Line name={t("nav.users")} type="monotone" dataKey="user" stroke={blue[600]} />
                          <Line name={t("nav.files")} type="monotone" dataKey="file" stroke={yellow[800]} />
                          <Line name={t("nav.shares")} type="monotone" dataKey="share" stroke={green[800]} />
                        </LineChart>
                      </ResponsiveContainer>
                    )}
                    {chartLoading && (
                      <Box
                        sx={{
                          height: "300px",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                        }}
                      >
                        <FacebookCircularProgress />
                      </Box>
                    )}
                    {!summary?.metrics_summary?.generated_at && !chartLoading && (
                      <Box
                        sx={{
                          height: "300px",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                        }}
                      >
                        <SecondaryButton onClick={() => loadSummary(true)}>
                          {t("application:fileManager.calculate")}
                        </SecondaryButton>
                      </Box>
                    )}
                  </Box>
                </CSSTransition>
              </SwitchTransition>
            </StyledPaper>
          </Grid>
          <Grid item xs={12} md={4} lg={3}>
            <StyledPaper>
              <Typography variant={"subtitle1"} fontWeight={500}>
                {t("summary.summary")}
              </Typography>
              <Divider sx={{ mb: 2, mt: 1 }} />
              <SwitchTransition>
                <CSSTransition
                  addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
                  classNames="fade"
                  key={`${!!summary?.metrics_summary}-${chartLoading}`}
                >
                  <Box>
                    {summary?.metrics_summary && (
                      <List disablePadding sx={{ minHeight: "300px" }}>
                        <ListItem>
                          <ListItemAvatar>
                            <Avatar
                              sx={{
                                backgroundColor: blue[100],
                                color: blue[600],
                              }}
                            >
                              <PeopleFilled />
                            </Avatar>
                          </ListItemAvatar>
                          <ListItemText
                            secondary={t("summary.totalUsers")}
                            primary={summary.metrics_summary.user_total.toLocaleString()}
                          />
                        </ListItem>
                        <ListItem>
                          <ListItemAvatar>
                            <Avatar
                              sx={{
                                backgroundColor: yellow[100],
                                color: yellow[800],
                              }}
                            >
                              <DocumentCopyFilled />
                            </Avatar>
                          </ListItemAvatar>
                          <ListItemText
                            secondary={t("summary.totalFilesAndFolders")}
                            primary={summary.metrics_summary.file_total.toLocaleString()}
                          />
                        </ListItem>
                        <ListItem>
                          <ListItemAvatar>
                            <Avatar
                              sx={{
                                backgroundColor: green[100],
                                color: green[800],
                              }}
                            >
                              <ShareFilled />
                            </Avatar>
                          </ListItemAvatar>
                          <ListItemText
                            secondary={t("summary.shareLinks")}
                            primary={summary.metrics_summary.share_total.toLocaleString()}
                          />
                        </ListItem>
                        <ListItem>
                          <ListItemAvatar>
                            <Avatar
                              sx={{
                                backgroundColor: red[100],
                                color: red[800],
                              }}
                            >
                              <BoxMultipleFilled />
                            </Avatar>
                          </ListItemAvatar>
                          <ListItemText
                            secondary={t("summary.totalBlobs")}
                            primary={summary.metrics_summary.entities_total.toLocaleString()}
                          />
                        </ListItem>
                      </List>
                    )}
                    {chartLoading && (
                      <Box
                        sx={{
                          height: "300px",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                        }}
                      >
                        <FacebookCircularProgress />
                      </Box>
                    )}
                    {!summary?.metrics_summary?.generated_at && !chartLoading && (
                      <Box
                        sx={{
                          height: "300px",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                        }}
                      >
                        <SecondaryButton onClick={() => loadSummary(true)}>
                          {t("application:fileManager.calculate")}
                        </SecondaryButton>
                      </Box>
                    )}
                  </Box>
                </CSSTransition>
              </SwitchTransition>
            </StyledPaper>
          </Grid>
          <Grid item xs={12}>
            <StyledPaper>
              <Typography variant="subtitle1" fontWeight={500}>
                {t("summary.storagePolicies")}
              </Typography>
              <Divider sx={{ mb: 2, mt: 1 }} />
              <Box>
                {summary?.storage_policies && summary.storage_policies.length > 0 ? (
                  <Box sx={{ gap: 3, display: "flex", flexDirection: "column" }}>
                    {summary.storage_policies.map((policy) => {
                      const percentage = policy.total > 0 ? (policy.used / policy.total) * 100 : 0;
                      const formatSize = (bytes: number) => {
                        if (bytes === 0) return "0 B";
                        const k = 1024;
                        const sizes = ["B", "KB", "MB", "GB", "TB", "PB"];
                        const i = Math.floor(Math.log(bytes) / Math.log(k));
                        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
                      };

                      return (
                        <Box key={policy.id}>
                          <Box sx={{ display: "flex", justifyContent: "space-between", mb: 0.5 }}>
                            <Typography variant="subtitle2">{policy.name}</Typography>
                            <Typography variant="caption" color="text.secondary">
                              {formatSize(policy.used)} / {formatSize(policy.total)}
                            </Typography>
                          </Box>
                          <Box sx={{ display: "flex", justifyContent: "space-between", mb: 1 }}>
                            <Typography variant="caption" color="text.secondary">
                              {policy.type}
                            </Typography>
                            <Typography variant="caption" color="text.secondary">
                              {percentage.toFixed(1)}%
                            </Typography>
                          </Box>
                          <LinearProgress
                            variant="determinate"
                            value={percentage}
                            sx={{
                              height: 8,
                              borderRadius: 4,
                              backgroundColor: theme.palette.divider,
                              "& .MuiLinearProgress-bar": {
                                borderRadius: 4,
                                backgroundColor:
                                  percentage > 90 ? red[500] : percentage > 70 ? yellow[500] : green[500],
                              },
                            }}
                          />
                        </Box>
                      );
                    })}
                  </Box>
                ) : (
                  <Box sx={{ py: 2, textAlign: "center", color: "text.secondary" }}>
                    {t("summary.noStoragePolicies")}
                  </Box>
                )}
              </Box>
            </StyledPaper>
          </Grid>
          <Grid item xs={12} md={5} lg={4}>
            <StyledPaper sx={{ p: 0 }}>
              <Box sx={{ p: 3, display: "flex", alignItems: "center" }}>
                <Box component={"img"} sx={{ width: 70 }} alt="cloudreve" src={"/static/img/cloudreve.svg"} />
                <Box sx={{ ml: 2 }}>
                  <Typography variant={"h5"} fontWeight={600}>
                    Cloudreve
                    {summary && summary.version.pro && (
                      <SquareChip sx={{ ml: 1, height: "initial" }} size={"small"} color={"primary"} label={"Pro"} />
                    )}
                  </Typography>
                  <Typography variant={"subtitle2"} color={"text.secondary"}>
                    {summary ? summary.version.version : <Skeleton variant={"text"} width={70} />}
                    {summary && (
                      <Box component={"span"} sx={{ ml: 1, color: (t) => t.palette.action.disabled }}>
                        #{summary.version.commit}
                      </Box>
                    )}
                  </Typography>
                </Box>
              </Box>
              <Divider />
              <List component="nav" aria-label="main mailbox folders" sx={{ mx: 2 }}>
                <ListItemButton onClick={() => window.open("https://cloudreve.org")}>
                  <ListItemIcon>
                    <HomeIcon />
                  </ListItemIcon>
                  <ListItemText primary={t("summary.homepage")} />
                  <StyledListItemIcon>
                    <OpenFilled />
                  </StyledListItemIcon>
                </ListItemButton>
                <ListItemButton onClick={() => window.open("https://github.com/cloudreve/cloudreve")}>
                  <ListItemIcon>
                    <GitHub />
                  </ListItemIcon>
                  <ListItemText primary={t("summary.github")} />
                  <StyledListItemIcon>
                    <OpenFilled />
                  </StyledListItemIcon>
                </ListItemButton>
                <ListItemButton onClick={() => window.open("https://docs.cloudreve.org/")}>
                  <ListItemIcon>
                    <Book />
                  </ListItemIcon>
                  <ListItemText primary={t("summary.documents")} />
                  <StyledListItemIcon>
                    <OpenFilled />
                  </StyledListItemIcon>
                </ListItemButton>
                <ListItemButton onClick={() => window.open("https://discord.gg/WTpMFpZT76")}>
                  <ListItemIcon>
                    <Discord />
                  </ListItemIcon>
                  <ListItemText primary={t("summary.discordCommunity")} />
                  <StyledListItemIcon>
                    <OpenFilled />
                  </StyledListItemIcon>
                </ListItemButton>
                <ListItemButton onClick={() => window.open("https://t.me/cloudreve_official")}>
                  <ListItemIcon>
                    <Telegram />
                  </ListItemIcon>
                  <ListItemText primary={t("summary.telegram")} />
                  <StyledListItemIcon>
                    <OpenFilled />
                  </StyledListItemIcon>
                </ListItemButton>
                <ListItemButton onClick={() => window.open("https://github.com/cloudreve/cloudreve/discussions")}>
                  <ListItemIcon>
                    <CommentMultiple />
                  </ListItemIcon>
                  <ListItemText primary={t("summary.forum")} />
                  <StyledListItemIcon>
                    <OpenFilled />
                  </StyledListItemIcon>
                </ListItemButton>
                {summary && !summary.version.pro && (
                  <ListItemButton onClick={() => setProDialogOpen(true)}>
                    <ListItemIcon>
                      <SparkleFilled color={"primary"} />
                    </ListItemIcon>
                    <ListItemText primary={t("summary.buyPro")} />
                  </ListItemButton>
                )}
              </List>
              <Divider />
            </StyledPaper>
          </Grid>
          <Grid item xs={12} md={7} lg={8}>
            <StyledPaper>
              <Typography variant={"subtitle1"} fontWeight={500}>
                公告
              </Typography>
              <Divider sx={{ mb: 2, mt: 1 }} />
              <Giscus
                id="comments"
                repo="cloudreve/cloudreve"
                repoId="MDEwOlJlcG9zaXRvcnkxMjAxNTYwNzY="
                mapping={"number"}
                term={i18next.language == "zh-CN" ? "2170" : "2169"}
                reactionsEnabled={"1"}
                emitMetadata={"0"}
                inputPosition={"bottom"}
                theme={theme.palette.mode === "dark" ? "dark" : "light"}
                lang={i18next.language == "zh-CN" ? "zh-CN" : "en"}
                loading={"lazy"}
              />
            </StyledPaper>
          </Grid>
        </Grid>
      </Container>
    </PageContainer>
  );
};

export default Home;
