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

import Upload from '.';
import { Field } from '../field/Field';

const meta = {
  component: Upload,
  title: 'Forms/Upload/Tests',
  tags: ['!manifest'],
  argTypes: {
    maxSize: {
      control: {
        type: 'number',
        min: 0,
      },
    },
  },
} satisfies Meta<typeof Upload>;

export default meta;

export const MaxSizes = () => {
  const bKB = 1024;
  const bMB = 1024 * bKB;

  const dKB = 1000;
  const dMB = 1000 * dKB;

  const binarySizes = [
    10 * bMB,
    5 * bMB,
    1 * bMB,
    500 * bKB,
    100 * bKB,
    50 * bKB,
    10 * bKB,
    5 * bKB,
    1 * bKB,
  ];

  const decimalSizes = [
    10 * dMB,
    5 * dMB,
    1 * dMB,
    500 * dKB,
    100 * dKB,
    50 * dKB,
    10 * dKB,
    5 * dKB,
    1 * dKB,
  ];

  return (
    <div style={{ display: 'flex', gap: '1rem' }}>
      <div style={{ flex: 1 }}>
        {binarySizes.map((maxSize) => (
          <Field key={maxSize} label={`Max size: ${maxSize} bytes`}>
            <Upload usLabel="Pick a file, any file" maxSize={maxSize} />
          </Field>
        ))}

        <Field label="Max size: null (no limit)">
          <Upload usLabel="Pick a file, any file" maxSize={null} />
        </Field>
      </div>
      <div style={{ flex: 1 }}>
        {decimalSizes.map((maxSize) => (
          <Field key={maxSize} label={`Max size: ${maxSize} bytes`}>
            <Upload usLabel="Pick a file, any file" maxSize={maxSize} />
          </Field>
        ))}
      </div>
    </div>
  );
};

export const WithError: StoryObj<typeof meta> = {
  render: () => (
    <Field label="Upload a file">
      <Upload
        usAccept="*"
        usLabel="Upload a file"
        usPlaceholder="Maximum filesize is 1B"
        usDisabled={false}
        maxSize={1}
        errorIconLabel="File too large error"
        httpOptions={{
          url: 'https://httpbin.org/post',
          method: 'POST',
        }}
      />
    </Field>
  ),
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const fileInput = canvasElement.querySelector<HTMLInputElement>('input[type="file"]');

    if (!fileInput) {
      throw new Error('File input not found');
    }

    const file = new File(['This file content is definitely more than 1 byte'], 'test-file.txt', {
      type: 'text/plain',
    });

    await userEvent.upload(fileInput, file);
    await waitFor(async () => canvas.findByText(/Maximum filesize is/i), { timeout: 3000 });
  },
};

export const AllVariants = () => {
  return (
    <div style={{ display: 'flex', gap: '1rem' }}>
      <div style={{ flex: 1 }}>
        <Field key="small" label="Small Upload">
          <Upload usLabel="Pick a file, any file" size="sm" />
        </Field>
        <Field key="medium" label="Medium Upload">
          <Upload usLabel="Pick a file, any file" size="md" />
        </Field>
        <Field key="large" label="Large Upload">
          <Upload usLabel="Pick a file, any file" size="lg" />
        </Field>
        <Field key="disabled" label="Disabled Upload">
          <Upload usLabel="Pick a file, any file" usDisabled />
        </Field>
      </div>
    </div>
  );
};
