import { Meta, StoryObj } from '@storybook/react-webpack5';
import {
  ArrowLeft,
  Cross,
  Edit,
  Menu,
  Plus,
  Cog,
  Star,
  Suitcase,
  Briefcase,
  Bank,
  Freeze,
} from '@transferwise/icons';
import { fn } from 'storybook/test';
import { createSandboxStory, globalScope } from '../../.storybook/components/sandbox/SandboxEditor';
import IconButton, { Props } from './IconButton';
import SentimentSurface from '../sentimentSurface';

/**
 * **Design guidance**: <a href="https://docs.wise.design/components/icon-button" target="_blank">wise.design/components/icon-button</a>
 */
export default {
  title: 'Actions/IconButton',
  component: IconButton,
  args: {
    onClick: fn(),
    'aria-label': 'Action',
  },
  argTypes: {
    id: { table: { category: 'Common' } },
    className: { table: { category: 'Common' } },
    role: { table: { category: 'Common' } },
    tabIndex: { table: { category: 'Common' } },
    'data-testid': { table: { category: 'Common' } },
    onClick: { table: { category: 'Common' } },
  },
  parameters: {
    docs: { toc: true },
  },
} satisfies Meta<typeof IconButton>;

type Story = StoryObj<typeof IconButton>;

const sizes: Props['size'][] = [16, 24, 32, 40, 48, 56, 72];

/**
 * Explore size, priority, type, and disabled state via the controls panel.
 * Use `aria-label` to provide an accessible name.
 */
export const Playground: Story = {
  args: {
    size: 48,
    priority: 'primary',
    type: 'default',
    disabled: false,
  },
  render: (args) => (
    <IconButton {...args}>
      <Plus />
    </IconButton>
  ),
};

export const Sandbox = createSandboxStory({
  code: `<IconButton
  size={48}
  priority="primary"
  type="default"
  aria-label="Add item"
  onClick={() => console.log('clicked')}
>
  <Plus />
</IconButton>`,
  scope: globalScope,
});

/**
 * Priorities set a visual hierarchy amongst the buttons displayed on the
 * screen to help more important buttons to take precedence over others. <br />
 * <a href="https://docs.wise.design/components/icon-button#priorities" target="_blank">Design documentation</a>
 */
export const Priority: Story = {
  args: {
    type: 'default',
  },
  argTypes: {
    type: {
      control: 'radio',
      options: ['default', 'negative'],
    },
    priority: { table: { disable: true } },
    size: { table: { disable: true } },
    disabled: { table: { disable: true } },
    href: { table: { disable: true } },
    target: { table: { disable: true } },
    onClick: { table: { disable: true } },
  },
  decorators: [
    (Story) => (
      <div style={{ display: 'flex', gap: '24px', alignItems: 'center', justifyContent: 'center' }}>
        <Story />
      </div>
    ),
  ],
  render: (args: Props) => (
    <>
      <IconButton priority="primary" type={args.type} aria-label="Primary" onClick={fn()}>
        <Plus />
      </IconButton>
      <IconButton priority="secondary" type={args.type} aria-label="Secondary" onClick={fn()}>
        <Cog />
      </IconButton>
      <IconButton priority="tertiary" type={args.type} aria-label="Tertiary" onClick={fn()}>
        <Star />
      </IconButton>
      <IconButton priority="minimal" type={args.type} aria-label="Minimal" onClick={fn()}>
        <Menu />
      </IconButton>
    </>
  ),
};

/**
 * There are two different types of button – default and negative – designed to emphasise the nature of the action. <br />
 * <a href="https://docs.wise.design/components/icon-button#types" target="_blank">Design documentation</a>
 */
export const Type: Story = {
  args: {
    priority: 'primary',
  },
  argTypes: {
    priority: {
      control: 'radio',
      options: ['primary', 'secondary', 'tertiary', 'minimal'],
    },
    type: { table: { disable: true } },
    size: { table: { disable: true } },
    disabled: { table: { disable: true } },
    href: { table: { disable: true } },
    target: { table: { disable: true } },
    onClick: { table: { disable: true } },
  },
  decorators: [
    (Story) => (
      <div style={{ display: 'flex', gap: '24px', alignItems: 'center', justifyContent: 'center' }}>
        <Story />
      </div>
    ),
  ],
  render: (args: Props) => (
    <>
      <IconButton priority={args.priority} type="default" aria-label="Default" onClick={fn()}>
        <Plus />
      </IconButton>
      <IconButton priority={args.priority} type="negative" aria-label="Negative" onClick={fn()}>
        <Cross />
      </IconButton>
    </>
  ),
};

/**
 * IconButton is available in 7 sizes: 16, 24, 32, 40, 48, 56, 72. <br />
 * <a href="https://docs.wise.design/components/icon-button#sizes" target="_blank">Design documentation</a>
 */
export const Size: Story = {
  args: {
    priority: 'primary',
    type: 'default',
  },
  argTypes: {
    priority: {
      control: 'radio',
      options: ['primary', 'secondary', 'tertiary', 'minimal'],
    },
    type: {
      control: 'radio',
      options: ['default', 'negative'],
    },
    size: { table: { disable: true } },
    disabled: { table: { disable: true } },
    href: { table: { disable: true } },
    target: { table: { disable: true } },
    onClick: { table: { disable: true } },
  },
  decorators: [
    (Story) => (
      <div style={{ display: 'flex', gap: '24px', alignItems: 'center' }}>
        <Story />
      </div>
    ),
  ],
  render: (args: Props) => (
    <>
      {sizes.map((size) => (
        <div
          key={size}
          style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}
        >
          <IconButton
            size={size}
            priority={args.priority}
            type={args.type}
            aria-label={`${size}px`}
          >
            <ArrowLeft />
          </IconButton>
          <span style={{ fontSize: '12px' }}>{size}px</span>
        </div>
      ))}
    </>
  ),
  parameters: {
    docs: {
      source: {
        code: `{[16, 24, 32, 40, 48, 56, 72].map((size) => (
  <div key={size}>
    <IconButton size={size} priority="primary" type="default" aria-label={\`\${size}px\`}>
      <ArrowLeft />
    </IconButton>
    <span>{size}px</span>
  </div>
))}`,
      },
    },
  },
};

/**
 * Disabled buttons cannot be interacted with and are visually distinct.
 */
export const Disabled: Story = {
  args: {
    priority: 'primary',
    type: 'default',
  },
  argTypes: {
    priority: {
      control: 'radio',
      options: ['primary', 'secondary', 'tertiary', 'minimal'],
    },
    type: {
      control: 'radio',
      options: ['default', 'negative'],
    },
    size: { table: { disable: true } },
    disabled: { table: { disable: true } },
    href: { table: { disable: true } },
    target: { table: { disable: true } },
    onClick: { table: { disable: true } },
  },
  render: (args: Props) => (
    <IconButton disabled priority={args.priority} type={args.type} aria-label="Disabled">
      <Plus />
    </IconButton>
  ),
};

/**
 * IconButton can render as an anchor element when `href` is provided.
 */
export const AsAnchor: Story = {
  args: {
    priority: 'primary',
    type: 'default',
    href: 'https://wise.com',
    target: '_blank',
  },
  argTypes: {
    priority: {
      control: 'radio',
      options: ['primary', 'secondary', 'tertiary', 'minimal'],
    },
    type: {
      control: 'radio',
      options: ['default', 'negative'],
    },
    size: { table: { disable: true } },
    disabled: { table: { disable: true } },
    onClick: { table: { disable: true } },
  },
  render: (args: Props) => (
    <IconButton {...args} aria-label="External link">
      <ArrowLeft />
    </IconButton>
  ),
};

/**
 * `IconButton` is sentiment-aware and will automatically adjust its colours if wrapped inside
 * the [SentimentSurface](?path=/docs/foundations-sentimentsurface--docs) component
 */
export const SentimentAwareness: Story = {
  args: {
    size: 48,
  },
  argTypes: {
    size: {
      control: 'radio',
      options: [16, 24, 32, 40, 48, 56, 72],
    },
  },
  render: (args: Props) => {
    const priorities = [
      { key: 'primary', label: 'primary' },
      { key: 'secondary', label: 'secondary' },
      { key: 'tertiary', label: 'tertiary' },
      { key: 'minimal', label: 'minimal' },
      { key: 'neg-primary', label: 'negative\nprimary' },
      { key: 'neg-secondary', label: 'negative\nsecondary' },
      { key: 'disabled', label: 'disabled' },
    ] as const;
    const sentiments = ['success', 'warning', 'negative', 'neutral', 'proposition'] as const;

    return (
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {/* Header row with priority labels */}
        <div style={{ display: 'flex', alignItems: 'flex-end', marginBottom: '4px', gap: '8px' }}>
          <div style={{ width: '82px', paddingLeft: '8px' }} />
          {priorities.map((priority) => (
            <div
              key={priority.key}
              style={{
                width: `${args.size}px`,
                textAlign: 'center',
                fontSize: '11px',
                fontWeight: 'bold',
                writingMode: 'vertical-rl',
                transform: 'rotate(180deg)',
                height: '80px',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                whiteSpace: 'pre',
                lineHeight: '1',
              }}
            >
              {priority.label}
            </div>
          ))}
        </div>

        {/* Rows for each sentiment with base and elevated emphasis */}
        {sentiments.flatMap((sentiment) => [
          <SentimentSurface
            key={`${sentiment}-base`}
            sentiment={sentiment}
            emphasis="base"
            style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
          >
            <div
              style={{
                width: '82px',
                fontSize: '11px',
                fontWeight: 'bold',
                textAlign: 'left',
                paddingLeft: '8px',
              }}
            >
              {sentiment} (base)
            </div>
            <IconButton
              size={args.size}
              aria-label="Primary action"
              priority="primary"
              type="default"
              onClick={fn()}
            >
              <Plus />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Secondary action"
              priority="secondary"
              type="default"
              onClick={fn()}
            >
              <Cog />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Tertiary action"
              priority="tertiary"
              type="default"
              onClick={fn()}
            >
              <Star />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Minimal action"
              priority="minimal"
              type="default"
              onClick={fn()}
            >
              <Suitcase />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Negative primary action"
              priority="primary"
              type="negative"
              onClick={fn()}
            >
              <Cross />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Negative secondary action"
              priority="secondary"
              type="negative"
              onClick={fn()}
            >
              <Edit />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Disabled action"
              priority="primary"
              type="default"
              disabled
              onClick={fn()}
            >
              <Menu />
            </IconButton>
          </SentimentSurface>,
          <SentimentSurface
            key={`${sentiment}-elevated`}
            sentiment={sentiment}
            emphasis="elevated"
            style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
          >
            <div
              style={{
                width: '82px',
                fontSize: '11px',
                fontWeight: 'bold',
                textAlign: 'left',
                paddingLeft: '8px',
              }}
            >
              {sentiment} (elevated)
            </div>
            <IconButton
              size={args.size}
              aria-label="Primary action"
              priority="primary"
              type="default"
              onClick={fn()}
            >
              <Briefcase />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Secondary action"
              priority="secondary"
              type="default"
              onClick={fn()}
            >
              <Bank />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Tertiary action"
              priority="tertiary"
              type="default"
              onClick={fn()}
            >
              <Freeze />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Minimal action"
              priority="minimal"
              type="default"
              onClick={fn()}
            >
              <Edit />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Negative primary action"
              priority="primary"
              type="negative"
              onClick={fn()}
            >
              <Cross />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Negative secondary action"
              priority="secondary"
              type="negative"
              onClick={fn()}
            >
              <Edit />
            </IconButton>
            <IconButton
              size={args.size}
              aria-label="Disabled action"
              priority="primary"
              type="default"
              disabled
              onClick={fn()}
            >
              <Cross />
            </IconButton>
          </SentimentSurface>,
        ])}
      </div>
    );
  },
  parameters: {
    docs: {
      canvas: { sourceState: 'hidden' },
    },
  },
};
