import Box from "@mui/material/Box";
import Checkbox from "@mui/material/Checkbox";
import FormControl from "@mui/material/FormControl";
import MenuItem from "@mui/material/MenuItem";
import OutlinedInput from "@mui/material/OutlinedInput";
import Select, { type SelectChangeEvent } from "@mui/material/Select";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import { ChevronDownSmallIcon } from "@/features/ministry/dashboard/components/dashboard-icons";
import { DashboardResetButton } from "@/features/ministry/dashboard/components/dashboard-reset-button";
import {
  agencyOptions,
  defaultWorkingGroupFilters,
  reportOptions,
  statusOptions,
  workingGroupOptions,
  type WorkingGroupOption,
  yearOptions,
  type WorkingGroupFiltersValue,
} from "@/features/ministry/dashboard/dashboard-data";

type WorkingGroupFilterSelectProps = {
  displayMode?: "count" | "join" | "single";
  label: string;
  multiple?: boolean;
  onChange: (value: string | string[]) => void;
  options: WorkingGroupOption[];
  value: string | string[];
  width: number;
};

type WorkingGroupFiltersProps = {
  filters: WorkingGroupFiltersValue;
  onFiltersChange: (filters: WorkingGroupFiltersValue) => void;
};

function WorkingGroupFilterSelect({
  displayMode = "single",
  label,
  multiple = false,
  onChange,
  options,
  value,
  width,
}: WorkingGroupFilterSelectProps) {
  const theme = useTheme();

  const renderValue = (selectedValue: unknown) => {
    if (multiple) {
      const selectedItems = Array.isArray(selectedValue)
        ? (selectedValue as string[])
        : [];

      if (selectedItems.length === 0) return label;
      if (displayMode === "count") return `${label} (${selectedItems.length})`;

      return options
        .filter((option) => selectedItems.includes(option.value))
        .map((option) => option.label)
        .join(", ");
    }

    const singleValue = String(selectedValue ?? "");
    if (!singleValue) return label;

    return options.find((option) => option.value === singleValue)?.label ?? label;
  };

  const handleChange = (event: SelectChangeEvent<string | string[]>) => {
    const nextValue = event.target.value;

    if (multiple) {
      onChange(Array.isArray(nextValue) ? nextValue : String(nextValue).split(","));
      return;
    }

    onChange(String(nextValue));
  };

  const selectedValues = Array.isArray(value) ? value : [];
  const hasValue = Array.isArray(value) ? value.length > 0 : Boolean(value);

  return (
    <FormControl size="small" sx={{ minWidth: width, flex: "0 0 auto" }}>
      <Select
        multiple={multiple}
        value={value}
        onChange={handleChange}
        displayEmpty
        input={<OutlinedInput notched={false} />}
        renderValue={renderValue}
        IconComponent={ChevronDownSmallIcon}
        MenuProps={{
          disableScrollLock: true,
          slotProps: {
            paper: {
              sx: {
                mt: 1,
                width: multiple ? 360 : width,
                maxWidth: "calc(100vw - 32px)",
                maxHeight: 290,
                borderRadius: "10px",
                border: `1px solid ${theme.palette.divider}`,
                backgroundColor: theme.palette.background.paper,
                boxShadow: "0 12px 30px rgba(15, 23, 42, 0.14)",
                overflowY: "auto",
                zIndex: 1500,

                "& .MuiMenuItem-root": {
                  minHeight: 34,
                  px: 1,
                  py: 0.5,
                  color: theme.palette.text.primary,
                },

                "& .MuiMenuItem-root.Mui-selected": {
                  backgroundColor: alpha(theme.palette.primary.main, 0.1),
                },

                "& .MuiMenuItem-root.Mui-selected:hover": {
                  backgroundColor: alpha(theme.palette.primary.main, 0.16),
                },
              },
            },
          },
        }}
        sx={{
          height: 34,
          bgcolor: theme.palette.background.paper,
          borderRadius: "6px",
          color: hasValue ? theme.palette.primary.main : theme.palette.text.secondary,
          fontSize: 12,
          fontWeight: 500,

          "& .MuiOutlinedInput-notchedOutline": {
            borderColor: hasValue ? theme.palette.primary.main : theme.palette.divider,
          },

          "&:hover .MuiOutlinedInput-notchedOutline": {
            borderColor: theme.palette.primary.main,
          },

          "&.Mui-focused .MuiOutlinedInput-notchedOutline": {
            borderColor: theme.palette.primary.main,
            borderWidth: 1,
          },

          "& .MuiSelect-select": {
            minHeight: "34px !important",
            display: "flex",
            alignItems: "center",
            py: 0,
            pl: 1.4,
            pr: 3.4,
            whiteSpace: "nowrap",
            overflow: "hidden",
            textOverflow: "ellipsis",
          },

          "& .MuiSvgIcon-root": {
            color: hasValue ? theme.palette.primary.main : theme.palette.text.secondary,
            fontSize: 16,
            right: 8,
          },
        }}
      >
        {options.map((option) => (
          <MenuItem key={option.value} value={option.value} dense>
            {multiple && (
              <Checkbox
                checked={selectedValues.includes(option.value)}
                size="small"
                sx={{
                  mr: 1,
                  p: 0.5,
                  color: theme.palette.divider,

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

            <Typography
              sx={{
                fontSize: 12,
                color: theme.palette.text.primary,
                whiteSpace: "normal",
                lineHeight: 1.45,
              }}
            >
              {option.label}
            </Typography>
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}

export function WorkingGroupFilters({
  filters,
  onFiltersChange,
}: WorkingGroupFiltersProps) {
  const updateFilters = (nextFilters: Partial<WorkingGroupFiltersValue>) => {
    onFiltersChange({ ...filters, ...nextFilters });
  };

  const resetFilters = () => {
    onFiltersChange({ ...defaultWorkingGroupFilters });
  };

  return (
    <Box
      sx={{
        position: "relative",
        zIndex: 20,
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        gap: 1.5,
        width: "100%",
      }}
    >
      <Box
        sx={{
          display: "flex",
          alignItems: "center",
          gap: 2.5,
          flexWrap: "nowrap",
          minWidth: 0,
          overflowX: "auto",
          overflowY: "visible",
          scrollbarWidth: "none",

          "&::-webkit-scrollbar": {
            display: "none",
          },
        }}
      >
        <WorkingGroupFilterSelect
          label="Working Group"
          value={filters.workingGroup}
          onChange={(nextValue) =>
            updateFilters({ workingGroup: nextValue as string[] })
          }
          options={workingGroupOptions}
          width={128}
          multiple
          displayMode="count"
        />

        <WorkingGroupFilterSelect
          label="Status"
          value={filters.status}
          onChange={(nextValue) => updateFilters({ status: nextValue as string[] })}
          options={statusOptions}
          width={84}
          multiple
          displayMode="count"
        />

        <WorkingGroupFilterSelect
          label="Primary Agency"
          value={filters.agency}
          onChange={(nextValue) => updateFilters({ agency: nextValue as string[] })}
          options={agencyOptions}
          width={134}
          multiple
          displayMode="count"
        />

        <WorkingGroupFilterSelect
          label="Year"
          value={filters.year}
          onChange={(nextValue) => updateFilters({ year: nextValue as string })}
          options={yearOptions}
          width={74}
        />

        <WorkingGroupFilterSelect
          label="Progress Report"
          value={filters.report}
          onChange={(nextValue) => updateFilters({ report: nextValue as string[] })}
          options={reportOptions}
          width={136}
          multiple
          displayMode="count"
        />
      </Box>

      <Box sx={{ flex: "0 0 auto" }}>
        <DashboardResetButton onClick={resetFilters} />
      </Box>
    </Box>
  );
}