/* eslint-disable jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
import { Meta, StoryObj, Decorator } from '@storybook/react-webpack5';
import { fn } from 'storybook/test';
import { Flag } from '@wise/art';
import { Rewards, Tags } from '@transferwise/icons';
import { createSandboxStory, globalScope } from '../../.storybook/components/sandbox/SandboxEditor';
import { storySourceWithoutNoise } from '../../.storybook/helpers';
import { lorem10, lorem5 } from '../test-utils';
import { Sentiment } from '../common';
import Link from '../link';
import Money from '../money';
import React from 'react';
import Button from '../button';
import Modal from '../modal';
import ListItem from '../listItem';
import List from '../list';
import ExpressiveMoneyInput, { Props as ExpressiveMoneyInputProps } from './ExpressiveMoneyInput';
import type { Props as CurrencySelectorProps } from './currencySelector/CurrencySelector';

const getCurrencySelectorProps = ({
  logEvents = false,
  secondAvatar = false,
} = {}): Partial<CurrencySelectorProps> => ({
  addons: secondAvatar ? [{ profileName: 'Mikkael Jordan' }] : undefined,
  options: [
    {
      title: 'Popular',
      currencies: [
        { code: 'USD', label: 'US Dollar', keywords: ['dollar', 'us'] },
        { code: 'AUD', label: 'Australia Dollar', keywords: ['dollar', 'us'] },
      ],
    },
    {
      title: 'Others',
      currencies: [
        { code: 'GBP', label: 'Pound', keywords: ['british'] },
        { code: 'EUR', label: 'Euro', keywords: ['euro'] },
      ],
    },
  ],
  onOpen: logEvents ? fn() : () => {},
  onSearchChange: logEvents ? fn() : (payload) => {},
  onChange: logEvents ? fn() : (currency) => {},
});

const withScrollbarProtector: Decorator = (Story) => (
  <>
    <style>{`.docs-story > div {overflow-y:hidden;}`}</style>
    <Story />
  </>
);

export default {
  title: 'Forms/ExpressiveMoneyInput',
  component: ExpressiveMoneyInput,
  tags: ['early-access', 'contribution'],
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
  args: {
    label: 'You send',
    currency: 'GBP',
    amount: 1234.56,
    currencySelector: getCurrencySelectorProps(),
    loading: false,
    inlinePrompt: { message: lorem10, sentiment: Sentiment.POSITIVE },
    showChevron: false,
    autoFocus: false,
    onAmountChange: fn(),
    onFocusChange: fn(),
  },
  decorators: [withScrollbarProtector],
} satisfies Meta<ExpressiveMoneyInputProps>;

type Story = StoryObj<ExpressiveMoneyInputProps>;

export const Playground: Story = {
  render: (args: ExpressiveMoneyInputProps) => <ExpressiveMoneyInput {...args} />,
};

export const Sandbox = createSandboxStory({
  code: `const App = () => {
  const [amount, setAmount] = React.useState(1234.56);
  const [currency, setCurrency] = React.useState('GBP');

  return (
    <ExpressiveMoneyInput
      label="You send"
      amount={amount}
      currency={currency}
      onAmountChange={(value) => setAmount(value)}
      currencySelector={{
        options: [
          {
            title: 'Popular',
            currencies: [
              { code: 'GBP', label: 'British pound', keywords: ['british'] },
              { code: 'EUR', label: 'Euro', keywords: ['euro'] },
              { code: 'USD', label: 'US Dollar', keywords: ['dollar'] },
            ],
          },
        ],
        onChange: (selected) => setCurrency(selected.code),
        onSearchChange: () => {},
        onOpen: () => {},
      }}
      inlinePrompt={{ message: 'Low cost transfer', sentiment: 'positive' }}
    />
  );
};`,
  scope: globalScope,
});

export const WithInitialAmount = {
  args: {
    amount: 1500,
    inlinePrompt: undefined,
  },
};

export const NullAmount = {
  args: {
    amount: null,
    inlinePrompt: undefined,
    currencySelector: getCurrencySelectorProps({ logEvents: true }),
  },
};

export const WithLoading = {
  args: {
    loading: true,
  },
};

/**
 * The chevron should be visible only when the input is inactive
 * and the current value is 0 or null.
 */
export const WithChevron = {
  args: {
    showChevron: true,
    amount: 0,
  },
};

export const WithBalanceText = storySourceWithoutNoise<ExpressiveMoneyInputProps>({
  args: {
    currencySelector: getCurrencySelectorProps({ logEvents: true }),
  },
  render: function Render(args: ExpressiveMoneyInputProps) {
    const availableBalance = 1500;
    const [sourceAmount, setSourceAmount] = React.useState(args.amount);
    return (
      <ExpressiveMoneyInput
        {...args}
        amount={sourceAmount}
        inlinePrompt={{
          message: (
            <>
              {`Available balance `}
              <Link
                onClick={() => {
                  setSourceAmount(availableBalance);
                }}
              >
                <Money amount={availableBalance} currency={args.currency} />
              </Link>
            </>
          ),
        }}
      />
    );
  },
});

export const WithInlinePromptSentiment = {
  render: (args: ExpressiveMoneyInputProps) => {
    const inlinePrompts = [
      { message: lorem5, sentiment: 'negative' },
      { message: lorem5, sentiment: 'warning' },
      { message: lorem5, sentiment: 'neutral' },
      { message: lorem5, sentiment: 'positive' },
      { message: lorem5, sentiment: 'positive', media: <Tags /> },
      { message: lorem5, sentiment: 'proposition' },
      { message: lorem5, sentiment: 'proposition', media: <Rewards /> },
    ] as const;

    return inlinePrompts.map((inlinePrompt, index) => (
      <ExpressiveMoneyInput key={index} {...args} inlinePrompt={inlinePrompt} />
    ));
  },
};

export const WithFormattedCurrencyCode = {
  args: {
    currency: 'USC',
    currencySelector: {
      ...getCurrencySelectorProps({ logEvents: true }),
      options: [
        {
          title: 'Popular',
          currencies: [
            { code: 'USC', label: 'Digital Dollar', keywords: ['USDC', 'Digital Dollar'] },
            { code: 'USD', label: 'US Dollar', keywords: ['dollar', 'us'] },
          ],
        },
      ],
    },
  },
};

export const WithSecondaryCurrencySelectorAvatar = {
  args: {
    currencySelector: getCurrencySelectorProps({ logEvents: true, secondAvatar: true }),
  },
};

export const WithCustomCurrencySelector = {
  render: (args: ExpressiveMoneyInputProps) => {
    const [open, setOpen] = React.useState(false);
    return (
      <>
        <ExpressiveMoneyInput
          {...args}
          currencySelector={{
            customRender: ({ id, labelId }) => (
              <Button
                v2
                size="sm"
                priority="primary"
                aria-describedby={labelId}
                onClick={() => setOpen(true)}
              >
                Currency Selector
              </Button>
            ),
          }}
        />
        <Modal
          open={open}
          title="Custom UX for currency selectors"
          body={
            <List>
              <ListItem
                media={
                  <ListItem.AvatarView>
                    <Flag code="gb" />
                  </ListItem.AvatarView>
                }
                title="GBP"
                control={<ListItem.Radio name="currency-key" checked={false} />}
              />
              <ListItem
                media={
                  <ListItem.AvatarView>
                    <Flag code="au" />
                  </ListItem.AvatarView>
                }
                title="AUD"
                control={<ListItem.Radio name="currency-key" checked />}
              />
            </List>
          }
          onClose={() => setOpen(false)}
        />
      </>
    );
  },
};
