import React, { type FC } from "react";
import { Decorator, Meta, StoryFn } from "@storybook/react";
import { Button, ThemeProviderWithStyledEngine } from "../";
import icons from "../components/icon/icons";
import type {
  ButtonProps,
  ButtonSize,
  ButtonVariant,
} from "../components/button/types";
import type { TooltipProps } from "../components/tooltip/Tooltip";
import type { IconProps } from "../components/icon/Icon";
const iconNames = Object.keys(icons).sort();

const variantOptions: ButtonVariant[] = [
  "primary",
  "secondary",
  "tertiary",
  "outlined",
  "danger",
];

const sizeOptions: ButtonSize[] = ["tiny", "small", "default", "large"];

const iconWeightOptions: IconProps["weight"][] = [
  "regular",
  "medium",
  "semibold",
  "bold",
];

const tooltipPlacementOptions: TooltipProps["placement"][] = [
  "top",
  "top-start",
  "top-end",
  "right",
  "right-start",
  "right-end",
  "bottom",
  "bottom-start",
  "bottom-end",
  "left",
  "left-start",
  "left-end",
];

const tooltipSpacingOptions: TooltipProps["spacing"][] = ["4", "6", "8", "12"];

const disabled = {
  table: {
    disable: true,
  },
};

const decorator: Decorator<unknown> = (Story) => (
  <ThemeProviderWithStyledEngine>{Story()}</ThemeProviderWithStyledEngine>
);

const meta = {
  title: "Components/Inputs/Button",
  component: Button as FC<ButtonProps & AdditionalControls>,
  decorators: [decorator],
  argTypes: {
    variant: {
      name: "Variant",
      options: variantOptions,
    },
    size: {
      name: "Size",
      options: sizeOptions,
    },
    children: {
      description: "Text for button",
      control: {
        type: "text",
      },
    },
    type: disabled,
    action: disabled,
    centerRipple: disabled,
    focusRipple: disabled,
    disableRipple: disabled,
    disableFocusRipple: disabled,
    disableTouchRipple: disabled,
    disableElevation: disabled,
    touchRippleRef: disabled,
    TouchRippleProps: disabled,
    LinkComponent: disabled,
    startIcon: disabled,
    endIcon: disabled,
    href: disabled,
    sx: disabled,
    classes: disabled,
    tabIndex: disabled,
    focusVisibleClassName: disabled,
    onFocusVisible: disabled,
    onClick: disabled,
    to: {
      description: `If you want to render a button as html \`a\` (anchor),
        you can use 'to' parameter.
        You need to just set it as an url of a page like regular href attribute of anchor`,
      table: {
        type: null,
      },
      control: {
        type: null,
      },
    },
    tooltipPlacement: {
      name: "Tooltip placement",
      table: {
        type: null,
      },
      options: tooltipPlacementOptions,
      description: tooltipPlacementOptions.map((o) => `\`"${o}"\``).join(", "),
    },
    tooltipSpacing: {
      name: "Tooltip spacing",
      table: {
        type: null,
      },
      control: "select",
      options: tooltipSpacingOptions,
    },
    icon: {
      options: iconNames,
      name: "Icon name",
      table: {
        type: null,
      },
    },
    iconWeight: {
      name: "Icon weight",
      options: iconWeightOptions,
      control: "radio",
    },
  },
} satisfies Meta<FC<ButtonProps & AdditionalControls>>;

export default meta;

interface AdditionalControls {
  tooltipPlacement: TooltipProps["placement"];
  tooltipSpacing: TooltipProps["spacing"];
}

const Template: StoryFn<FC<ButtonProps & AdditionalControls>> = ({
  tooltipPlacement,
  tooltipSpacing,
  ...args
}) => (
  <Button
    {...args}
    tooltipProps={{ placement: tooltipPlacement, spacing: tooltipSpacing }}
  >
    {args.children}
  </Button>
);

export const Default: StoryFn<FC<ButtonProps & AdditionalControls>> =
  Template.bind({});
Default.args = {
  tooltip: "Tooltip",
  variant: "primary",
  onClick: () => {},
  children: "Submit",
  tooltipPlacement: "bottom",
  tooltipSpacing: "8",
};
