import type { Meta, StoryObj } from '@storybook/react-webpack5';
import { fn } from 'storybook/test';
import { useState } from 'react';

import Chips, { type ChipValue, type ChipsProps } from './Chips';
import { storySourceWithoutNoise } from '../../.storybook/helpers';

/**
 * Can be used for making a <a href="?path=/story/actions-chips--choice">choice</a>, or as a <a href="?path=/story/actions-chips--filter">filter</a> with multiple options.
 *
 * **Design guidance**: <a href="https://wise.design/components/chip" target="_blank">wise.design/components/chip</a>
 */
export default {
  component: Chips,
  title: 'Actions/Chips',
  args: {
    multiple: false,
    onChange: fn(),
    'aria-label': 'Category filter',
  },
  argTypes: {
    'aria-label': {
      control: 'text',
      description: 'Provides the accessible name for the chip group.',
    },
    className: { table: { category: 'Common' } },
  },
  parameters: {
    docs: { toc: true },
  },
} satisfies Meta<typeof Chips>;

type Story = StoryObj<typeof Chips>;

const categoryChips = [
  { value: 'all', label: 'All' },
  { value: 'accounting', label: 'Accounting' },
  { value: 'payroll', label: 'Payroll' },
  { value: 'reporting', label: 'Reporting' },
  { value: 'payments', label: 'Payments' },
];

const amountChips = [
  { value: 100, label: '100 GBP' },
  { value: 200, label: '200 GBP' },
  { value: 300, label: '300 GBP' },
  { value: 500, label: '500 GBP+' },
];

/**
 * Toggle `multiple` in the controls panel to switch between filter (multi-select)
 * and choice (single-select) modes.
 */
export const Playground: Story = storySourceWithoutNoise<typeof Chips>({
  args: {
    chips: categoryChips,
    multiple: true,
  },
  render: function Render(args: ChipsProps) {
    const [selectedMulti, setSelectedMulti] = useState<readonly ChipValue[]>(['accounting']);
    const [selectedSingle, setSelectedSingle] = useState<ChipValue>('accounting');

    if (args.multiple) {
      return (
        <Chips
          chips={args.chips}
          multiple
          selected={selectedMulti}
          aria-label={args['aria-label']}
          onChange={({ selectedValue, isEnabled }) => {
            setSelectedMulti((prev) =>
              isEnabled ? [...prev, selectedValue] : prev.filter((v) => v !== selectedValue),
            );
            args.onChange({ selectedValue, isEnabled });
          }}
        />
      );
    }

    return (
      <Chips
        chips={args.chips}
        selected={selectedSingle}
        aria-label={args['aria-label']}
        onChange={({ selectedValue, isEnabled }) => {
          setSelectedSingle(selectedValue);
          args.onChange({ selectedValue, isEnabled });
        }}
      />
    );
  },
});

/**
 * The user can select any number of chips with the selected prop as an array (`multiple` prop set to `true`). <br />
 * <a href="https://wise.design/components/chip#filter-chips" target="_blank">Design documentation</a>
 */
export const Filter: Story = storySourceWithoutNoise<typeof Chips>({
  args: {
    chips: categoryChips,
  },
  argTypes: {
    multiple: { table: { disable: true } },
  },
  render: function Render(args: ChipsProps) {
    const [selected, setSelected] = useState<readonly ChipValue[]>(['accounting', 'payments']);

    return (
      <Chips
        chips={args.chips}
        selected={selected}
        multiple
        aria-label="Category filter"
        onChange={({ selectedValue, isEnabled }) => {
          setSelected((prev) =>
            isEnabled ? [...prev, selectedValue] : prev.filter((v) => v !== selectedValue),
          );
          args.onChange({ selectedValue, isEnabled });
        }}
      />
    );
  },
});

/**
 * The user can only select one chip with the selected prop as a single value (`multiple` prop set to `false`). <br />
 * <a href="https://wise.design/components/chip#choice-chips" target="_blank">Design documentation</a>
 */
export const Choice: Story = storySourceWithoutNoise<typeof Chips>({
  args: {
    chips: amountChips,
  },
  argTypes: {
    multiple: { table: { disable: true } },
  },
  render: function Render(args: ChipsProps) {
    const [selected, setSelected] = useState<ChipValue>(300);

    return (
      <Chips
        chips={args.chips}
        selected={selected}
        aria-label="Transfer amount"
        onChange={({ selectedValue, isEnabled }) => {
          setSelected(selectedValue);
          args.onChange({ selectedValue, isEnabled });
        }}
      />
    );
  },
});
