import type { Meta, StoryObj } from "@storybook/nextjs-vite"

import { expect } from "storybook/test"

import { Input } from "./Input"
import { TextField } from "react-aria-components"
import { MaterialIcon } from "../Icons/MaterialIcon"
import { MaterialIconName } from "../Icons/MaterialIcon/generated"

const meta: Meta<typeof Input> = {
  title: "Core Components/Input",
  // @ts-expect-error Input does not support this, but wrapping <TextField> does
  component: ({ isInvalid, validationState, ...props }) => (
    <TextField isInvalid={isInvalid} data-validation-state={validationState}>
      <Input {...props} data-validation-state={validationState} />
    </TextField>
  ),
  argTypes: {
    label: {
      control: "text",
      description: "The label text displayed for the input field",
      table: {
        type: { summary: "string" },
      },
    },
    labelPosition: {
      control: "select",
      options: ["floating", "top"],
      description: "Position of the label relative to the input",
      table: {
        type: { summary: "'floating' | 'top'" },
        defaultValue: { summary: "'floating'" },
      },
    },
    placeholder: {
      control: "text",
      description: "Placeholder text shown when input is empty",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
      },
    },
    required: {
      control: "boolean",
      description: "Whether the input is required",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    disabled: {
      control: "boolean",
      description: "Whether the input is disabled",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    showClearContentIcon: {
      control: "boolean",
      description: "Whether the clear content icon is shown",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    showLeftIcon: {
      control: "boolean",
      description: "Whether to show a left icon",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    showRightIcon: {
      control: "boolean",
      description: "Whether to show a right icon",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    leftIconName: {
      control: "select",
      options: [
        "calendar_month",
        "credit_card",
        "email",
        "info_circle",
        "location_on",
        "lock",
        "phone",
        "search",
        "sell",
        "visibility",
        "visibility_off",
      ],
      description: "Icon name for the left icon",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "'person'" },
      },
    },
    rightIconName: {
      control: "select",
      options: [
        "calendar_month",
        "credit_card",
        "email",
        "info_circle",
        "location_on",
        "lock",
        "phone",
        "search",
        "sell",
        "visibility",
        "visibility_off",
      ],
      description: "Icon name for the right icon",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "'lock'" },
      },
    },
    showWarning: {
      control: "boolean",
      description: "Whether to show warning validation state",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  } as any,
}

export default meta

type Story = StoryObj<typeof Input>

export const Default: Story = {
  args: {
    label: "Label",
    name: "foo",
    required: false,
    showLeftIcon: false,
    showRightIcon: false,
    leftIconName: "person",
    rightIconName: "lock",
    showWarning: false,
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  } as any,
  render: (args) => {
    // Extract custom Storybook args
    const {
      showLeftIcon,
      showRightIcon,
      leftIconName,
      rightIconName,
      showWarning,
      ...inputProps
    } = args as typeof args & {
      showLeftIcon?: boolean
      showRightIcon?: boolean
      leftIconName?: string
      rightIconName?: string
      showWarning?: boolean
    }

    const validationState = showWarning ? "warning" : undefined

    return (
      <TextField data-validation-state={validationState}>
        <Input
          {...inputProps}
          data-validation-state={validationState}
          leftIcon={
            showLeftIcon && leftIconName ? (
              <MaterialIcon icon={leftIconName as MaterialIconName} />
            ) : undefined
          }
          rightIcon={
            showRightIcon && rightIconName ? (
              <MaterialIcon icon={rightIconName as MaterialIconName} />
            ) : undefined
          }
        />
      </TextField>
    )
  },
  play: async ({ canvas, userEvent }) => {
    const textbox = canvas.getByRole("textbox")
    expect(textbox).not.toBeDisabled()

    expect(textbox).toHaveValue("")

    await userEvent.type(textbox, "Hello World")
    expect(textbox).toHaveValue("Hello World")

    await userEvent.clear(textbox)
    expect(textbox).toHaveValue("")
  },
}
