import { Meta, StoryObj } from '@storybook/react-webpack5';
import { action } from 'storybook/actions';
import { lorem10, lorem5 } from '../../test-utils';
import Link from '../../link';
import List from '../../list';
import { Sentiment as Sentiments } from '../../common';
import { withoutKey } from '../_stories/helpers';
import {
  SB_LIST_ITEM_CONTROLS as CONTROLS,
  SB_LIST_ITEM_MEDIA as MEDIA,
} from '../_stories/subcomponents';
import { ListItem } from '../ListItem';
import { Prompt, type ListItemPromptProps } from './ListItemPrompt';
import { Clock } from '@transferwise/icons';

const meta: Meta<ListItemPromptProps> = {
  component: Prompt,
  title: 'Content/ListItem/ListItem.Prompt',

  decorators: [withoutKey],
  args: {
    sentiment: undefined,
    mediaLabel: undefined,
    children: 'You have done a terrible thing',
  },
  argTypes: {
    sentiment: {
      options: [
        'unset (undefined)',
        Sentiments.POSITIVE,
        Sentiments.NEGATIVE,
        Sentiments.NEUTRAL,
        Sentiments.WARNING,
      ],
      mapping: {
        'unset (undefined)': undefined,
      },
      control: { type: 'radio' },
    },
    children: {
      table: {
        type: { summary: 'ReactNode' },
      },
    },
  },
};

export default meta;

type Story = StoryObj<ListItemPromptProps>;

export const Playground: Story = {
  parameters: {
    docs: {
      source: 'dynamic',
    },
  },
  render: (args) => (
    <List>
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={<ListItem.Prompt {...args} />}
      />
    </List>
  ),
};

export const Sentiment: Story = {
  parameters: {
    controls: { disable: true },
    actions: { disable: true },
    a11y: { disable: true },
    knobs: { disable: true },
  },
  render: (args) => (
    <List>
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.NEUTRAL}>
            This is a neutral prompt.
          </ListItem.Prompt>
        }
      />
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.POSITIVE}>
            This is a positive prompt.
          </ListItem.Prompt>
        }
      />
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.WARNING}>
            This is a warning prompt.
          </ListItem.Prompt>
        }
      />
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.NEGATIVE}>
            This is a negative prompt.
          </ListItem.Prompt>
        }
      />
    </List>
  ),
};

/**
 * While all main sentiments (`warning`, `negative`, `positive` and `neutral`) are associated with a
 * default `StatusIcon`s, we also allow for Icon overrides to bring the prompt's visual language
 * closer to the prompt's content. <br /><br />
 * It's also possible to override the default StatusIcon's accessible name announced by screen
 * readers via `mediaLabel` prop, which is especially useful for the `proposition` sentiment.
 * <br /><br />
 * **NB**: If you're setting a label on a custom Icon, the accessible name should be provided via
 * Icon's `title` prop instead.
 */
export const IconOverrides: Story = {
  parameters: {
    controls: { disable: true },
    actions: { disable: true },
    a11y: { disable: true },
    knobs: { disable: true },
  },
  render: (args) => (
    <List>
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.WARNING} mediaLabel="Processing: ">
            This prompt uses default Icon, but with a custom label for screen readers.
          </ListItem.Prompt>
        }
      />
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.WARNING} media={<Clock title="Processing: " />}>
            This prompt uses custom Icon with a custom label for screen readers.
          </ListItem.Prompt>
        }
      />
    </List>
  ),
};

/**
 * `ListItem.Prompt` is rendered on a separate branch of the Accessibility Tree from the item's
 * control, so it can include a single instance of `Link` component, which can be rendered as
 * either HTML anchor or button. That element will spread across the whole surface of the Prompt
 * so it's easily accessible for all users.
 */
export const Interactivity: Story = {
  argTypes: {
    children: {
      table: {
        disable: true,
      },
    },
  },
  render: (args) => (
    <List>
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={args.sentiment}>
            This prompt includes a{' '}
            <Link href="https://wise.com" target="_blank" rel="noreferrer">
              link to some resource
            </Link>{' '}
            to help the user in their journey.
          </ListItem.Prompt>
        }
      />

      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.avatarSingle}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={args.sentiment}>
            {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
            This prompt includes an <Link onClick={action('inline button')}>
              inline button
            </Link>{' '}
            than can e.g. trigger a modal.
          </ListItem.Prompt>
        }
      />
    </List>
  ),
};

/**
 * By default, the Prompt will try to occupy as little space as possible, but as soon as you make it more than 1 line long, it will stretch to the full available width.
 *
 * **NB:** While Prompt supports multi-line text, its content should be concise and have no more than 2 short sentences so users can quickly understand the message.
 */
export const Sizing: Story = {
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  render: (args) => (
    <List>
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.image}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.POSITIVE}>This is a short text</ListItem.Prompt>
        }
      />
      <ListItem
        title={lorem5}
        subtitle={lorem10}
        media={MEDIA.image}
        control={CONTROLS.switch}
        prompt={
          <ListItem.Prompt sentiment={Sentiments.WARNING}>
            This is a very, very, very, very, very long text that will wrap into more than 1 line
            and will make the prompt stretch to a full available width. Technically it can be as
            long as Vim manual, but we recommend keeping it concise and no more than 2 short
            sentences.
          </ListItem.Prompt>
        }
      />
    </List>
  ),
};
