"use client";

import {
  useMemo,
  useState,
  type MouseEvent,
} from "react";

import CheckBoxOutlineBlankRoundedIcon from "@mui/icons-material/CheckBoxOutlineBlankRounded";
import CheckBoxRoundedIcon from "@mui/icons-material/CheckBoxRounded";
import ExpandMoreRoundedIcon from "@mui/icons-material/ExpandMoreRounded";
import KeyboardArrowDownRoundedIcon from "@mui/icons-material/KeyboardArrowDownRounded";
import KeyboardArrowUpRoundedIcon from "@mui/icons-material/KeyboardArrowUpRounded";
import TuneRoundedIcon from "@mui/icons-material/TuneRounded";

import {
  Box,
  Button,
  Checkbox,
  Menu,
  MenuItem,
  Typography,
} from "@mui/material";
import {
  alpha,
  useTheme,
} from "@mui/material/styles";

import type { RgcDecisionLanguage } from "../data/rgc-decision-i18n";

export type RgcDecisionFilterState = {
  status: string[];
  primaryAgency: string[];
  category: string[];
  meetingDate: string[];
};

export type RgcDecisionFilterOptions = {
  status: string[];
  primaryAgency: string[];
  category: string[];
  meetingDate: string[];
};

export const defaultRgcDecisionFilters: RgcDecisionFilterState = {
  status: [],
  primaryAgency: [],
  category: [],
  meetingDate: [],
};

type FilterKey = keyof RgcDecisionFilterState;

type RgcDecisionFiltersProps = {
  filters: RgcDecisionFilterState;
  options: RgcDecisionFilterOptions;
  language: RgcDecisionLanguage;

  onChange: (
    key: FilterKey,
    value: string[],
  ) => void;

  onReset: () => void;
};

type FilterButtonProps = {
  label: string;
  open: boolean;

  width: {
    xs: string;
    sm?: string;
    md?: string;
  };

  onClick: (
    event: MouseEvent<HTMLButtonElement>,
  ) => void;
};

type CheckboxOptionProps = {
  label: string;
  checked: boolean;
  onClick: () => void;
};

const FILTER_ORDER: FilterKey[] = [
  "status",
  "primaryAgency",
  "category",
  "meetingDate",
];

const ENGLISH_MONTHS = [
  "Jan",
  "Feb",
  "Mar",
  "Apr",
  "May",
  "Jun",
  "Jul",
  "Aug",
  "Sep",
  "Oct",
  "Nov",
  "Dec",
] as const;

function normalizeMeetingMonth(
  value: string | null | undefined,
): string {
  const match = /^(\d{4})-(\d{2})/.exec(
    String(value ?? "").trim(),
  );

  if (!match) {
    return "";
  }

  const year = Number(match[1]);
  const month = Number(match[2]);

  if (
    !Number.isInteger(year) ||
    month < 1 ||
    month > 12
  ) {
    return "";
  }

  return `${year}-${String(month).padStart(
    2,
    "0",
  )}`;
}

function parseMeetingMonth(
  value: string | null | undefined,
): {
  year: number;
  monthIndex: number;
} {
  const normalized =
    normalizeMeetingMonth(value);

  if (normalized) {
    const [year, month] =
      normalized.split("-");

    return {
      year: Number(year),
      monthIndex: Number(month) - 1,
    };
  }

  const now = new Date();

  return {
    year: now.getFullYear(),
    monthIndex: now.getMonth(),
  };
}

function buildMeetingMonth(
  year: number,
  monthIndex: number,
): string {
  return `${year}-${String(
    monthIndex + 1,
  ).padStart(2, "0")}`;
}

function getMonthLabel(
  monthIndex: number,
  language: RgcDecisionLanguage,
): string {
  if (language !== "kh") {
    return ENGLISH_MONTHS[monthIndex];
  }

  return new Intl.DateTimeFormat(
    "km-KH",
    {
      month: "short",
    },
  ).format(
    new Date(2026, monthIndex, 1),
  );
}

function formatMeetingMonth(
  value: string,
  language: RgcDecisionLanguage,
): string {
  const parsed =
    parseMeetingMonth(value);

  return `${getMonthLabel(
    parsed.monthIndex,
    language,
  )} ${parsed.year}`;
}

function FilterButton({
  label,
  open,
  width,
  onClick,
}: FilterButtonProps) {
  const theme = useTheme();
  const isDark =
    theme.palette.mode === "dark";

  return (
    <Button
      type="button"
      variant="outlined"
      onClick={onClick}
      endIcon={
        <ExpandMoreRoundedIcon
          sx={{
            fontSize: 18,

            transform: open
              ? "rotate(180deg)"
              : "rotate(0deg)",

            transition:
              "transform 160ms ease",
          }}
        />
      }
      sx={{
        width,
        height: 40,
        minWidth: 0,
        flexShrink: 0,

        px: 1.5,
        borderRadius: "6px",

        color:
          theme.palette.text.secondary,

        borderColor: open
          ? theme.palette.primary.main
          : theme.palette.divider,

        bgcolor:
          theme.palette.background.paper,

        textTransform: "none",
        justifyContent: "space-between",

        fontSize: 13,
        fontWeight: 400,
        lineHeight: "20px",

        boxShadow: "none",

        "& .MuiButton-endIcon": {
          ml: 1,
          mr: 0,
          flexShrink: 0,

          color:
            theme.palette.text.secondary,
        },

        "&:hover": {
          borderColor:
            theme.palette.primary.main,

          bgcolor: isDark
            ? alpha(
                theme.palette.primary.main,
                0.1,
              )
            : theme.palette.background.paper,

          boxShadow: "none",
        },
      }}
    >
      <Box
        component="span"
        sx={{
          minWidth: 0,
          flex: 1,

          overflow: "hidden",
          textOverflow: "ellipsis",
          whiteSpace: "nowrap",

          textAlign: "left",
        }}
      >
        {label}
      </Box>
    </Button>
  );
}

function CheckboxOption({
  label,
  checked,
  onClick,
}: CheckboxOptionProps) {
  const theme = useTheme();
  const isDark =
    theme.palette.mode === "dark";

  return (
    <MenuItem
      onClick={onClick}
      disableRipple
      sx={{
        minHeight: 40,

        mx: 0.5,
        px: 1,
        py: 0.75,

        display: "flex",
        alignItems: "center",
        gap: 1,

        borderRadius: "5px",

        color:
          theme.palette.text.primary,

        "&:hover": {
          bgcolor: alpha(
            theme.palette.primary.main,
            isDark ? 0.16 : 0.07,
          ),
        },
      }}
    >
      <Checkbox
        checked={checked}
        disableRipple
        tabIndex={-1}
        icon={
          <CheckBoxOutlineBlankRoundedIcon
            sx={{
              fontSize: 19,
            }}
          />
        }
        checkedIcon={
          <CheckBoxRoundedIcon
            sx={{
              fontSize: 19,
            }}
          />
        }
        sx={{
          p: 0,

          color: isDark
            ? theme.palette.text.secondary
            : "#98A2B3",

          "&.Mui-checked": {
            color:
              theme.palette.primary.main,
          },
        }}
      />

      <Typography
        sx={{
          minWidth: 0,

          color:
            theme.palette.text.primary,

          fontSize: 13,
          fontWeight: 400,
          lineHeight: "20px",

          overflow: "hidden",
          textOverflow: "ellipsis",
          whiteSpace: "nowrap",
        }}
      >
        {label}
      </Typography>
    </MenuItem>
  );
}

function getButtonLabel({
  key,
  selectedValues,
  options,
  language,
}: {
  key: FilterKey;
  selectedValues: string[];
  options: string[];
  language: RgcDecisionLanguage;
}): string {
  const defaultLabels: Record<
    FilterKey,
    string
  > = {
    status:
      language === "kh"
        ? "ស្ថានភាព"
        : "Status",

    primaryAgency:
      language === "kh"
        ? "ស្ថាប័នទទួលបន្ទុក"
        : "Primary Agency",

    category:
      language === "kh"
        ? "ប្រភេទ"
        : "Category",

    meetingDate:
      language === "kh"
        ? "កាលបរិច្ឆេទប្រជុំ"
        : "Meeting Date",
  };

  if (selectedValues.length === 0) {
    return defaultLabels[key];
  }

  if (selectedValues.length === 1) {
    const selected =
      selectedValues[0];

    if (key === "meetingDate") {
      return formatMeetingMonth(
        selected,
        language,
      );
    }

    return selected;
  }

  const validSelectedCount =
    selectedValues.filter((value) =>
      options.includes(value),
    ).length;

  return `${defaultLabels[key]} (${
    validSelectedCount ||
    selectedValues.length
  })`;
}

export function RgcDecisionFilters({
  filters,
  options,
  language,
  onChange,
  onReset,
}: RgcDecisionFiltersProps) {
  const theme = useTheme();
  const isDark =
    theme.palette.mode === "dark";

  const [
    anchorEl,
    setAnchorEl,
  ] = useState<HTMLElement | null>(
    null,
  );

  const [
    activeFilter,
    setActiveFilter,
  ] = useState<FilterKey | null>(
    null,
  );

  const initialMeetingMonth =
    parseMeetingMonth(
      filters.meetingDate[0],
    );

  const [
    draftMonthIndex,
    setDraftMonthIndex,
  ] = useState(
    initialMeetingMonth.monthIndex,
  );

  const [
    draftYear,
    setDraftYear,
  ] = useState(
    initialMeetingMonth.year,
  );

  const openMenu = (
    key: FilterKey,
    event: MouseEvent<HTMLButtonElement>,
  ) => {
    if (key === "meetingDate") {
      const selected =
        parseMeetingMonth(
          filters.meetingDate[0],
        );

      setDraftMonthIndex(
        selected.monthIndex,
      );

      setDraftYear(selected.year);
    }

    setActiveFilter(key);
    setAnchorEl(event.currentTarget);
  };

  const closeMenu = () => {
    setAnchorEl(null);
    setActiveFilter(null);
  };

  const toggleOption = (
    key: FilterKey,
    option: string,
  ) => {
    const currentValues =
      filters[key] ?? [];

    const nextValues =
      currentValues.includes(option)
        ? currentValues.filter(
            (item) =>
              item !== option,
          )
        : [
            ...currentValues,
            option,
          ];

    onChange(key, nextValues);
  };

  const normalizedOptions =
    useMemo<RgcDecisionFilterOptions>(
      () => {
        const unique = (
          values: string[],
        ): string[] => {
          return Array.from(
            new Set(
              values
                .map((value) =>
                  value?.trim(),
                )
                .filter(
                  (
                    value,
                  ): value is string =>
                    Boolean(value),
                ),
            ),
          );
        };

        return {
          status: unique(
            options.status ?? [],
          ),

          primaryAgency: unique(
            options.primaryAgency ?? [],
          ).sort((a, b) =>
            a.localeCompare(b),
          ),

          category: unique(
            options.category ?? [],
          ).sort((a, b) =>
            a.localeCompare(b),
          ),

          meetingDate: unique(
            options.meetingDate ?? [],
          )
            .map(normalizeMeetingMonth)
            .filter(Boolean)
            .sort((a, b) =>
              b.localeCompare(a),
            ),
        };
      },
      [options],
    );

  const menuOptions =
    activeFilter &&
    activeFilter !== "meetingDate"
      ? normalizedOptions[
          activeFilter
        ]
      : [];

  const menuWidth =
    activeFilter === "status"
      ? 220
      : activeFilter ===
          "primaryAgency"
        ? 260
        : activeFilter ===
            "category"
          ? 260
          : 300;

  const selectedMeetingDate =
    filters.meetingDate[0] ?? "";

  return (
    <>
      <Box
        sx={{
          width: "100%",
          mb: 2.5,

          display: "flex",
          alignItems: "center",
          justifyContent:
            "space-between",
          gap: 2,
        }}
      >
        <Box
          sx={{
            minWidth: 0,
            flex: 1,

            display: "flex",
            alignItems: "center",
            gap: 2,

            overflowX: {
              xs: "auto",
              lg: "visible",
            },

            overflowY: "visible",

            pb: {
              xs: 0.5,
              lg: 0,
            },

            "&::-webkit-scrollbar": {
              height: 6,
            },

            "&::-webkit-scrollbar-track":
              {
                bgcolor:
                  "transparent",
              },

            "&::-webkit-scrollbar-thumb":
              {
                bgcolor: alpha(
                  theme.palette.text.secondary,
                  0.25,
                ),

                borderRadius: 999,
              },
          }}
        >
          {FILTER_ORDER.map((key) => {
            const selectedValues =
              filters[key] ?? [];

            const label =
              getButtonLabel({
                key,
                selectedValues,

                options:
                  normalizedOptions[key],

                language,
              });

            const width =
              key === "status"
                ? {
                    xs: "140px",
                    md: "140px",
                  }
                : key ===
                    "primaryAgency"
                  ? {
                      xs: "190px",
                      md: "190px",
                    }
                  : key ===
                      "category"
                    ? {
                        xs: "180px",
                        md: "180px",
                      }
                    : {
                        xs: "180px",
                        md: "180px",
                      };

            return (
              <FilterButton
                key={key}
                label={label}
                width={width}
                open={
                  activeFilter === key &&
                  Boolean(anchorEl)
                }
                onClick={(event) =>
                  openMenu(
                    key,
                    event,
                  )
                }
              />
            );
          })}
        </Box>

        <Button
          type="button"
          variant="outlined"
          endIcon={
            <TuneRoundedIcon
              sx={{
                fontSize: 18,
              }}
            />
          }
          onClick={() => {
            closeMenu();
            onReset();
          }}
          sx={{
            minWidth: 94,
            height: 40,
            px: 1.75,
            flexShrink: 0,

            borderRadius: "5px",

            borderColor: isDark
              ? "#53B1FD"
              : "#1570EF",

            color: isDark
              ? "#84CAFF"
              : "#1570EF",

            bgcolor: isDark
              ? theme.palette.background.paper
              : "#FFFFFF",

            fontSize: 12,
            fontWeight: 500,
            lineHeight: "18px",
            textTransform: "none",

            boxShadow: "none",

            "& .MuiButton-endIcon": {
              ml: 1,
              mr: 0,
            },

            "&:hover": {
              borderColor: isDark
                ? "#84CAFF"
                : "#175CD3",

              bgcolor: isDark
                ? "rgba(83, 177, 253, 0.08)"
                : "#EFF8FF",

              boxShadow: "none",
            },
          }}
        >
          {language === "kh"
            ? "កំណត់ឡើងវិញ"
            : "Reset"}
        </Button>
      </Box>

      <Menu
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={closeMenu}
        disableScrollLock
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "left",
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "left",
        }}
        slotProps={{
          paper: {
            sx: {
              width: menuWidth,
              maxWidth:
                "calc(100vw - 32px)",

              maxHeight:
                activeFilter ===
                "meetingDate"
                  ? 360
                  : 340,

              mt: 0.75,
              p:
                activeFilter ===
                "meetingDate"
                  ? 0
                  : 0.5,

              overflowY:
                activeFilter ===
                "meetingDate"
                  ? "hidden"
                  : "auto",

              borderRadius: "8px",

              border: `1px solid ${theme.palette.divider}`,

              bgcolor:
                theme.palette.background.paper,

              color:
                theme.palette.text.primary,

              boxShadow: isDark
                ? "0 18px 42px rgba(0,0,0,0.5)"
                : "0 14px 32px rgba(15,23,42,0.15)",

              "& .MuiMenu-list": {
                p: 0,
              },

              "&::-webkit-scrollbar": {
                width: 7,
              },

              "&::-webkit-scrollbar-track":
                {
                  bgcolor: isDark
                    ? alpha(
                        "#FFFFFF",
                        0.05,
                      )
                    : "#F2F4F7",
                },

              "&::-webkit-scrollbar-thumb":
                {
                  bgcolor: isDark
                    ? alpha(
                        "#FFFFFF",
                        0.22,
                      )
                    : "#98A2B3",

                  borderRadius: 99,
                },
            },
          },
        }}
      >
        {activeFilter ===
        "meetingDate" ? (
          <Box
            sx={{
              width: "100%",
              p: 2,
            }}
          >
            <Box
              sx={{
                display: "grid",
                gridTemplateColumns:
                  "1fr 1fr",
                gap: 2,
              }}
            >
              <Box
                sx={{
                  textAlign: "center",
                }}
              >
                <Button
                  type="button"
                  onClick={() => {
                    setDraftMonthIndex(
                      (current) =>
                        current === 0
                          ? 11
                          : current - 1,
                    );
                  }}
                  sx={{
                    minWidth: 36,
                    height: 34,
                    color:
                      theme.palette.primary.main,
                  }}
                >
                  <KeyboardArrowUpRoundedIcon />
                </Button>

                <Typography
                  sx={{
                    py: 1,
                    fontSize: 18,
                    fontWeight: 700,
                    lineHeight: 1.2,
                  }}
                >
                  {getMonthLabel(
                    draftMonthIndex,
                    language,
                  )}
                </Typography>

                <Button
                  type="button"
                  onClick={() => {
                    setDraftMonthIndex(
                      (current) =>
                        current === 11
                          ? 0
                          : current + 1,
                    );
                  }}
                  sx={{
                    minWidth: 36,
                    height: 34,
                    color:
                      theme.palette.primary.main,
                  }}
                >
                  <KeyboardArrowDownRoundedIcon />
                </Button>
              </Box>

              <Box
                sx={{
                  textAlign: "center",
                }}
              >
                <Button
                  type="button"
                  onClick={() => {
                    setDraftYear(
                      (current) =>
                        current + 1,
                    );
                  }}
                  sx={{
                    minWidth: 36,
                    height: 34,
                    color:
                      theme.palette.primary.main,
                  }}
                >
                  <KeyboardArrowUpRoundedIcon />
                </Button>

                <Typography
                  sx={{
                    py: 1,
                    fontSize: 18,
                    fontWeight: 700,
                    lineHeight: 1.2,
                  }}
                >
                  {draftYear}
                </Typography>

                <Button
                  type="button"
                  onClick={() => {
                    setDraftYear(
                      (current) =>
                        current - 1,
                    );
                  }}
                  sx={{
                    minWidth: 36,
                    height: 34,
                    color:
                      theme.palette.primary.main,
                  }}
                >
                  <KeyboardArrowDownRoundedIcon />
                </Button>
              </Box>
            </Box>

            <Box
              sx={{
                mt: 1.5,

                display: "flex",
                justifyContent:
                  "flex-end",
                alignItems: "center",
                gap: 1,
              }}
            >
              {selectedMeetingDate ? (
                <Button
                  type="button"
                  onClick={() => {
                    onChange(
                      "meetingDate",
                      [],
                    );

                    closeMenu();
                  }}
                  sx={{
                    minWidth: 64,
                    height: 40,

                    color:
                      theme.palette.text.secondary,

                    fontSize: 13,
                    fontWeight: 500,
                    textTransform: "none",
                  }}
                >
                  {language === "kh"
                    ? "សម្អាត"
                    : "Clear"}
                </Button>
              ) : null}

              <Button
                type="button"
                variant="contained"
                onClick={() => {
                  onChange(
                    "meetingDate",
                    [
                      buildMeetingMonth(
                        draftYear,
                        draftMonthIndex,
                      ),
                    ],
                  );

                  closeMenu();
                }}
                sx={{
                  minWidth: 84,
                  height: 40,

                  borderRadius: "5px",

                  fontSize: 13,
                  fontWeight: 600,
                  textTransform: "none",

                  boxShadow:
                    "0 2px 4px rgba(16,24,40,0.12)",

                  "&:hover": {
                    boxShadow:
                      "0 2px 4px rgba(16,24,40,0.16)",
                  },
                }}
              >
                {language === "kh"
                  ? "បង្ហាញ"
                  : "Show"}
              </Button>
            </Box>
          </Box>
        ) : menuOptions.length > 0 ? (
          menuOptions.map(
            (option) => {
              const checked =
                activeFilter !== null &&
                (
                  filters[
                    activeFilter
                  ] ?? []
                ).includes(option);

              return (
                <CheckboxOption
                  key={option}
                  label={option}
                  checked={checked}
                  onClick={() => {
                    if (!activeFilter) {
                      return;
                    }

                    toggleOption(
                      activeFilter,
                      option,
                    );
                  }}
                />
              );
            },
          )
        ) : (
          <MenuItem
            disabled
            sx={{
              minHeight: 42,
              fontSize: 13,
            }}
          >
            {language === "kh"
              ? "មិនមានទិន្នន័យ"
              : "No options found"}
          </MenuItem>
        )}
      </Menu>
    </>
  );
}

export default RgcDecisionFilters;