"use client";

import Box from "@mui/material/Box";
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 { dashboardAssets } from "@/components/dashboard/dashboard-assets";
import { DashboardAssetIcon } from "@/components/dashboard/dashboard-asset-icon";
import { AppCheckbox } from "@/components/ui/checkbox";

export type DropdownOption = {
  label: string;
  value: string;
  logo?: string | null;
};

export type DropdownProps = {
  label: string;
  options: DropdownOption[];
  value: string | string[];
  width?: number | string;
  multiple?: boolean;
  showCheckbox?: boolean;
  displayMode?: "count" | "join" | "single";
  menuMinWidth?: number;
  menuMaxHeight?: number;
  onChange: (value: string | string[]) => void;
};

function DropdownChevron() {
  return (
    <DashboardAssetIcon
      src={dashboardAssets.chevronDownSmall}
      width={8}
      height={5}
      sx={{ flexShrink: 0, pointerEvents: "none" }}
    />
  );
}

function DropdownTriggerValue({ text }: { text: string }) {
  return (
    <Box
      sx={{
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        gap: 1.5,
        width: "100%",
        minWidth: 0,
      }}
    >
      <Box
        component="span"
        sx={{
          flex: 1,
          minWidth: 0,
          overflow: "hidden",
          textOverflow: "ellipsis",
          whiteSpace: "nowrap",
        }}
      >
        {text}
      </Box>
      <DropdownChevron />
    </Box>
  );
}

export function Dropdown({
  label,
  options,
  value,
  width = 153,
  multiple = false,
  showCheckbox = false,
  displayMode = "single",
  menuMinWidth,
  menuMaxHeight,
  onChange,
}: DropdownProps) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  // A checkbox dropdown can also be single-select. Wrap its one value in an
  // array so the selected item, including the empty "All" option, is checked.
  const selectedValues = Array.isArray(value) ? value : [value];
  const hasValue = Array.isArray(value) ? value.length > 0 : Boolean(value);
  const resolvedMenuMaxHeight = menuMaxHeight ?? 232;

  const menuPaperSx = showCheckbox
    ? {
        mt: 1,
        minWidth: menuMinWidth ?? 386,
        maxWidth: menuMinWidth ?? 386,
        borderRadius: "12px",
        border: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#f5f5f5"}`,
        bgcolor: isDark ? "#101828" : "#ffffff",
        boxShadow: isDark
          ? "0 12px 30px rgba(0, 0, 0, 0.5)"
          : "0px 0px 10.6px rgba(0, 0, 0, 0.1)",
        overflow: "hidden",
        "& .MuiList-root": {
          maxHeight: resolvedMenuMaxHeight,
          overflowY: "auto",
          py: 0.5,
          scrollbarWidth: "thin",
          scrollbarColor: isDark
            ? `${alpha("#ffffff", 0.4)} ${alpha("#ffffff", 0.12)}`
            : "#a4a7ae #e9eaeb",
          "&::-webkit-scrollbar": {
            width: 6,
          },
          "&::-webkit-scrollbar-track": {
            background: isDark ? alpha("#ffffff", 0.12) : "#e9eaeb",
            borderRadius: "3px",
          },
          "&::-webkit-scrollbar-thumb": {
            background: isDark ? alpha("#ffffff", 0.4) : "#a4a7ae",
            borderRadius: "3px",
          },
        },
        "& .MuiMenuItem-root": {
          minHeight: 40,
          px: 1.5,
          py: 1.25,
          gap: 1.5,
          color: isDark ? alpha("#ffffff", 0.86) : "#414651",
          "&:hover": {
            bgcolor: isDark ? alpha("#ffffff", 0.06) : alpha("#000000", 0.04),
          },
          "&.Mui-selected": {
            bgcolor: "transparent",
          },
          "&.Mui-selected:hover": {
            bgcolor: isDark ? alpha("#ffffff", 0.06) : alpha("#000000", 0.04),
          },
        },
      }
    : {
        mt: 1,
        borderRadius: "14px",
        border: `1px solid ${theme.palette.divider}`,
        bgcolor: theme.palette.background.paper,
        boxShadow:
          theme.palette.mode === "dark"
            ? "0 12px 30px rgba(0, 0, 0, 0.5)"
            : "0 12px 30px rgba(15, 23, 42, 0.12)",
        maxHeight: 320,
        "& .MuiMenuItem-root": {
          minHeight: 48,
          px: 1.5,
          color: theme.palette.text.primary,
        },
        "& .MuiMenuItem-root:hover": {
          bgcolor: theme.palette.action.hover,
        },
        "& .MuiMenuItem-root.Mui-selected": {
          bgcolor: alpha(theme.palette.primary.main, 0.16),
        },
        "& .MuiMenuItem-root.Mui-selected:hover": {
          bgcolor: alpha(theme.palette.primary.main, 0.24),
        },
      };

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

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

    onChange(String(selectedValue));
  };

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

      if (items.length === 0) {
        return label;
      }

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

      if (displayMode === "join") {
        return options
          .filter((option) => items.includes(option.value))
          .map((option) => option.label)
          .join(", ");
      }

      return (
        options.find((option) => option.value === items[0])?.label ?? label
      );
    }

    const itemValue = String(selectedValue ?? "");

    if (!itemValue) {
      return label;
    }

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

  const renderValue = (selectedValue: unknown) => (
    <DropdownTriggerValue text={getDisplayText(selectedValue)} />
  );

  return (
    <FormControl size="small" sx={{ width }}>
      <Select
        multiple={multiple}
        displayEmpty
        value={value}
        onChange={handleChange}
        input={<OutlinedInput notched={false} />}
        renderValue={renderValue}
        IconComponent={() => null}
        MenuProps={{
          slotProps: {
            paper: {
              sx: menuPaperSx,
            },
          },
        }}
        sx={{
          height: 40,
          borderRadius: "6px",
          bgcolor: theme.palette.background.paper,
          color: hasValue
            ? theme.palette.text.primary
            : theme.palette.text.secondary,
          fontSize: 13,
          fontWeight: 500,
          "& .MuiOutlinedInput-notchedOutline": {
            borderColor: theme.palette.divider,
          },
          "&:hover .MuiOutlinedInput-notchedOutline": {
            borderColor: theme.palette.text.secondary,
          },
          "&.Mui-focused .MuiOutlinedInput-notchedOutline": {
            borderColor: theme.palette.primary.main,
            borderWidth: 1,
          },
          "& .MuiSelect-select": {
            display: "flex",
            alignItems: "center",
            minHeight: "40px !important",
            px: 1.5,
            py: 0,
            pr: "12px !important",
          },
          "& .MuiSelect-icon": {
            display: "none",
          },
        }}
      >
        {options.map((option) => (
          <MenuItem key={option.value} value={option.value} dense>
            {showCheckbox ? (
              <AppCheckbox
                checked={selectedValues.includes(option.value)}
                tabIndex={-1}
                sx={{
                  mr: 0,
                  flexShrink: 0,
                }}
              />
            ) : null}

            <Box
              sx={{
                display: "flex",
                alignItems: "center",
                gap: 1.25,
                minWidth: 0,
                flex: 1,
              }}
            >
              {option.logo !== undefined ? (
                <Box
                  component="img"
                  src={option.logo || dashboardAssets.primaryAgencyAvatar}
                  alt=""
                  sx={{
                    width: 24,
                    height: 24,
                    borderRadius: "50%",
                    objectFit: "cover",
                    flexShrink: 0,
                  }}
                />
              ) : null}

              <Typography
                noWrap
                sx={{
                  fontSize: showCheckbox ? 13 : 14,
                  fontWeight: 500,
                  color: showCheckbox
                    ? isDark
                      ? alpha("#ffffff", 0.86)
                      : "#414651"
                    : "inherit",
                  minWidth: 0,
                }}
              >
                {option.label}
              </Typography>
            </Box>
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}
