import { useState } from 'react';
import { Meta, StoryObj } from '@storybook/react-webpack5';
import { userEvent, within, expect, waitFor } from 'storybook/test';
import { Button, Field, SelectInput, Sentiment } from '..';
import Alert, { type AlertProps } from './Alert';

const meta = {
  title: 'Prompts/Alert/Tests',
  component: Alert,
  tags: ['!manifest', 'deprecated'],
  argTypes: {},
  args: {
    type: Sentiment.POSITIVE,
    message: 'Payments sent to your bank details today might not arrive in time for the holidays.',
  },
} satisfies Meta<typeof Alert>;
export default meta;

type Story = StoryObj<typeof meta>;

const wait = async (duration = 500) =>
  new Promise<void>((resolve) => {
    setTimeout(resolve, duration);
  });

export const SimpleTrigger: Story = {
  play: async ({ args, canvasElement }) => {
    const canvas = within(canvasElement);
    await wait();
    await userEvent.tab();
    await wait();
    await userEvent.keyboard('{Enter}');

    await waitFor(async () => expect(canvas.getByText(args.message || '')).toBeInTheDocument());
  },
  render: function Render(args) {
    const [isActive, setIsActive] = useState(false);

    return (
      <>
        <Button v2 onClick={() => setIsActive(true)}>
          Trigger Alert
        </Button>

        {isActive && <Alert {...args} className="m-t-4" />}
      </>
    );
  },
};

export const ComplexTrigger: Story = {
  play: async ({ args, canvasElement }) => {
    const canvas = within(canvasElement);
    await wait();
    await userEvent.tab();
    await wait();
    await userEvent.keyboard('{ArrowDown}');
    await wait();
    await userEvent.keyboard('{ArrowDown}');
    await wait();
    await userEvent.keyboard('{Enter}');

    await waitFor(async () => expect(canvas.getByText(args.message || '')).toBeInTheDocument());
  },
  render: function Render(args) {
    const [isActive, setIsActive] = useState(false);
    const [value, setValue] = useState<string>();

    return (
      <>
        <Field label="Select option to triger Alert">
          <SelectInput
            items={[
              { type: 'option', value: 'one' },
              { type: 'option', value: 'two' },
            ]}
            onChange={setValue}
            onClose={() => setIsActive(Boolean(value))}
          />
        </Field>

        {isActive && <Alert {...args} className="m-t-2" />}
      </>
    );
  },
};

export const MultipleDynamicAlerts: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await expect(canvas.queryAllByRole('status')).toHaveLength(0);
    await expect(canvas.queryAllByRole('alert')).toHaveLength(0);
    await wait();
    await userEvent.tab();
    await userEvent.keyboard('{Enter}');
    await waitFor(async () => expect(canvas.getAllByRole('graphics-symbol')).toHaveLength(3));
    await expect(canvas.getAllByRole('status')).toHaveLength(2);
    await expect(canvas.getAllByRole('alert')).toHaveLength(1);
  },
  render: function Render() {
    const [alerts, setAlerts] = useState<AlertProps[]>([]);

    const getAlerts: () => AlertProps[] = () => [
      {
        type: Sentiment.POSITIVE,
        title: `Title 1`,
        children: `This is a ${Sentiment.POSITIVE} content`,
      },
      {
        type: Sentiment.WARNING,
        title: `Title 2`,
        children: `This is a ${Sentiment.WARNING} content`,
      },
      {
        type: Sentiment.NEGATIVE,
        title: `Title 3`,
        children: `This is a ${Sentiment.NEGATIVE} content`,
      },
    ];

    return (
      <>
        <Button v2 onClick={() => setAlerts(getAlerts())}>
          Generate dynamic alerts
        </Button>

        {alerts.map((props) => (
          <Alert key={props.title} {...props} className="m-t-3" />
        ))}
      </>
    );
  },
};
