import { Meta, StoryObj } from '@storybook/react-webpack5';
import { Leaf, Taxi } from '@transferwise/icons';
import { lorem10 } from '../../test-utils';
import { ProfileType } from '../../common';
import List from '../../list';
import { ListItem } from '../ListItem';
import {
  SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
  SB_LIST_ITEM_CONTROLS as CONTROLS,
} from '../_stories/subcomponents';
import { disableControls } from '../_stories/helpers';
import type { ListItemAvatarViewProps } from './ListItemAvatarView';

const hideControls = disableControls(['badge', 'children']);

const SIZES = [24, 32, 40, 48, 56, 72] as const;
const BADGES = {
  'Country flag badge': { flagCode: 'GBP' },
  'StatusIcon badge': { status: 'warning' },
  'Icon badge': { icon: <Taxi /> },
  'Default action badge': {
    type: 'action',
  },
  'Default reference badge': {
    type: 'reference',
  },
  'Action badge with custom icon': {
    type: 'action',
    icon: <Taxi />,
  },
  'Reference badge with custom icon': {
    type: 'reference',
    icon: <Taxi />,
  },
  'Custom badge': {
    asset: (
      <div
        className="d-flex align-items-center justify-content-center"
        style={{
          backgroundColor: 'var(--color-bright-pink)',
          color: 'var(--color-interactive-primary)',
          width: '100%',
          height: '100%',
        }}
      >
        <Leaf />
      </div>
    ),
  },
  'Notification badge': { type: 'notification' },
  'Online badge': { type: 'online' },
} as const;

export default {
  component: ListItem.AvatarView,
  title: 'Content/ListItem/ListItem.AvatarView',
  args: {
    size: 48,
    selected: false,
    badge: { type: 'action' },
    profileName: undefined,
    profileType: undefined,
    imgSrc: undefined,
  },
  argTypes: {
    size: {
      control: 'select',
      options: SIZES,
      description: 'Size of the avatar',
    },
    profileName: {
      control: 'text',
      description: 'Name used to generate initials when no image or icon is provided',
    },
    imgSrc: {
      control: 'text',
      description: 'URL of the profile image',
    },
    profileType: {
      control: 'select',
      options: [ProfileType.PERSONAL, ProfileType.BUSINESS],
      description: 'Type of profile for default icons',
      table: {
        type: { summary: 'ProfileType' },
      },
    },
    badge: {
      control: 'select',
      options: ['action', 'notification', 'online'],
      description: 'Badge type',
      mapping: {
        action: { type: 'action' },
        notification: { type: 'notification' },
        online: { type: 'online' },
      },
      table: {
        type: { summary: 'AvatarViewBadgeProps' },
      },
    },
    selected: {
      control: 'boolean',
      description: 'Toggles selected state',
    },
    children: {
      table: {
        type: { summary: 'ReactNode' },
      },
    },
    style: {
      table: {
        disable: true,
      },
    },
  },
} satisfies Meta<ListItemAvatarViewProps>;

type Story = StoryObj<ListItemAvatarViewProps>;

export const Playground: Story = {
  render: (args: ListItemAvatarViewProps) => {
    return (
      <List>
        <ListItem
          title="John Smith"
          subtitle="Personal account"
          media={<ListItem.AvatarView {...args} />}
          control={CONTROLS.iconButton}
          additionalInfo={INFO.nonInteractive}
        />
      </List>
    );
  },
};

/**
 * AvatarView can display different types of content including icons, profile images, and initials. <br />
 * Refer to the [design documentation](https://wise.design/components/avatar#:~:text=56%2C%20%E2%80%A8and%2072.-,Media,-There%20are%204) for details.
 */
export const ContentTypes: Story = {
  args: {
    badge: undefined,
  },
  argTypes: hideControls(['profileName', 'imgSrc', 'profileType']),
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  render: (args) => {
    return (
      <List>
        <ListItem
          title="With icon"
          subtitle="Default icon content"
          media={
            <ListItem.AvatarView {...args}>
              <Taxi />
            </ListItem.AvatarView>
          }
          control={CONTROLS.iconButton}
        />

        <ListItem
          title="With profile image"
          subtitle="User profile picture."
          media={
            <ListItem.AvatarView
              {...args}
              imgSrc="../avatar-square-dude.webp"
              profileName="John Smith"
            />
          }
          control={CONTROLS.iconButton}
        />

        <ListItem
          title="With initials"
          subtitle="Fallback for when no profile image is available."
          media={<ListItem.AvatarView {...args} profileName="Sarah Johnson" />}
          control={CONTROLS.iconButton}
        />

        <ListItem
          title="Business profile"
          subtitle="Fallback for when no logo is available"
          media={<ListItem.AvatarView {...args} profileType={ProfileType.BUSINESS} />}
          control={CONTROLS.iconButton}
        />

        <ListItem
          title="Personal profile"
          subtitle="Fallback for when no personal data is available or when image fails to load."
          media={
            <ListItem.AvatarView
              {...args}
              profileType={ProfileType.PERSONAL}
              profileName="Alex Chen"
            />
          }
          control={CONTROLS.iconButton}
        />
      </List>
    );
  },
};

/**
 * AvatarView supports 6 sizes to fit different list item contexts: `24`, `32`, `40`, `48`, `56`, `72`. If decorated with a Badge, those will be sized accordingly as well. <br />
 * Please refer to the [design documentation](https://wise.design/components/list-item#avatar:~:text=of%20the%20avatar.-,Avatar%20sizes,-List%20item%20supports) for details on when to use which one.
 */
export const Sizes: Story = {
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  argTypes: hideControls(['profileName', 'imgSrc', 'profileType', 'size']),
  render: (args) => {
    return (
      <List>
        {SIZES.map((size) => (
          <ListItem
            key={size}
            title={`Size ${size}`}
            subtitle={lorem10}
            media={
              <ListItem.AvatarView {...args} size={size}>
                <Taxi />
              </ListItem.AvatarView>
            }
            control={CONTROLS.iconButton}
          />
        ))}
      </List>
    );
  },
};

/**
 * AvatarView supports different types of badges for additional context and information. <br />
 * Refer to the [design documentation](https://wise.design/components/avatar#:~:text=support%20the%20information.-,With%20badge,-Badges%20contain%20additional) for details.
 */
export const Badges: Story = {
  args: {
    imgSrc: '../avatar-square-dude.webp',
  },
  argTypes: hideControls([
    'profileName',
    'imgSrc',
    'profileType',
    'notification',
    'dot',
    'selected',
  ]),
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  render: (args) => {
    return (
      <List>
        {Object.entries(BADGES).map(([title, badge]) => (
          <ListItem
            key={title}
            title={title}
            subtitle={lorem10}
            media={<ListItem.AvatarView {...args} badge={badge} />}
            control={CONTROLS.iconButton}
          />
        ))}
      </List>
    );
  },
};

/**
 * `notification` is a particular `type` of Badge that appears in the top right corner as a red dot. It also adjusts to the Avatar's size. <br />
 * **NB:** You can only choose one badge at a time, so the notification badge cannot be combined with any other badge type.
 */
export const Notification: Story = {
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  args: {
    badge: undefined,
  },
  argTypes: hideControls([
    'profileName',
    'imgSrc',
    'profileType',
    'size',
    'notification',
    'dot',
    'selected',
  ]),
  render: (args) => {
    return (
      <List>
        {SIZES.map((size) => (
          <ListItem
            key={size}
            title={`Size ${size}`}
            subtitle={lorem10}
            media={
              <ListItem.AvatarView {...args} size={size} badge={{ type: 'notification' }}>
                <Taxi />
              </ListItem.AvatarView>
            }
            control={CONTROLS.iconButton}
          />
        ))}
      </List>
    );
  },
};

/**
 * Similarly, Badge also has an `online` `type` which is green and also adjusts to the Avatar's size. <br />
 * **NB:** You can only choose one badge at a time, so the online badge cannot be combined with any other badge type.
 */
export const Online: Story = {
  tags: ['new'],
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  args: {
    badge: undefined,
  },
  argTypes: hideControls([
    'profileName',
    'imgSrc',
    'profileType',
    'size',
    'notification',
    'selected',
  ]),
  render: (args) => {
    return (
      <List>
        {SIZES.map((size) => (
          <ListItem
            key={size}
            title={`Size ${size}`}
            subtitle={lorem10}
            media={
              <ListItem.AvatarView {...args} size={size} badge={{ type: 'online' }}>
                <Taxi />
              </ListItem.AvatarView>
            }
            control={CONTROLS.iconButton}
          />
        ))}
      </List>
    );
  },
};

/**
 * AvatarView supports selected state for interactive contexts.
 */
export const Selected: Story = {
  argTypes: hideControls([
    'profileName',
    'imgSrc',
    'profileType',
    'notification',
    'dot',
    'selected',
  ]),
  render: (args) => {
    return (
      <List>
        <ListItem
          title="Selected state"
          subtitle="Currently selected item"
          media={<ListItem.AvatarView profileName="Alex Chen" selected />}
          control={CONTROLS.iconButton}
        />
      </List>
    );
  },
};
