"use client";

import { useState, type ReactNode } from "react";

import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";

import { dashboardAssets } from "@/components/dashboard/dashboard-assets";
import { DashboardAssetIcon } from "@/components/dashboard/dashboard-asset-icon";
import { Dropdown, type DropdownOption } from "@/components/ui/dropdown";
import type { MeetingRequestStatus } from "../meeting-request-data";
import type { MeetingRequestsFiltersState } from "../hook/use-meeting-requests";

type FilterName = keyof MeetingRequestsFiltersState;

type Props = {
  filters: MeetingRequestsFiltersState;
  onFilterChange: <K extends FilterName>(
    name: K,
    value: MeetingRequestsFiltersState[K],
  ) => void;
  onExport: () => void;
  labels: {
    status: string;
    year: string;
    numberOfIssues: string;
    export: string;
  };
  statusLabels: Record<MeetingRequestStatus, string>;
};

type OpenFilter = "year" | "issues" | null;

const STATUS_OPTIONS: DropdownOption[] = [
  { value: "Submitted", label: "Submitted" },
  { value: "Under Review", label: "Under Review" },
  { value: "Scheduled", label: "Scheduled" },
  { value: "Completed", label: "Completed" },
];

const MIN_YEAR = 2018;
const MAX_YEAR = 2035;
const MIN_ISSUES = 1;
const MAX_ISSUES = 30;

export function MeetingRequestsFilters({
  filters,
  onFilterChange,
  onExport,
  labels,
}: Props) {
  const [openFilter, setOpenFilter] = useState<OpenFilter>(null);

  const [draftYear, setDraftYear] = useState<number>(() =>
    filters.year ? Number(filters.year) : 2018,
  );

  const [draftIssues, setDraftIssues] = useState<number>(() =>
    filters.issues ? Number(filters.issues) : 1,
  );

  const yearLabel = filters.year || labels.year;
  const issuesLabel = filters.issues || labels.numberOfIssues;

  const handleToggle = (target: OpenFilter) => {
    setOpenFilter((current) => (current === target ? null : target));
  };

  const handleYearShow = () => {
    onFilterChange("year", String(draftYear));
    setOpenFilter(null);
  };

  const handleIssuesShow = () => {
    onFilterChange("issues", String(draftIssues));
    setOpenFilter(null);
  };

  return (
    <Box
      sx={{
        mb: 2.5,
        display: "flex",
        justifyContent: "space-between",
        alignItems: { xs: "stretch", md: "center" },
        flexDirection: { xs: "column", md: "row" },
        gap: 2,
      }}
    >
      <Box
        sx={{
          display: "flex",
          gap: { xs: 1.5, sm: 2 },
          flexWrap: "wrap",
          alignItems: "center",
          flex: 1,
          minWidth: 0,
          width: "100%",
        }}
      >
        <Box sx={{ width: { xs: "100%", sm: 180 }, minWidth: 0 }}>
          <Dropdown
            displayMode="count"
            label={labels.status}
            multiple
            onChange={(value) =>
              onFilterChange(
                "status",
                Array.isArray(value) ? value : [value],
              )
            }
            options={STATUS_OPTIONS}
            showCheckbox
            value={filters.status}
            width="100%"
          />
        </Box>

        <FilterBox>
          <FilterButton
            active={openFilter === "year"}
            label={yearLabel}
            onClick={() => {
              setDraftYear(filters.year ? Number(filters.year) : 2018);
              handleToggle("year");
            }}
            width={180}
          />

          {openFilter === "year" && (
            <NumberDropdown
              value={draftYear}
              min={MIN_YEAR}
              max={MAX_YEAR}
              onIncrease={() =>
                setDraftYear((current) => Math.min(current + 1, MAX_YEAR))
              }
              onDecrease={() =>
                setDraftYear((current) => Math.max(current - 1, MIN_YEAR))
              }
              onShow={handleYearShow}
            />
          )}
        </FilterBox>

        <FilterBox>
          <FilterButton
            active={openFilter === "issues"}
            label={issuesLabel}
            onClick={() => {
              setDraftIssues(filters.issues ? Number(filters.issues) : 1);
              handleToggle("issues");
            }}
            width={220}
          />

          {openFilter === "issues" && (
            <NumberDropdown
              value={draftIssues}
              min={MIN_ISSUES}
              max={MAX_ISSUES}
              onIncrease={() =>
                setDraftIssues((current) => Math.min(current + 1, MAX_ISSUES))
              }
              onDecrease={() =>
                setDraftIssues((current) => Math.max(current - 1, MIN_ISSUES))
              }
              onShow={handleIssuesShow}
            />
          )}
        </FilterBox>
      </Box>

      <Button
        variant="outlined"
        onClick={onExport}
        sx={{
          width: { xs: "100%", sm: 115 },
          height: 44,
          minWidth: { xs: 0, sm: 115 },
          alignSelf: { xs: "stretch", md: "center" },
          borderRadius: "6px",
          borderColor: "var(--mr-blue)",
          color: "var(--mr-blue)",
          textTransform: "none",
          px: 1.5,
          py: 1.25,
          fontSize: 13,
          fontWeight: 500,
          bgcolor: "var(--mr-card)",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 0,
          lineHeight: 1,
          "&:hover": {
            borderColor: "var(--mr-blue)",
            bgcolor: "var(--mr-blue-soft)",
          },
        }}
      >
        <DashboardAssetIcon
          src={dashboardAssets.exportIcon}
          width={16}
          height={16}
          sx={{ transform: "rotate(90deg)" }}
        />
        <Typography
          component="span"
          sx={{
            color: "var(--mr-blue)",
            fontSize: 13,
            fontWeight: 500,
            lineHeight: 1,
            whiteSpace: "nowrap",
          }}
        >
          {labels.export}
        </Typography>
        <Box
          component="span"
          sx={{
            width: 24,
            height: 24,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <DashboardAssetIcon
            src={dashboardAssets.chevronDownBlue}
            width={8}
            height={5}
          />
        </Box>
      </Button>
    </Box>
  );
}

function FilterBox({ children }: { children: ReactNode }) {
  return (
    <Box
      sx={{
        position: "relative",
        display: "inline-flex",
        width: { xs: "100%", sm: "auto" },
        minWidth: 0,
      }}
    >
      {children}
    </Box>
  );
}

function FilterButton({
  label,
  active,
  onClick,
  width,
}: {
  label: string;
  active: boolean;
  onClick: () => void;
  width: number;
}) {
  return (
    <Button
      variant="outlined"
      onClick={onClick}
      sx={{
        width: { xs: "100%", sm: width },
        height: 44,
        justifyContent: "space-between",
        borderRadius: 2,
        borderColor: active ? "var(--mr-blue)" : "var(--mr-border)",
        bgcolor: "var(--mr-input)",
        color: active ? "var(--mr-text)" : "var(--mr-muted)",
        textTransform: "none",
        px: 1.8,
        fontSize: 14,
        fontWeight: 500,
        "&:hover": {
          borderColor: "var(--mr-blue)",
          bgcolor: "var(--mr-input)",
        },
      }}
    >
      <Box
        component="span"
        sx={{
          overflow: "hidden",
          textOverflow: "ellipsis",
          whiteSpace: "nowrap",
        }}
      >
        {label}
      </Box>

      <ChevronIcon open={active} />
    </Button>
  );
}

function ChevronIcon({ open }: { open: boolean }) {
  return (
    <Box
      component="span"
      sx={{
        ml: 1,
        width: 8,
        height: 8,
        flexShrink: 0,
        borderRight: "2px solid currentColor",
        borderBottom: "2px solid currentColor",
        transform: open ? "rotate(225deg)" : "rotate(45deg)",
        transition: "transform .18s ease",
        opacity: 0.75,
      }}
    />
  );
}

function DropdownPanel({
  children,
  width = 270,
}: {
  children: ReactNode;
  width?: number;
}) {
  return (
    <Box
      sx={{
        position: "absolute",
        top: "calc(100% + 8px)",
        left: 0,
        width,
        zIndex: 50,
        borderRadius: 2.5,
        bgcolor: "var(--mr-card)",
        color: "var(--mr-text)",
        border: "1px solid var(--mr-border)",
        boxShadow: "0 12px 28px rgba(15, 23, 42, 0.14)",
        p: 1.4,
      }}
    >
      {children}
    </Box>
  );
}

function NumberDropdown({
  value,
  min,
  max,
  onIncrease,
  onDecrease,
  onShow,
}: {
  value: number;
  min: number;
  max: number;
  onIncrease: () => void;
  onDecrease: () => void;
  onShow: () => void;
}) {
  const canDecrease = value > min;
  const canIncrease = value < max;

  return (
    <DropdownPanel width={220}>
      <Box
        sx={{
          display: "grid",
          justifyItems: "center",
          gap: 0.8,
        }}
      >
        <Button
          disabled={!canIncrease}
          onClick={onIncrease}
          sx={{
            minWidth: 36,
            height: 30,
            color: "var(--mr-muted)",
            fontSize: 22,
            fontWeight: 400,
            lineHeight: 1,
          }}
        >
          ⌃
        </Button>

        <Typography
          sx={{
            fontSize: 22,
            fontWeight: 400,
            color: "var(--mr-text)",
            lineHeight: 1.2,
          }}
        >
          {value}
        </Typography>

        <Button
          disabled={!canDecrease}
          onClick={onDecrease}
          sx={{
            minWidth: 36,
            height: 30,
            color: "var(--mr-muted)",
            fontSize: 22,
            fontWeight: 400,
            lineHeight: 1,
          }}
        >
          ⌄
        </Button>

        <Button
          variant="contained"
          onClick={onShow}
          sx={{
            mt: 0.5,
            width: 105,
            height: 36,
            borderRadius: 1.5,
            bgcolor: "var(--mr-blue)",
            color: "#fff",
            textTransform: "none",
            fontSize: 14,
            fontWeight: 500,
            "&:hover": {
              bgcolor: "var(--mr-blue)",
            },
          }}
        >
          Show
        </Button>
      </Box>
    </DropdownPanel>
  );
}
