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

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

export default {
  component: Chips,
  title: 'Actions/Chips/Tests',
  tags: ['!autodocs', '!manifest'],
} satisfies Meta<typeof Chips>;

type Story = StoryObj<typeof Chips>;

const wait = async (ms: number) =>
  new Promise<void>((resolve) => {
    setTimeout(resolve, ms);
  });

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

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

/** Filter and choice chips across all themes. */
export const Variants: Story = {
  render: function Render() {
    const [filterSelected, setFilterSelected] = useState<readonly ChipValue[]>([
      'accounting',
      'payments',
    ]);
    const [choiceSelected, setChoiceSelected] = useState<ChipValue>(300);

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
        <Chips
          chips={filterChips}
          multiple
          selected={filterSelected}
          aria-label="Category filter"
          onChange={({ selectedValue, isEnabled }) => {
            setFilterSelected((prev) =>
              isEnabled ? [...prev, selectedValue] : prev.filter((v) => v !== selectedValue),
            );
          }}
        />
        <Chips
          chips={choiceChips}
          selected={choiceSelected}
          aria-label="Transfer amount"
          onChange={({ selectedValue }) => setChoiceSelected(selectedValue)}
        />
      </div>
    );
  },
  ...withVariantConfig(['default', 'dark', 'bright-green', 'forest-green']),
};

/**
 * Tab moves between chips. Enter or Space toggles selection.
 */
export const ChoiceKeyboardInteraction: Story = {
  render: function Render() {
    const [selected, setSelected] = useState<ChipValue>(300);
    return (
      <Chips
        chips={choiceChips}
        selected={selected}
        aria-label="Transfer amount"
        onChange={({ selectedValue }) => setSelected(selectedValue)}
      />
    );
  },
  play: async () => {
    await userEvent.tab();
    await wait(400);
    await userEvent.tab();
    await wait(400);
    await userEvent.keyboard('{Enter}');
  },
};

/**
 * Tab moves between chips. Enter or Space toggles selection.
 */
export const FilterKeyboardInteraction: Story = {
  render: function Render() {
    const [selected, setSelected] = useState<readonly ChipValue[]>(['accounting']);
    return (
      <Chips
        chips={filterChips}
        multiple
        selected={selected}
        aria-label="Category filter"
        onChange={({ selectedValue, isEnabled }) => {
          setSelected((prev) =>
            isEnabled ? [...prev, selectedValue] : prev.filter((v) => v !== selectedValue),
          );
        }}
      />
    );
  },
  play: async () => {
    await userEvent.tab();
    await wait(400);
    await userEvent.tab();
    await wait(400);
    await userEvent.tab();
    await wait(400);
    await userEvent.keyboard('{Enter}');
  },
};

/** Filter and choice chips in right-to-left layout. */
export const RTL: Story = {
  render: function Render() {
    const [filterSelected, setFilterSelected] = useState<readonly ChipValue[]>([
      'accounting',
      'payments',
    ]);
    const [choiceSelected, setChoiceSelected] = useState<ChipValue>(300);

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
        <Chips
          chips={filterChips}
          multiple
          selected={filterSelected}
          aria-label="Category filter"
          onChange={({ selectedValue, isEnabled }) => {
            setFilterSelected((prev) =>
              isEnabled ? [...prev, selectedValue] : prev.filter((v) => v !== selectedValue),
            );
          }}
        />
        <Chips
          chips={choiceChips}
          selected={choiceSelected}
          aria-label="Transfer amount"
          onChange={({ selectedValue }) => setChoiceSelected(selectedValue)}
        />
      </div>
    );
  },
  ...withVariantConfig(['rtl']),
};

/** Filter chips at 400% zoom for accessibility testing. */
export const Zoom400: Story = {
  render: function Render() {
    const [selected, setSelected] = useState<readonly ChipValue[]>(['accounting']);
    return (
      <Chips
        chips={filterChips}
        multiple
        selected={selected}
        aria-label="Category filter"
        onChange={({ selectedValue, isEnabled }) => {
          setSelected((prev) =>
            isEnabled ? [...prev, selectedValue] : prev.filter((v) => v !== selectedValue),
          );
        }}
      />
    );
  },
  ...withVariantConfig(['400%']),
};
