import type { Meta, StoryObj } from "@storybook/react"
import { SvgUse } from "../../shared/SvgUse"
import { Button } from "./Button"

/**
 * Displays a button or a component that looks like a button.
 *
 * ## Props
 * - `variant`: "classic" | "solid" | "soft" | "surface" | "outline" | "ghost" (default: "solid")
 * - `size`: "1" | "2" | "3" | "4" (default: "2")
 * - `color`: "gray" | "gold" | "bronze" | "brown" | "yellow" | "amber" | "orange" | "tomato" | "red" | "ruby" | "crimson" | "pink" | "plum" | "purple" | "violet" | "iris" | "indigo" | "blue" | "cyan" | "teal" | "jade" | "green" | "grass" | "lime" | "mint" | "sky" (default: "gray")
 * - `radius`: "none" | "small" | "medium" | "large" | "full"
 * - `highContrast`: boolean
 * - `loading`: boolean (default: false)
 * - `disabled`: boolean
 * - `asChild`: boolean
 */
const meta = {
  title: "base/action/Button",
  component: Button,
  tags: ["autodocs"],
  argTypes: {
    children: {
      control: "text",
    },
    variant: {
      control: "select",
      options: ["classic", "solid", "soft", "surface", "outline", "ghost"],
      description: "The visual style of the button",
    },
    size: {
      control: "select",
      options: ["1", "2", "3", "4"],
      description: "The size of the button",
    },
    color: {
      control: "select",
      options: [
        "gray",
        "gold",
        "bronze",
        "brown",
        "yellow",
        "amber",
        "orange",
        "tomato",
        "red",
        "ruby",
        "crimson",
        "pink",
        "plum",
        "purple",
        "violet",
        "iris",
        "indigo",
        "blue",
        "cyan",
        "teal",
        "jade",
        "green",
        "grass",
        "lime",
        "mint",
        "sky",
      ],
      description: "The color theme of the button",
    },
    radius: {
      control: "select",
      options: ["none", "small", "medium", "large", "full"],
      description: "The border radius of the button",
    },
    highContrast: {
      control: "boolean",
      description: "Whether to use high contrast colors",
    },
    loading: {
      control: "boolean",
      description: "Whether the button is in a loading state",
    },
    disabled: {
      control: "boolean",
      description: "Whether the button is disabled",
    },
  },
  parameters: {
    layout: "centered",
  },
  args: {
    children: "Button",
  },
} satisfies Meta<typeof Button>

export default meta

type Story = StoryObj<typeof meta>

/**
 * The default form of the button, used for primary actions and commands.
 */
export const Default: Story = {}

/**
 * Use the `outline` button to reduce emphasis on secondary actions, such as
 * canceling or dismissing a dialog.
 */
export const Outline: Story = {
  args: {
    variant: "outline",
  },
}

/**
 * Use the `ghost` button is minimalistic and subtle, for less intrusive
 * actions.
 */
export const Ghost: Story = {
  args: {
    variant: "ghost",
  },
}

/**
 * Use the `soft` button to call for less emphasized actions, styled to
 * complement the primary button while being less conspicuous.
 */
export const Soft: Story = {
  args: {
    variant: "soft",
  },
}

/**
 * Use the `surface` button for actions that should blend with the surface.
 */
export const Surface: Story = {
  args: {
    variant: "surface",
  },
}

/**
 * Use the `classic` button for a traditional button appearance.
 */
export const Classic: Story = {
  args: {
    variant: "classic",
  },
}

/**
 * Use the `destructive` button to indicate errors, alerts, or the need for
 * immediate attention.
 */
export const Destructive: Story = {
  args: {
    variant: "solid",
    color: "red",
  },
}

/**
 * Use the `link` button to reduce emphasis on tertiary actions, such as
 * hyperlink or navigation, providing a text-only interactive element.
 */
export const Link: Story = {
  args: {
    variant: "ghost",
    color: "blue",
  },
}

/**
 * Add the `disabled` prop to a button to prevent interactions and add a
 * loading indicator, such as a spinner, to signify an in-progress action.
 */
export const Loading: Story = {
  render: args => (
    <Button {...args}>
      <SvgUse icon="loader" className="mr-2 h-4 w-4 animate-spin" />
      Button
    </Button>
  ),
  args: {
    ...Outline.args,
    disabled: true,
  },
}

/**
 * Add an icon element to a button to enhance visual communication and
 * providing additional context for the action.
 */
export const WithIcon: Story = {
  render: args => (
    <Button {...args}>
      <SvgUse icon="mail" className="mr-2 size-4" /> Login with Email Button
    </Button>
  ),
  args: {
    ...Soft.args,
  },
}

/**
 * Use the `1` size for a smaller button, suitable for interfaces needing
 * compact elements without sacrificing usability.
 */
export const Small: Story = {
  args: {
    size: "1",
  },
}

/**
 * Use the `3` size for a larger button, offering better visibility and
 * easier interaction for users.
 */
export const Large: Story = {
  args: {
    size: "3",
  },
}

/**
 * Use the `4` size for the largest button.
 */
export const ExtraLarge: Story = {
  args: {
    size: "4",
  },
}

/**
 * Add the `disabled` prop to prevent interactions with the button.
 */
export const Disabled: Story = {
  args: {
    disabled: true,
  },
}

/**
 * Showcase different color variants of the button.
 */
export const Colors: Story = {
  render: () => (
    <div className="flex flex-wrap gap-4">
      <Button color="indigo" variant="soft">
        Edit profile
      </Button>
      <Button color="cyan" variant="soft">
        Edit profile
      </Button>
      <Button color="orange" variant="soft">
        Edit profile
      </Button>
      <Button color="crimson" variant="soft">
        Edit profile
      </Button>
    </div>
  ),
}

/**
 * Showcase different radius options.
 */
export const Radius: Story = {
  render: () => (
    <div className="flex flex-wrap gap-4">
      <Button radius="none">No Radius</Button>
      <Button radius="small">Small</Button>
      <Button radius="medium">Medium</Button>
      <Button radius="large">Large</Button>
      <Button radius="full">Full</Button>
    </div>
  ),
}

/**
 * Showcase high contrast mode.
 */
export const HighContrast: Story = {
  render: () => (
    <div className="flex flex-wrap gap-4">
      <Button>Normal</Button>
      <Button highContrast>High Contrast</Button>
    </div>
  ),
}

/**
 * Showcase all variants in a grid layout.
 */
export const AllVariants: Story = {
  render: () => (
    <div className="grid grid-cols-2 gap-4">
      <Button variant="solid">Solid</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="soft">Soft</Button>
      <Button variant="surface">Surface</Button>
      <Button variant="classic">Classic</Button>
    </div>
  ),
}

/**
 * Showcase all sizes in a vertical layout.
 */
export const AllSizes: Story = {
  render: () => (
    <div className="flex flex-col gap-4">
      <Button size="1">Size 1 (Small)</Button>
      <Button size="2">Size 2 (Default)</Button>
      <Button size="3">Size 3 (Large)</Button>
      <Button size="4">Size 4 (Extra Large)</Button>
    </div>
  ),
}
