"use client";

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

import Box from "@mui/material/Box";
import Button, { type ButtonProps } from "@mui/material/Button";
import { alpha, type SxProps, type Theme } from "@mui/material/styles";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";

import {
  ExportFormatMenu,
  type ExportFormat,
} from "@/components/ui/export-format-menu";
import { exportFileIcon as ExportFileIcon } from "./icon";

function getSxArray(sx?: SxProps<Theme>) {
  if (!sx) return [];

  return Array.isArray(sx) ? sx : [sx];
}

function getExportButtonSx(compact: boolean): SxProps<Theme> {
  return (theme) => {
    const isDark = theme.palette.mode === "dark";

    return {
      height: 40,
      minHeight: 40,
      py: "10px",
      px: "12px",
      minWidth: compact ? 128 : 175,
      ...(compact && {
        width: 128,
        maxWidth: 128,
      }),
      borderColor: isDark ? alpha("#ffffff", 0.2) : "#1a64a8",
      color: isDark ? "#7cc7ff" : "#1a64a8",
      bgcolor: isDark ? alpha("#ffffff", 0.04) : "transparent",
      fontSize: 13,
      fontWeight: 500,
      lineHeight: 1,
      borderRadius: "6px",
      boxShadow: "none",
      textTransform: "none",
      whiteSpace: "nowrap",
      "&:hover": {
        borderColor: isDark ? alpha("#ffffff", 0.32) : "#15548e",
        bgcolor: isDark
          ? alpha("#ffffff", 0.08)
          : alpha("#1a64a8", 0.04),
        boxShadow: "none",
      },
    };
  };
}

export type ExportButtonProps = Omit<ButtonProps, "startIcon" | "endIcon"> & {
  loading?: boolean;
  loadingLabel?: string;
  compact?: boolean;
  showChevron?: boolean;
  showMenu?: boolean;
  onExport?: (format: ExportFormat) => void;
};

export function ExportButton({
  children = "Export as XLSX",
  loading = false,
  loadingLabel = "Exporting...",
  compact = false,
  showChevron = false,
  showMenu = false,
  onExport,
  disabled,
  onClick,
  sx,
  ...props
}: ExportButtonProps) {
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
  const open = Boolean(anchorEl);
  const menuEnabled = showMenu && !loading;
  const dropdownLayout = showChevron || showMenu;
  const label = loading ? loadingLabel : children;

  const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
    if (menuEnabled) {
      setAnchorEl(event.currentTarget);
      return;
    }

    onClick?.(event);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  const handleSelect = (format: ExportFormat) => {
    onExport?.(format);
    handleClose();
  };

  return (
    <>
      <Button
        type="button"
        variant="outlined"
        disabled={disabled || loading}
        onClick={handleClick}
        startIcon={
          dropdownLayout ? undefined : <ExportFileIcon sx={{ fontSize: 16 }} />
        }
        aria-haspopup={menuEnabled ? "menu" : undefined}
        aria-expanded={menuEnabled && open ? "true" : undefined}
        sx={[getExportButtonSx(compact), ...getSxArray(sx)]}
        {...props}
      >
        {dropdownLayout ? (
          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
              width: "100%",
              gap: compact ? 0.5 : 1,
            }}
          >
            <ExportFileIcon
              sx={{ fontSize: compact ? 15 : 16, flexShrink: 0 }}
            />
            <Box
              component="span"
              sx={{
                fontSize: compact ? 12 : 13,
                fontWeight: 500,
                lineHeight: 1,
                flexShrink: 0,
              }}
            >
              {label}
            </Box>
            <KeyboardArrowDownIcon
              sx={{ fontSize: compact ? 18 : 24, flexShrink: 0 }}
            />
          </Box>
        ) : (
          label
        )}
      </Button>

      {menuEnabled ? (
        <ExportFormatMenu
          anchorEl={anchorEl}
          open={open}
          onClose={handleClose}
          onSelect={handleSelect}
        />
      ) : null}
    </>
  );
}
