import EventIcon from "@mui/icons-material/Event";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import {
  Accordion,
  AccordionDetails,
  AccordionSummary,
  Chip,
  List,
  ListItem,
  ListItemButton,
  ListItemText,
  Paper,
  Typography
} from "@mui/material";
import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";

import { fetchUpcomingDeadlines } from "../api/contracts";
import PageHeader from "../components/PageHeader";
import { UpcomingDeadline } from "../types";
import { formatDate } from "../utils/date";

const UNKNOWN_MONTH_KEY = "__unknown__";

function groupByMonth(deadlines: UpcomingDeadline[], unknownKey: string) {
  const groups = new Map<string, UpcomingDeadline[]>();
  deadlines.forEach((deadline) => {
    const month = deadline.terminationDeadline?.slice(0, 7) ?? unknownKey;
    if (!groups.has(month)) {
      groups.set(month, []);
    }
    groups.get(month)!.push(deadline);
  });
  return Array.from(groups.entries())
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([month, items]) => ({
      month,
      items: items.sort((a, b) => (a.terminationDeadline ?? "").localeCompare(b.terminationDeadline ?? ""))
    }));
}

export default function CalendarView() {
  const { data, isLoading } = useQuery({
    queryKey: ["deadlines", "calendar"],
    queryFn: () => fetchUpcomingDeadlines(365)
  });

  const groups = useMemo(() => {
    if (!data || !Array.isArray(data)) return [] as ReturnType<typeof groupByMonth>;
    return groupByMonth(data, UNKNOWN_MONTH_KEY);
  }, [data]);

  const navigate = useNavigate();
  const { t, i18n } = useTranslation();

  return (
    <>
      <PageHeader
        title={t("calendar.title")}
        subtitle={t("calendar.subtitle")}
      />

      <Paper variant="outlined" sx={{ borderRadius: 3 }}>
        {isLoading ? (
          <Typography sx={{ p: 3 }}>{t("calendar.loading")}</Typography>
        ) : groups.length === 0 ? (
          <Typography sx={{ p: 3 }} color="text.secondary">
            {t("calendar.none")}
          </Typography>
        ) : (
          groups.map(({ month, items }) => (
            <Accordion key={month} defaultExpanded>
              <AccordionSummary expandIcon={<ExpandMoreIcon />}>
                <Typography variant="subtitle1" fontWeight={600} display="flex" alignItems="center" gap={1}>
                  <EventIcon fontSize="small" />
                  {formatMonth(month, i18n.language, t("calendar.unknownMonth"))}
                </Typography>
                <Chip
                  label={t("calendar.deadlineCount", { count: items.length })}
                  size="small"
                  color="primary"
                  sx={{ ml: 2 }}
                />
              </AccordionSummary>
              <AccordionDetails>
                <List>
                  {items.map((deadline) => (
                    <ListItem
                      key={`${month}-${deadline.id}`}
                      disablePadding
                      secondaryAction={
                        deadline.daysUntilDeadline != null ? (
                          <Chip
                            label={t("deadlineList.daysLabel", { count: deadline.daysUntilDeadline })}
                            color={
                              deadline.daysUntilDeadline <= 7
                                ? "error"
                                : deadline.daysUntilDeadline <= 21
                                  ? "warning"
                                  : "default"
                            }
                            variant="outlined"
                          />
                        ) : undefined
                      }
                    >
                      <ListItemButton onClick={() => navigate(`/contracts/${deadline.id}`)}>
                        <ListItemText
                          primary={deadline.title}
                          secondary={
                            <>
                              {t("deadlineList.terminateBy", {
                                date: formatDate(deadline.terminationDeadline)
                              })}
                              {deadline.contractEndDate
                                ? ` • ${t("deadlineList.contractEnds", {
                                    date: formatDate(deadline.contractEndDate)
                                  })}`
                                : ""}
                            </>
                          }
                          primaryTypographyProps={{ fontWeight: 600 }}
                        />
                      </ListItemButton>
                    </ListItem>
                  ))}
                </List>
              </AccordionDetails>
            </Accordion>
          ))
        )}
      </Paper>
    </>
  );
}

function formatMonth(month: string, locale: string, unknownLabel: string): string {
  if (month === UNKNOWN_MONTH_KEY) return unknownLabel;
  const [year, monthNumber] = month.split("-");
  const date = new Date(Number(year), Number(monthNumber) - 1);
  return new Intl.DateTimeFormat(locale.startsWith("de") ? "de-DE" : "en-US", {
    month: "long",
    year: "numeric"
  }).format(date);
}
