import { Meta, StoryObj } from '@storybook/react-webpack5';
import { within, userEvent, expect } from 'storybook/test';
import { Padlock } from '@transferwise/icons';
import { useState } from 'react';

import { createSandboxStory, globalScope } from '../../.storybook/components/sandbox/SandboxEditor';
import MoneyInput, { CurrencyOptionItem } from '.';
import { Field } from '../field/Field';
import translations from '../i18n/en.json';

export default {
  component: MoneyInput,
  title: 'Forms/MoneyInput',
  render: function Render({ id, ...args }) {
    const [selectedCurrency, setSelectedCurrency] = useState(args.selectedCurrency);

    const handleOnCurrencyChange = (value: CurrencyOptionItem) => setSelectedCurrency(value);

    return (
      <Field label="Editable money input label" required id={id}>
        <MoneyInput
          {...args}
          selectedCurrency={selectedCurrency}
          onCurrencyChange={handleOnCurrencyChange}
        />
      </Field>
    );
  },
  args: {
    amount: 1000,
    id: 'moneyInput',
    searchPlaceholder: '',
    onAmountChange: () => {},
    onCurrencyChange: () => {},
  },
  argTypes: {
    searchPlaceholder: {
      table: {
        defaultValue: {
          summary: `"${translations['neptune.MoneyInput.Select.searchPlaceholder']}"`,
        },
      },
    },
  },
} satisfies Meta<typeof MoneyInput>;

type Story = StoryObj<typeof MoneyInput>;

const exampleCurrency = {
  eur: {
    value: 'EUR',
    label: 'EUR',
    note: 'Euro',
    currency: 'eur',
    searchable: 'Spain, Germany, France, Austria',
  },
  gbp: {
    value: 'GBP',
    label: 'GBP',
    note: 'British pound',
    currency: 'gbp',
    searchable: 'England, Scotland, Wales',
  },
  usd: {
    value: 'USD',
    label: 'USD',
    note: 'United States dollar',
    currency: 'usd',
    searchable: 'Hong Kong, Saudi Arabia',
  },
  hkd: {
    value: 'HKD',
    label: 'HKD',
    note: 'Hong Kong dollar',
    currency: 'hkd',
    searchable: 'Hong Kong, Saudi Arabia',
  },
  aud: {
    value: 'AUD',
    label: 'AUD',
    note: 'Australian dollar',
    currency: 'aud',
    searchable: 'Kenguru',
  },
  cny: {
    value: 'CNY',
    label: 'CNY',
    note: 'Chinese yuan',
    currency: 'cny',
    searchable: 'China',
  },
  jpy: {
    value: 'JPY',
    label: 'JPY',
    note: 'Japanese yen',
    currency: 'jpy',
    searchable: 'Japan',
  },
} as const;

const exampleBalanceCurrency = {
  eur: {
    ...exampleCurrency.eur,
    label: '123.45 EUR',
  },
  gbp: {
    ...exampleCurrency.gbp,
    label: '12.34 GBP',
  },
} as const;

export const Sandbox = createSandboxStory({
  code: `const App = () => {
  const currencies = [
    { header: 'Popular currencies' },
    { value: 'EUR', label: 'EUR', note: 'Euro', currency: 'eur', searchable: 'Spain, Germany' },
    { value: 'GBP', label: 'GBP', note: 'British pound', currency: 'gbp', searchable: 'England' },
    { value: 'USD', label: 'USD', note: 'US dollar', currency: 'usd', searchable: 'United States' },
  ];

  const [selectedCurrency, setSelectedCurrency] = React.useState(currencies[1]);
  const [amount, setAmount] = React.useState(1000);

  return (
    <Field label="Amount" id="money-input">
      <MoneyInput
        id="money-input"
        size="lg"
        amount={amount}
        currencies={currencies}
        selectedCurrency={selectedCurrency}
        searchPlaceholder="Type a currency or country"
        onAmountChange={(value) => setAmount(value)}
        onCurrencyChange={(value) => setSelectedCurrency(value)}
      />
    </Field>
  );
};`,
  scope: globalScope,
});

export const SingleCurrency: Story = {
  args: {
    currencies: [],
    selectedCurrency: exampleCurrency.eur,
  },
};

export const MultipleCurrencies: Story = {
  args: {
    addon: <Padlock />,
    currencies: [
      {
        header: 'Popular currencies',
      },
      exampleCurrency.eur,
      exampleCurrency.gbp,
      exampleCurrency.usd,
      exampleCurrency.hkd,
      { header: 'All currencies' },
      exampleCurrency.eur,
      exampleCurrency.gbp,
      exampleCurrency.usd,
      exampleCurrency.aud,
      exampleCurrency.jpy,
    ],
    customActionLabel: 'Custom message with custom action',
    onCustomAction: () => {
      console.log('Custom action');
    },
    selectedCurrency: exampleCurrency.usd,
    id: 'moneyInput',
  },
};

export const BalanceCurrencies: Story = {
  args: {
    currencies: [
      {
        header: 'Balance currencies',
      },
      exampleBalanceCurrency.eur,
      exampleBalanceCurrency.gbp,
    ],
    selectedCurrency: exampleBalanceCurrency.eur,
  },
};

export const WithDecimals: Story = {
  args: {
    currencies: [],
    selectedCurrency: exampleCurrency.eur,
    decimals: 4,
    amount: 1234.1412,
  },
};

export const DisabledOptions: Story = {
  args: {
    currencies: [
      { header: 'Popular currencies' },
      exampleCurrency.eur,
      exampleCurrency.gbp,
      { ...exampleCurrency.usd, disabled: true },
      { header: 'All currencies' },
      exampleCurrency.aud,
      { ...exampleCurrency.cny, disabled: true },
      exampleCurrency.jpy,
    ],
    selectedCurrency: exampleCurrency.eur,
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('combobox'));
  },
};

export const OpenedInput: Story = {
  ...MultipleCurrencies,
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('combobox'));
  },
};

export const SmallInput: Story = {
  render: ({ id, ...args }) => {
    return (
      <>
        <Field label="Money inputs" required>
          <MoneyInput {...args} {...SingleCurrency.args} />
        </Field>
        <br />
        <Field label="Multiple currencies">
          <MoneyInput {...args} {...MultipleCurrencies.args} />
        </Field>
        <hr />
        <Field label="Error state" sentiment="negative" required>
          <MoneyInput {...args} {...SingleCurrency.args} />
        </Field>
        <br />
        <Field label="Multiple currencies: error state" sentiment="negative">
          <MoneyInput {...args} {...MultipleCurrencies.args} />
        </Field>
      </>
    );
  },
  args: {
    size: 'sm',
  },
};

export const MediumInput: Story = {
  ...SmallInput,
  args: {
    size: 'md',
  },
};

export const LargeInput: Story = {
  ...SmallInput,
  args: {
    size: 'lg',
  },
};
