"use client";

import { useEffect, useMemo, useState } from "react";

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

import { dashboardAssets } from "@/components/dashboard/dashboard-assets";
import { DashboardAssetIcon } from "@/components/dashboard/dashboard-asset-icon";
import { AppCheckbox } from "@/components/ui/checkbox";
import { useMeetingRequests } from "@/features/pswg/meeting-request/hook/use-meeting-requests";
import {
  getMeetingRequestFont,
  i18n,
  type UiLang,
} from "@/features/pswg/meeting-request/meeting-request-i18n";

import {
  MeetingRequestsViewTabs,
  type MeetingRequestsViewMode,
} from "./meeting-requests-view-tabs";

type MeetingRequestsFiltersProps = {
  activeView: MeetingRequestsViewMode;
  language?: UiLang;
  onViewChange: (view: MeetingRequestsViewMode) => void;

  workingGroupFilter: string[];
  onWorkingGroupFilterChange: (values: string[]) => void;

  governmentAgencyFilter: string[];
  onGovernmentAgencyFilterChange: (values: string[]) => void;

  statusFilter: string[];
  onStatusFilterChange: (values: string[]) => void;

  meetingDateFilter: string[];
  onMeetingDateFilterChange: (values: string[]) => void;
};

type FilterKey =
  | "workingGroup"
  | "governmentAgency"
  | "meetingStatus"
  | "meetingDate";

type FilterOption = {
  label: string;
  value: string;
  image?: string | null;
  disabled?: boolean;
};

type FilterFieldProps = {
  filterKey: FilterKey;
  label: string;
  width: number;
  language: UiLang;
  options: FilterOption[];
  selectedValues: string[];
  onChange: (values: string[]) => void;
};

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

function FilterField({
  filterKey,
  label,
  width,
  language,
  options,
  selectedValues,
  onChange,
}: FilterFieldProps) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
  const [monthIndex, setMonthIndex] = useState(new Date().getMonth());
  const [year, setYear] = useState(new Date().getFullYear());

  const open = Boolean(anchorEl);
  const isDateFilter = filterKey === "meetingDate";

  const selectedLabel = useMemo(() => {
    if (selectedValues.length === 0) return label;

    if (selectedValues.length === 1) {
      return (
        options.find((item) => item.value === selectedValues[0])?.label ??
        selectedValues[0]
      );
    }

    return `${label} (${selectedValues.length})`;
  }, [label, options, selectedValues]);

  const handleToggle = (option: FilterOption) => {
    if (option.disabled || option.value.startsWith("__")) return;

    if (selectedValues.includes(option.value)) {
      onChange(selectedValues.filter((item) => item !== option.value));
      return;
    }

    onChange([...selectedValues, option.value]);
  };

  const handleShowDate = () => {
    const month = months[monthIndex];

    onChange([`${month} ${year}`]);
    setAnchorEl(null);
  };

  return (
    <>
      <ButtonBase
        onClick={(event) => setAnchorEl(event.currentTarget)}
        sx={{
          width,
          height: 44,
          flex: "0 0 auto",
          px: 1.5,
          borderRadius: "6px",
          border: `1px solid ${
            open ? "#1f6fb2" : isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"
          }`,
          bgcolor: isDark ? alpha("#ffffff", 0.05) : "#ffffff",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 1,
          overflow: "hidden",
        }}
      >
        <Typography
          noWrap
          sx={{
            color: isDark ? alpha("#ffffff", 0.7) : "#717680",
            fontSize: 14,
            fontWeight: 500,
            fontFamily: getMeetingRequestFont(language),
            minWidth: 0,
          }}
        >
          {selectedLabel}
        </Typography>

        <DashboardAssetIcon
          src={dashboardAssets.chevronDownSmall}
          width={8}
          height={5}
          sx={{ flexShrink: 0 }}
        />
      </ButtonBase>

      <Menu
        anchorEl={anchorEl}
        open={open}
        onClose={() => setAnchorEl(null)}
        slotProps={{
          paper: {
            sx: {
              mt: 1,
              width: isDateFilter ? 250 : Math.max(width, 300),
              maxHeight: isDateFilter ? "none" : 260,
              borderRadius: "8px",
              border: `1px solid ${
                isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"
              }`,
              backgroundColor: isDark ? "#101828" : "#ffffff",
              boxShadow: "0px 12px 30px rgba(16, 24, 40, 0.16)",
              // Keep the existing dropdown size, but allow long option lists
              // such as Working Group and Government Agency to scroll.
              overflowX: "hidden",
              overflowY: isDateFilter ? "hidden" : "auto",
              overscrollBehavior: "contain",
            },
          },
        }}
      >
        {isDateFilter ? (
          <Box sx={{ p: 2 }}>
            <Box
              sx={{
                display: "grid",
                gridTemplateColumns: "1fr 1fr",
                alignItems: "center",
                textAlign: "center",
                columnGap: 2,
              }}
            >
              <ButtonBase
                onClick={() =>
                  setMonthIndex((previous) =>
                    previous === 0 ? months.length - 1 : previous - 1,
                  )
                }
                sx={{ height: 26, borderRadius: "8px" }}
              >
                <Typography sx={{ fontSize: 20, lineHeight: 1 }}>⌃</Typography>
              </ButtonBase>

              <ButtonBase
                onClick={() => setYear((previous) => previous + 1)}
                sx={{ height: 26, borderRadius: "8px" }}
              >
                <Typography sx={{ fontSize: 20, lineHeight: 1 }}>⌃</Typography>
              </ButtonBase>

              <Typography
                sx={{
                  py: 1,
                  fontSize: 18,
                  fontWeight: 500,
                  color: isDark ? "#ffffff" : "#4a4a4a",
                  fontFamily: getMeetingRequestFont(language),
                }}
              >
                {months[monthIndex]}
              </Typography>

              <Typography
                sx={{
                  py: 1,
                  fontSize: 18,
                  fontWeight: 500,
                  color: isDark ? "#ffffff" : "#4a4a4a",
                  fontFamily: getMeetingRequestFont(language),
                }}
              >
                {year}
              </Typography>

              <ButtonBase
                onClick={() =>
                  setMonthIndex((previous) =>
                    previous === months.length - 1 ? 0 : previous + 1,
                  )
                }
                sx={{ height: 26, borderRadius: "8px" }}
              >
                <Typography sx={{ fontSize: 20, lineHeight: 1 }}>⌄</Typography>
              </ButtonBase>

              <ButtonBase
                onClick={() => setYear((previous) => previous - 1)}
                sx={{ height: 26, borderRadius: "8px" }}
              >
                <Typography sx={{ fontSize: 20, lineHeight: 1 }}>⌄</Typography>
              </ButtonBase>
            </Box>

            <Box sx={{ mt: 1.5, display: "flex", justifyContent: "flex-end" }}>
              <ButtonBase
                onClick={handleShowDate}
                sx={{
                  height: 30,
                  width: 86,
                  borderRadius: "6px",
                  bgcolor: "#1f6fb2",
                  color: "#ffffff",
                  fontSize: 12,
                  fontWeight: 600,
                  fontFamily: getMeetingRequestFont(language),
                  "&:hover": { bgcolor: "#195f99" },
                }}
              >
                Show
              </ButtonBase>
            </Box>
          </Box>
        ) : (
          options.map((option) => {
            const checked = selectedValues.includes(option.value);

            return (
              <MenuItem
                key={option.value}
                disabled={option.disabled}
                onClick={() => handleToggle(option)}
                sx={{
                  minHeight: 44,
                  px: 1.5,
                  gap: 1,
                  fontFamily: getMeetingRequestFont(language),
                }}
              >
                <AppCheckbox
                  checked={checked}
                  disabled={option.disabled}
                  tabIndex={-1}
                  sx={{
                    mr: 1,
                    flexShrink: 0,
                  }}
                />

                {option.image ? (
                  <Box
                    component="img"
                    src={option.image}
                    alt={option.label}
                    onError={(event) => {
                      event.currentTarget.style.display = "none";
                    }}
                    sx={{
                      width: 28,
                      height: 28,
                      borderRadius: "50%",
                      objectFit: "cover",
                      flexShrink: 0,
                    }}
                  />
                ) : null}

                <Typography
                  noWrap
                  sx={{
                    fontSize: 14,
                    fontWeight: 500,
                    color: isDark ? "#ffffff" : "#344054",
                    fontFamily: getMeetingRequestFont(language),
                  }}
                >
                  {option.label}
                </Typography>
              </MenuItem>
            );
          })
        )}
      </Menu>
    </>
  );
}

export function MeetingRequestsFilters({
  activeView,
  language = "km",
  onViewChange,
  workingGroupFilter,
  onWorkingGroupFilterChange,
  governmentAgencyFilter,
  onGovernmentAgencyFilterChange,
  statusFilter,
  onStatusFilterChange,
  meetingDateFilter,
  onMeetingDateFilterChange,
}: MeetingRequestsFiltersProps) {
  const t = i18n(language);

  const {
    agencies,
    workingGroups,
    loadingAgencies,
    loadingWorkingGroups,
    fetchGovernmentAgencies,
    fetchWorkingGroups,
  } = useMeetingRequests();

  useEffect(() => {
    fetchWorkingGroups();
    fetchGovernmentAgencies();
  }, [fetchWorkingGroups, fetchGovernmentAgencies]);

  const handleFilterChange = (key: FilterKey, values: string[]) => {
    if (key === "workingGroup") {
      onWorkingGroupFilterChange(values);
      return;
    }

    if (key === "governmentAgency") {
      onGovernmentAgencyFilterChange(values);
      return;
    }

    if (key === "meetingStatus") {
      onStatusFilterChange(values);
      return;
    }

    if (key === "meetingDate") {
      onMeetingDateFilterChange(values);
    }
  };

  const workingGroupOptions: FilterOption[] =
    workingGroups.length > 0
      ? workingGroups.map((item) => ({
          label: item.name,
          value: String(item.id),
        }))
      : [
          {
            label: loadingWorkingGroups
              ? language === "km"
                ? "កំពុងទាញយក..."
                : "Loading..."
              : language === "km"
                ? "មិនមានទិន្នន័យ"
                : "No data",
            value: "__empty_working_group__",
            disabled: true,
          },
        ];

  const governmentAgencyOptions: FilterOption[] =
    agencies.length > 0
      ? agencies.map((item) => ({
          label: item.name,
          value: String(item.id),
          image: item.logo,
        }))
      : [
          {
            label: loadingAgencies
              ? language === "km"
                ? "កំពុងទាញយក..."
                : "Loading..."
              : language === "km"
                ? "មិនមានទិន្នន័យ"
                : "No data",
            value: "__empty_government_agency__",
            disabled: true,
          },
        ];

  const filterOptions: Record<FilterKey, FilterOption[]> = {
    workingGroup: workingGroupOptions,
    governmentAgency: governmentAgencyOptions,
    meetingStatus: [
      { label: t.statuses.Drafted, value: "Drafted" },
      { label: t.statuses.Submitted, value: "Submitted" },
      { label: t.statuses["Under Review"], value: "Under Review" },
      { label: t.statuses.Scheduled, value: "Scheduled" },
      { label: t.statuses.Completed, value: "Completed" },
    ],
    meetingDate: [],
  };

  const filters: { key: FilterKey; label: string; width: number }[] = [
    { key: "workingGroup", label: t.workingGroup, width: 170 },
    { key: "governmentAgency", label: t.governmentAgency, width: 220 },
    { key: "meetingStatus", label: t.meetingStatus, width: 180 },
    { key: "meetingDate", label: t.meetingDate, width: 165 },
  ];

  const getSelectedValues = (key: FilterKey) => {
    if (key === "workingGroup") return workingGroupFilter;
    if (key === "governmentAgency") return governmentAgencyFilter;
    if (key === "meetingStatus") return statusFilter;

    return meetingDateFilter;
  };

  return (
    <Box
      sx={{
        mt: 3,
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        gap: 2,
        flexWrap: "nowrap",
        width: "100%",
      }}
    >
      <Box
        sx={{
          display: "flex",
          alignItems: "center",
          gap: 1,
          flexWrap: "nowrap",
          flex: "0 1 auto",
          minWidth: 0,
          overflow: "hidden",
        }}
      >
        {filters.map((filterItem) => (
          <FilterField
            key={filterItem.key}
            filterKey={filterItem.key}
            label={filterItem.label}
            width={filterItem.width}
            language={language}
            options={filterOptions[filterItem.key]}
            selectedValues={getSelectedValues(filterItem.key)}
            onChange={(values) => handleFilterChange(filterItem.key, values)}
          />
        ))}
      </Box>

      <Box sx={{ flexShrink: 0, display: "flex", justifyContent: "flex-end" }}>
        <MeetingRequestsViewTabs
          activeView={activeView}
          language={language}
          onViewChange={onViewChange}
        />
      </Box>
    </Box>
  );
}
