import { action } from 'storybook/actions';
import { useState } from 'react';
import { Meta, StoryObj } from '@storybook/react-webpack5';
import { fireEvent, within } from 'storybook/test';
import { FastFlag } from '@transferwise/icons';
import { lorem10, lorem100, lorem500 } from '../../test-utils';
import { Typography } from '../propsValues/typography';
import Alert from '../../alert';
import Body from '../../body';
import Button from '../../button';
import Title from '../../title';
import ListItem from '../../listItem';
import BottomSheet from './BottomSheet';
import { withVariantConfig } from '../../../.storybook/helpers';

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

export default {
  component: BottomSheet,
  title: 'Dialogs/BottomSheet/Tests',
  tags: ['!autodocs'],
  args: {
    open: false,
  },
} satisfies Meta<typeof BottomSheet>;

type Story = StoryObj<typeof BottomSheet>;

/**
 * This test ensures that when the SelectInput is used within a scrollable page,
 * opening the dropdown does not cause any unwanted scrolling or layout shifts.
 * Expected preview should start with green bar at the top, with yellow section
 * not in the viewport. The issue is particularly prominent on iOS Safari.
 *
 * NB: This test is disabled in Chromatic as there's no obvious way to control
 * <html/> element of a snapshot. It's to be primarily used in manual testing
 * on an actual device or a simulator as it cannot be reproduced with mobile
 * emulation modes on desktop browsers.
 */
export const SmoothScrollReset: Story = {
  args: {
    children: (
      <>
        <Title type={Typography.TITLE_SECTION}>Observe the document</Title>
        <Alert className="m-t-2" type="warning">
          Once the <code>BottomSheet</code> opens, the document underneath should be static and
          should not scroll.
        </Alert>
        <Body as="p">{lorem100}</Body>
        <Body as="p">{lorem100}</Body>
      </>
    ),
  },
  decorators: [
    (Story) => (
      <>
        <style>{'html { scroll-behavior: smooth; }'}</style>
        <div style={{ maxWidth: 500 }}>
          <Body>
            <p>{lorem100}</p>
            <p>{lorem100}</p>
          </Body>
          <Story />
          <Body as="p" className="m-t-5 disabled">
            {lorem500}
          </Body>
        </div>
      </>
    ),
  ],
  parameters: {
    chromatic: {
      disableSnapshot: true,
    },
  },
  play: async ({ canvasElement }) => {
    document.documentElement.scrollTop = 400;
    await wait(500);
    const canvas = within(canvasElement);
    // cannot use userEvent.click as it crashes on iOS Safari in the simulator
    await fireEvent.click(canvas.getByRole('button'));
  },
  render: ({ open, ...args }) => {
    const [isOpen, setIsOpen] = useState(false);

    return (
      <div>
        <Button onClick={() => setIsOpen(true)}>Open BottomSheet</Button>
        <BottomSheet
          {...args}
          open={isOpen}
          onClose={() => {
            setIsOpen(false);
          }}
        />
      </div>
    );
  },
};

const Basic: Story = {
  args: {
    children: (
      <>
        <Title type={Typography.TITLE_SECTION}>Money without borders</Title>
        {lorem10}
        <br />
        <br />
        <ListItem
          title="List item"
          subtitle="Button and icon are vertically centered."
          control={<ListItem.Navigation href="#" />}
          media={
            <ListItem.AvatarView>
              <FastFlag />
            </ListItem.AvatarView>
          }
        />
      </>
    ),
  },
  parameters: {
    chromatic: {
      delay: 1000,
    },
  },
  render: (args, { viewMode }) => {
    const [open, setOpen] = useState(viewMode !== 'docs');

    return (
      <div>
        <Button onClick={() => setOpen(true)}>Open BottomSheet</Button>
        <BottomSheet
          {...args}
          open={open}
          onClose={() => {
            setOpen(false);
            action('BottomSheet closed')();
          }}
        />
      </div>
    );
  },
};

export const BasicMobile: Story = {
  ...Basic,
  ...withVariantConfig(['mobile'], Basic),
};

const WithOverflowContent: Story = {
  args: {
    children: (
      <>
        <Title type={Typography.TITLE_SECTION}>Money without borders</Title>
        {lorem10}
        <ListItem
          title="List item"
          subtitle="Button and icon are vertically centered."
          control={<ListItem.Navigation href="#" />}
          media={
            <ListItem.AvatarView>
              <FastFlag />
            </ListItem.AvatarView>
          }
        />
        <ListItem
          title="List item"
          subtitle="Button and icon are vertically centered."
          control={<ListItem.Navigation href="#" />}
          media={
            <ListItem.AvatarView>
              <FastFlag />
            </ListItem.AvatarView>
          }
        />
        {lorem500}
        <Body type={Typography.BODY_DEFAULT_BOLD}>{lorem10}</Body>
      </>
    ),
  },
  parameters: {
    chromatic: {
      delay: 1000,
    },
  },
  render: (args, { viewMode }) => {
    const [open, setOpen] = useState(viewMode !== 'docs');

    return (
      <div>
        <Button onClick={() => setOpen(true)}>Open BottomSheet</Button>
        <BottomSheet
          {...args}
          open={open}
          onClose={() => {
            setOpen(false);
            action('BottomSheet closed')();
          }}
        />
      </div>
    );
  },
};

export const WithOverflowContentMobile: Story = {
  ...WithOverflowContent,
  ...withVariantConfig(['mobile'], WithOverflowContent),
};

export const WithOverflowContentDark: Story = {
  ...WithOverflowContent,
  ...withVariantConfig(['dark'], WithOverflowContent),
};

export const WithOverflowContentDarkMobile: Story = {
  ...WithOverflowContent,
  ...withVariantConfig(['dark', 'mobile'], WithOverflowContent),
};

export const WithOverflowContentZoom400: Story = {
  ...WithOverflowContent,
  ...withVariantConfig(['400%'], WithOverflowContent),
};
