import { useState } from 'react';
import { Title, Subtitle, Description, Stories } from '@storybook/addon-docs/blocks';
import { Meta, StoryObj } from '@storybook/react-webpack5';
import { action } from 'storybook/actions';
import {
  InfoCircle,
  Documents,
  Warning,
  Home,
  Globe,
  People,
  Link as LinkIcon,
} from '@transferwise/icons';
import { lorem10, lorem100, lorem20, lorem5 } from '../../test-utils';
import Modal from '../../modal';
import Link from '../../link';
import List from '../../list';
import Popover from '../../popover';
import { SnackbarConsumer, type SnackbarContextType } from '../../snackbar/SnackbarContext';
import SnackbarProvider from '../../snackbar/SnackbarProvider';
import Tooltip from '../../tooltip';
import { Position } from '../../common';
import { ListItem, type ListItemProps } from '../ListItem';
import { storySourceWithoutNoise } from './helpers';
import {
  SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
  SB_LIST_ITEM_CONTROLS as CONTROLS,
  SB_LIST_ITEM_MEDIA as MEDIA,
  SB_LIST_ITEM_PROMPTS as PROMPTS,
} from './subcomponents';

export default {
  component: ListItem,
  title: 'Content/ListItem/Common Scenarios',
  tags: ['autodocs'],
  args: {
    title: lorem5,
    subtitle: lorem10,
    media: MEDIA.image,
    additionalInfo: INFO.nonInteractive,
    prompt: PROMPTS.interactive,
    control: CONTROLS.button,
  },
  parameters: {
    docs: {
      page: () => (
        <>
          <Title>Common scenarios</Title>
          <Subtitle />
          <Description />
          <Stories />
        </>
      ),
    },
  },
} satisfies Meta<ListItemProps>;
type Story = StoryObj<ListItemProps>;

/**
 * Aside from using the main control for triggering a [Modal](?path=/docs/dialogs-modal--docs),
 * it's also possible to toggle it via inline-button as part of the `<ListItem.AdditionalInfo>`
 * or `<ListItem.Prompt>`.
 */
export const WithModals: Story = storySourceWithoutNoise({
  parameters: {
    controls: { disable: true },
  },
  render: function WithModals(listItemProps) {
    const [isModalOpen, setIsModalOpen] = useState(false);

    const handleOpening = () => {
      setIsModalOpen(true);
      action('Modal opening')();
    };
    const handleClosing = () => {
      setIsModalOpen(false);
      action('Modal closing')();
    };

    return (
      <List>
        <ListItem
          {...listItemProps}
          control={
            <ListItem.Button partiallyInteractive onClick={handleOpening}>
              Open modal
            </ListItem.Button>
          }
          additionalInfo={
            <ListItem.AdditionalInfo
              action={{ label: 'button opening a modal', onClick: handleOpening }}
            >
              This is additional information that contains a
            </ListItem.AdditionalInfo>
          }
          prompt={
            <ListItem.Prompt sentiment="positive">
              {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
              This prompt also has a <Link onClick={handleOpening}>
                button that opens a modal
              </Link>{' '}
              for your convenience.
            </ListItem.Prompt>
          }
        />
        <Modal body={lorem100} open={isModalOpen} onClose={handleClosing} />
      </List>
    );
  },
});

/**
 * The control or inline buttons can trigger a [Popover](?path=/docs/dialogs-popover--docs).
 */
export const WithPopover: Story = {
  parameters: {
    controls: { disable: true },
  },
  render: (listItemProps) => {
    return (
      <List>
        <ListItem
          {...listItemProps}
          control={
            <Popover preferredPlacement={Position.BOTTOM} title={lorem5} content={lorem20}>
              <ListItem.IconButton
                partiallyInteractive
                aria-label="Learn more about {enter subject here}"
              >
                <InfoCircle />
              </ListItem.IconButton>
            </Popover>
          }
          prompt={PROMPTS.nonInteractive}
        />
      </List>
    );
  },
};

/**
 * The control or inline buttons can trigger a [Tooltip](?path=/docs/dialogs-tooltip--docs).
 */
export const WithTooltip: Story = {
  parameters: {
    controls: { disable: true },
  },
  render: (listItemProps) => {
    return (
      <List>
        <ListItem
          {...listItemProps}
          control={
            <Tooltip position={Position.BOTTOM} label={lorem10}>
              <ListItem.IconButton
                partiallyInteractive
                aria-label="Learn more about {enter subject here}"
              >
                <InfoCircle />
              </ListItem.IconButton>
            </Tooltip>
          }
          prompt={PROMPTS.nonInteractive}
        />
      </List>
    );
  },
};

/**
 * ListItem is often used as a simple copy and paste button augmented with a [Snackbar](?path=/docs/dialogs-snackbar--docs). <br />
 *
 * **NB** The snippet below uses a simplified example implementation of a clipboard handler,
 * which may not be suitable or sufficient for your needs.
 */
export const CopyAndPasteWithSnackbar: Story = storySourceWithoutNoise({
  parameters: {
    controls: { disable: true },
  },
  args: {
    prompt: undefined,
    additionalInfo: undefined,
  },
  render: function CopyAndPaste(listItemProps) {
    const title = 'Artie Choke';
    const subtitle = 'Account holder';

    const handleCopy = async (createSnackbar: SnackbarContextType['createSnackbar']) =>
      navigator.clipboard
        .writeText(`${subtitle}: ${title}`)
        .catch((err) => {
          console.error('Failed to copy text: ', err);
        })
        .then(() => {
          createSnackbar({
            text: `${subtitle} copied to clipboard.`,
          });
        });

    return (
      <List>
        <ListItem
          {...listItemProps}
          title={title}
          subtitle={subtitle}
          inverted
          control={
            <SnackbarProvider>
              <SnackbarConsumer>
                {({ createSnackbar }) => {
                  return (
                    <ListItem.IconButton
                      aria-label={`Copy ${subtitle} to clipboard`}
                      partiallyInteractive
                      onClick={async () => handleCopy(createSnackbar)}
                    >
                      <Documents />
                    </ListItem.IconButton>
                  );
                }}
              </SnackbarConsumer>
            </SnackbarProvider>
          }
          media={
            <ListItem.AvatarView
              imgSrc="../avatar-square-dude.webp"
              profileName="John Smith"
              size={48}
            />
          }
        />
      </List>
    );
  },
});

export const Summary: Story = storySourceWithoutNoise({
  parameters: {
    docs: {
      canvas: {
        sourceState: 'shown',
      },
    },
  },
  render: function Summary() {
    return (
      <List>
        <ListItem
          title="System maintenance"
          subtitle="Scheduled downtime notification"
          media={
            <ListItem.AvatarView size={32}>
              <Warning />
            </ListItem.AvatarView>
          }
          control={
            <ListItem.IconButton partiallyInteractive>
              <InfoCircle />
            </ListItem.IconButton>
          }
        />
        <ListItem
          title="One link, one QR code, many uses"
          subtitle="Quick Pay is a unique link and QR code for your business to get paid online and in person."
          media={
            <ListItem.AvatarView size={32}>
              <LinkIcon />
            </ListItem.AvatarView>
          }
        />
        <ListItem
          title="Action required"
          subtitle="Update your payment address"
          media={
            <ListItem.AvatarView size={32}>
              <Home />
            </ListItem.AvatarView>
          }
          additionalInfo={
            <ListItem.AdditionalInfo
              action={{ label: 'Change Address', onClick: () => console.log('hello') }}
            />
          }
        />
        <ListItem
          title="Action required"
          subtitle="Update your payment address"
          media={
            <ListItem.AvatarView size={32}>
              <Home />
            </ListItem.AvatarView>
          }
          additionalInfo={
            <ListItem.AdditionalInfo
              action={{ label: 'Change Address', onClick: () => console.log('hello') }}
            />
          }
          control={
            <ListItem.IconButton partiallyInteractive>
              <InfoCircle />
            </ListItem.IconButton>
          }
        />
        <ListItem
          title="Receive money from around the world"
          media={
            <ListItem.AvatarView size={32}>
              <Globe />
            </ListItem.AvatarView>
          }
        />
        <ListItem
          title="Let customers pay in a currency they trust"
          media={
            <ListItem.AvatarView size={32}>
              <People />
            </ListItem.AvatarView>
          }
        />
      </List>
    );
  },
});
