import { useState } from "react";
import {
  Meta,
  Canvas,
  ArgsTable,
  Story,
  SourceState,
} from "@storybook/blocks";
import { ComponentHeading, Code } from "../../storybook-components";
import { Banner } from "../Banner";
import { Label } from "../Label";
import { FormGroup } from "../FormGroup";
import { ICON_TYPE } from "../Icon";
import { Button, BUTTON_VARIANT } from "../Button";
import { InputFeedback } from "../InputFeedback";
import { STATUS_VARIANT } from "../../types";
import { FileUploadDnD } from ".";

<Meta title="Components/Forms/File Upload" component={FileUploadDnD} />

<ComponentHeading
  componentName="FileUploadDnD"
  description="A component for uploading one or multiple files"
  sourcePath="src/components/FileUpload/FileUploadDnD.tsx"
/>

<Banner
  title="The `FileUpload` component is deprecated"
  className="mt-8"
  variant={STATUS_VARIANT.WARNING}
  withIcon
>
  Use the <Code>FileUploadDnD</Code> component instead. It adds drag and drop
  functionality on top of the original <Code>FileUpload</Code>, but has a
  different API.
</Banner>

The `FileUploadDnD` component is a styled label that wraps an HTML `<input type="file" />` element. Props can be passed to the component to style and position it, and the `inputProps` object can be used to pass attributes to the native input element.

It also includes drag and drop functionality that works independently of the underlying `<input />`.

## Installation

```jsx
import { FileUploadDnD } from "@conveyorhq/arrow-ds";
```

## Basic usage

<Canvas withSource={SourceState.OPEN}>
  <Story name="FileUpload">
    {() => {
      const [file, setFile] = useState(null);
      return (
        <FileUploadDnD
          onChange={setFile}
          value={file}
          label="Select image file"
          accept="image/gif,image/jpeg,image/tiff,image/svg+xml,image/png"
        />
      );
    }}
  </Story>
</Canvas>

## API

Extends `React.HTMLProps<HTMLLabelElement>`

<ArgsTable of={FileUploadDnD} />

## Demos

### Multiple files

<Canvas>
  <Story name="Multiple">
    {() => {
      const [file, setFile] = useState(null);
      return (
        <FileUploadDnD
          multiple
          onChange={setFile}
          value={file}
          label="Select images"
          accept="image/gif,image/jpeg,image/tiff,image/svg+xml,image/png"
        />
      );
    }}
  </Story>
</Canvas>

## Within FormGroup

<Canvas>
  <Story name="WithinFormGroup">
    {() => {
      const [error, setError] = useState(false);
      const [file, setFile] = useState(null);
      const handleSubmit = (event) => {
        event.preventDefault();
        setError(!file);
      };
      return (
        <form onSubmit={handleSubmit}>
          <FormGroup
            isRequired
            variant={error ? STATUS_VARIANT.DANGER : STATUS_VARIANT.DEFAULT}
            id="important-file"
          >
            <Label>Upload PDF</Label>
            <FileUploadDnD
              onChange={setFile}
              value={file}
              label="Select PDF"
              accept="application/pdf"
            />
            {error && <InputFeedback>You must select a file</InputFeedback>}
          </FormGroup>
          <Button type="submit">Submit</Button>
        </form>
      );
    }}
  </Story>
</Canvas>

### Error State

This file uploader will show an error regardless of what file type you give it.

<Canvas>
  <Story name="Error">
    {() => {
      const [file, setFile] = useState(null);
      return (
        <FileUploadDnD
          multiple
          onChange={setFile}
          value={file}
          label="Select any file"
          accept="not/a/real/type"
        />
      );
    }}
  </Story>
</Canvas>

### Customize Button

FileUploadDnD uses a <Code>Button</Code> component as part of its UI. You can pass props that will filter down to the <Code>Button</Code> component and override its default appearance.

<Canvas>
  <Story name="Button Props">
    {() => {
      const [file, setFile] = useState(null);
      return (
        <FileUploadDnD
          multiple
          onChange={setFile}
          value={file}
          label="Select any file"
          accept="not/a/real/type"
          buttonProps={{
            variant: BUTTON_VARIANT.PRIMARY,
            icon: ICON_TYPE.PLUS,
          }}
        />
      );
    }}
  </Story>
</Canvas>
