import { Meta, StoryObj } from '@storybook/react-webpack5';
import ListItem from '..';
import { Edit } from '@transferwise/icons';
import { fn } from 'storybook/test';
import List from '../../list';
import {
  SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
  SB_LIST_ITEM_MEDIA as MEDIA,
  SB_LIST_ITEM_PROMPTS as PROMPTS,
} from '../_stories/subcomponents';
import { disableControls } from '../_stories/helpers';
import type { ListItemIconButtonProps } from './ListItemIconButton';

const hideControls = disableControls([
  'onClick',
  'children',
  'className',
  'addonStart',
  'addonEnd',
]);

/**
 * Use IconButton to provide compact action controls within a ListItem context using iconography.
 *
 * Refer to the [design documentation](https://wise.design/components/list-item) for more details.
 */
const meta: Meta<ListItemIconButtonProps> = {
  component: ListItem.IconButton,
  title: 'Content/ListItem/ListItem.IconButton',
  args: {
    partiallyInteractive: false,
    priority: undefined,
    type: undefined,
    'aria-label': 'Edit details',
    children: <Edit />,
    href: undefined,
    target: undefined,
    onClick: fn(),
  },
  argTypes: {
    children: {
      description: 'Once of the [Icon components](https://transferwise.github.io/icons/).',
      table: {
        type: { summary: 'ReactNode' },
      },
      control: false,
    },
    priority: {
      control: 'radio',
      options: ['unset (undefined)', 'primary', 'secondary', 'tertiary', 'minimal'],
      mapping: {
        'unset (undefined)': undefined,
      },
      description: 'IconButton priority/style variant',
    },
    type: {
      control: 'radio',
      options: ['unset (undefined)', 'default', 'negative'],
      mapping: {
        'unset (undefined)': undefined,
      },
      description:
        'Sets a visual hierarchy amongst the buttons displayed on the screen. <br /> **NB:** `negative` sentiment only affects the `primary` and `secondary` priorities.',
    },
    partiallyInteractive: {
      control: 'boolean',
      description: 'Whether the icon button allows partial interactivity in the ListItem',
    },
    href: {
      control: 'text',
      description: 'URL for icon button rendered as link',
    },
    target: {
      control: 'select',
      options: [undefined, '_blank', '_self', '_parent', '_top'],
      description:
        'The `target` attribute for HTML anchor. If set to `_blank`, `rel="noopener noreferrer"` is automatically added to the rendered node.',
    },
  },
} satisfies Meta<ListItemIconButtonProps>;

export default meta;

type Story = StoryObj<ListItemIconButtonProps>;

export const Playground: Story = {
  render: (args: ListItemIconButtonProps) => {
    return (
      <List>
        <ListItem
          title="List item title"
          subtitle="Subtitle goes here"
          media={MEDIA.avatarSingle}
          control={<ListItem.IconButton {...args} />}
          additionalInfo={INFO.nonInteractive}
        />
      </List>
    );
  },
};

/**
 * It's strongly encouraged to provide `aria-label` prop for the `IconButton` control to ensure it
 * follows accessibility best practices.
 * If not set, the component will provide accessible name via the `title`, `subtitle`, `valueTitle`
 * and `valueSubtitle` props and accessible description via `additionalInfo` and `prompt`, which
 * may not be descriptive enough for the screen readers users.
 */
export const AccessibleName: Story = {
  args: {
    children: <Edit />,
    href: 'https://wise.com',
    target: '_blank',
    onClick: undefined,
  },
  argTypes: hideControls(),
  render: (args: ListItemIconButtonProps) => {
    return (
      <List>
        <ListItem
          control={<ListItem.IconButton {...args} />}
          title="List item with icon button link"
          subtitle="IconButton rendered as anchor element"
          media={MEDIA.avatarSingle}
        />
      </List>
    );
  },
};

/**
 * By default, ListItem is fully interactive, which means its whole surface is clickable
 * and triggers the control. To remain WCAG-compliant there can be no nested interactive
 * elements inside the item.<br />
 *
 * To work around this limitation, this control also allows for a partially interactive mode,
 * which can be enabled via `partiallyInteractive` prop. Once set, only the control will
 * remain interactive, which allows for interactive element to be attached to the
 * `ListItem.AdditionalInfo`. This allows for more complex layouts while still providing a
 * clear, accessible action point for users. <br />
 *
 * If you still require a fully interactive ListItem, you can alternatively use `ListItem.Prompt`
 * which allows for a single instance of a link or an inline button.
 *
 * Refer to the [design documentation](https://wise.design/components/list-item#interaction) for details.
 */
export const Interactivity: Story = {
  args: {
    children: <Edit />,
  },
  argTypes: hideControls(['partiallyInteractive']),
  render: (args: ListItemIconButtonProps) => {
    return (
      <List>
        <ListItem
          control={<ListItem.IconButton {...args} />}
          title="Fully interactive ListItem"
          subtitle="IconButton in fully interactive context"
          media={MEDIA.avatarSingle}
          additionalInfo={INFO.nonInteractive}
          prompt={PROMPTS.interactive}
        />

        <ListItem
          control={<ListItem.IconButton {...args} partiallyInteractive />}
          title="Partially interactive ListItem"
          subtitle="IconButton in partially interactive context"
          media={MEDIA.avatarSingle}
          additionalInfo={INFO.interactive}
          prompt={PROMPTS.interactive}
        />
      </List>
    );
  },
};

/**
 * There are two different types of icon button – default and negative – designed to emphasise the nature of the action. <br />
 * **NB:** Sentiment only applies to `primary` and `secondary` priorities. <br />
 * [Design documentation](https://wise.design/components/icon-button#types)
 */
export const Sentiment: Story = {
  argTypes: hideControls(['sentiment', 'priority']),
  render: (args) => {
    return (
      <List>
        <ListItem
          control={<ListItem.IconButton {...args} priority="primary" type="default" />}
          title="Default Sentiment - Primary"
          subtitle="Default sentiment with primary priority"
          media={MEDIA.avatarSingle}
        />
        <ListItem
          control={<ListItem.IconButton {...args} priority="secondary" type="default" />}
          title="Default Sentiment - Secondary"
          subtitle="Default sentiment with secondary priority"
          media={MEDIA.avatarSingle}
        />
        <ListItem
          control={<ListItem.IconButton {...args} priority="primary" type="negative" />}
          title="Negative Sentiment - Primary"
          subtitle="Negative sentiment with primary priority"
          media={MEDIA.avatarSingle}
        />
        <ListItem
          control={<ListItem.IconButton {...args} priority="secondary" type="negative" />}
          title="Negative Sentiment - Secondary"
          subtitle="Negative sentiment with secondary priority"
          media={MEDIA.avatarSingle}
        />
      </List>
    );
  },
};

/**
 * Priorities set a visual hierarchy amongst the buttons displayed on the
 * screen to help more important buttons to take precedence over others. <br />
 * [Design documentation](https://wise.design/components/icon-button#priorities)
 */
export const Priority: Story = {
  argTypes: hideControls(['sentiment', 'priority']),
  render: (args) => {
    return (
      <List>
        <ListItem
          title="Primary Priority"
          subtitle="Primary priority (default)"
          media={MEDIA.avatarSingle}
          control={<ListItem.IconButton {...args} priority="primary" />}
        />
        <ListItem
          title="Secondary Priority"
          subtitle="Secondary priority"
          media={MEDIA.avatarSingle}
          control={<ListItem.IconButton {...args} priority="secondary" />}
        />
        <ListItem
          title="Secondary Neutral Priority"
          subtitle="Secondary neutral priority"
          media={MEDIA.avatarSingle}
          control={<ListItem.IconButton {...args} priority="tertiary" />}
        />
        <ListItem
          title="Tertiary Priority"
          subtitle="Tertiary priority"
          media={MEDIA.avatarSingle}
          control={<ListItem.IconButton {...args} priority="minimal" />}
        />
      </List>
    );
  },
};

/**
 * If `href` prop is set, the component will be automatically rendered as an HTML anchor element.
 */
export const AsAnchor: Story = {
  args: {
    children: <Edit />,
    href: 'https://wise.com',
    target: '_blank',
    onClick: undefined,
  },
  argTypes: hideControls(),
  render: (args: ListItemIconButtonProps) => {
    return (
      <List>
        <ListItem
          control={<ListItem.IconButton {...args} />}
          title="List item with icon button link"
          subtitle="IconButton rendered as anchor element"
          media={MEDIA.avatarSingle}
        />
      </List>
    );
  },
};
