import React, { type FC } from "react";
import { Decorator, Meta, StoryFn } from "@storybook/react";
import { Box } from "@mui/material";

import { ThemeProviderWithStyledEngine, Input } from "..";
import icons from "../components/icon/icons";
import type { InputProps } from "../components/input/Input";

const iconNames = Object.keys(icons).sort();

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

const meta = {
  title: "Components/Inputs/Input",
  component: Input as FC<InputProps & AdditionalControls>,
  decorators: [decorator],
  argTypes: {
    disabled: {
      type: "boolean",
    },
    maxLength: {
      type: "number",
    },
    variant: {
      control: {
        type: "radio",
      },
      options: ["outlined", "secondary"],
    },
    height: {
      control: {
        type: "radio",
      },
      options: ["32", "40"],
    },
    leftIcon: {
      name: "Left icon",
      options: iconNames,
      control: {
        type: "select",
      },
    },
    rightIcon: {
      table: {
        disable: true,
      },
    },
    rightButtonIcon: {
      name: "Right icon",
      description:
        "If you want to render an input button instead, make it actionable or give it a tooltip in the controls below.",
      options: iconNames,
      control: {
        type: "select",
      },
    },
    rightButtonClickable: {
      name: "Right button is clickable",
      description:
        "Whether clicking the right button should perform an action.",
      type: "boolean",
    },
    rightButtonTooltip: {
      name: "Right button tooltip",
      description: "The tooltip text of the right button.",
      type: "string",
    },
  },
} satisfies Meta<FC<InputProps & AdditionalControls>>;

export default meta;

interface AdditionalControls {
  rightButtonIcon?: keyof typeof icons;
  rightButtonClickable?: boolean;
  rightButtonTooltip?: string;
}

const Template: StoryFn<FC<InputProps & AdditionalControls>> = ({
  fullWidth,
  rightButtonIcon,
  rightButtonClickable,
  rightButtonTooltip,
  ...args
}) => {
  const [value, setValue] = React.useState("");

  return (
    <Box style={{ width: fullWidth ? "100%" : "240px" }}>
      <Input
        id="please-specify-the-id-when-youre-using-this-component"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        fullWidth
        rightIcon={
          rightButtonIcon &&
          (rightButtonClickable || rightButtonTooltip !== "" ? (
            <Input.Button
              icon={rightButtonIcon}
              onClick={rightButtonClickable ? () => {} : undefined}
              tooltip={rightButtonTooltip || undefined}
            />
          ) : (
            rightButtonIcon
          ))
        }
        {...args}
      />
    </Box>
  );
};

const SearchTemplate: StoryFn<typeof Input> = ({ fullWidth, ...args }) => {
  const [value, setValue] = React.useState("");

  return (
    <Box style={{ width: fullWidth ? "100%" : "240px" }}>
      <Input
        type="search"
        id="please-specify-the-id-when-youre-using-this-component"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        fullWidth
        leftIcon="search"
        name="search"
        {...args}
      />
    </Box>
  );
};

const TemplateWithHint: StoryFn<typeof Input> = ({
  fullWidth,
  label,
  ...args
}) => {
  const [value, setValue] = React.useState("");

  return (
    <Box style={{ width: fullWidth ? "100%" : "240px" }} marginTop={24}>
      <Input
        id="please-specify-the-id-when-youre-using-this-component"
        label={
          <Input.Label
            htmlFor="please-specify-the-id-when-youre-using-this-component"
            icon="question-mark-circle-fill"
            iconTooltipProps={{ tooltip: "This is a name field" }}
          >
            {label}
          </Input.Label>
        }
        value={value}
        onChange={(e) => setValue(e.target.value)}
        fullWidth
        {...args}
      />
    </Box>
  );
};

export const Default: StoryFn<FC<InputProps & AdditionalControls>> =
  Template.bind({});
export const SearchInput: StoryFn<typeof Input> = SearchTemplate.bind({});
export const InputWithHint: StoryFn<typeof Input> = TemplateWithHint.bind({});

Default.args = {
  fullWidth: true,
  variant: "outlined",
  label: "First Name",
  placeholder: "Enter your first name",
  required: false,
  error: false,
  disabled: false,
  height: "40",
  errorText: "",
  rightButtonIcon: undefined,
  rightButtonClickable: false,
  rightButtonTooltip: "",
};

SearchInput.args = {
  fullWidth: false,
  variant: "secondary",
  required: false,
  error: false,
  disabled: false,
  height: "32",
  errorText: "",
  label: undefined,
  placeholder: "Search...",
};

InputWithHint.args = {
  fullWidth: true,
  variant: "outlined",
  label: "First Name",
  placeholder: "Enter your first name",
  required: false,
  error: false,
  disabled: false,
  height: "40",
  errorText: "",
};
