import { forwardRef } from "react";
import {
  Meta,
  Preview,
  Story,
  SourceState,
} from "@storybook/addon-docs/blocks";
import { format, compareAsc } from "date-fns";
import { ComponentHeading } from "../../storybook-components";
import { Box } from "../Box";
import { Flex } from "../Flex";
import { Button } from "../Button";
import { Stack } from "../Stack";
import { FormGroup } from "../FormGroup";
import { Label } from "../Label";
import { PopoverMenu } from "../PopoverMenu";
import { DatePicker, DatePickerInput } from "./DatePicker";

<Meta title="Components/Forms/Date Picker" component={DatePicker} />

<ComponentHeading
  componentName="DatePicker"
  description="Creates a visual calendar date selector as part of an input or as a standalone element"
  sourcePath="src/components/DatePicker/DatePicker.tsx"
/>

export const DemoContainer = (props) => (
  <Box className="pb-20" style={{ minHeight: "320px" }} {...props} />
);

Date picker uses [react-datepicker](https://reactdatepicker.com).

```jsx
import { DatePicker } from "@aptible/arrow-ds";
```

<Preview>
  <Story name="DatePicker">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      return (
        <DemoContainer>
          <FormGroup>
            <Label htmlFor="date">Select a date</Label>
            <DatePicker
              onChange={(date) => setStartDate(date)}
              selected={startDate}
              id="date"
            />
          </FormGroup>
        </DemoContainer>
      );
    }}
  </Story>
</Preview>

## Props

The props extend `ReactDatePickerProps` from
[react-datepicker](https://reactdatepicker.com).

## Demos

### With custom input as a button

When providing a `customInput`, make sure is able to accept a `ref`.

<Preview withSource={SourceState.OPEN}>
  <Story name="DatePicker custom input as a button">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      const CustomInput = forwardRef(({ onClick }, ref) => (
        <Button onClick={onClick} ref={ref}>
          Select a date
        </Button>
      ));
      return (
        <DemoContainer>
          <DatePicker
            customInput={<CustomInput />}
            onChange={(date) => setStartDate(date)}
            selected={startDate}
          />
        </DemoContainer>
      );
    }}
  </Story>
</Preview>

### Multiple months in popover

<Preview withSource={SourceState.OPEN}>
  <Story name="DatePicker multiple months">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      return (
        <DemoContainer>
          <FormGroup>
            <Label htmlFor="date">Select a date</Label>
            <DatePicker
              onChange={(date) => setStartDate(date)}
              selected={startDate}
              id="date-multi"
              monthsShown={2}
            />
          </FormGroup>
        </DemoContainer>
      );
    }}
  </Story>
</Preview>

### Rendered inline

<Preview withSource={SourceState.OPEN}>
  <Story name="Rendered inline">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      return (
        <DatePicker
          onChange={(date) => setStartDate(date)}
          selected={startDate}
          inline
        />
      );
    }}
  </Story>
</Preview>

### Multiple months inline

<Preview withSource={SourceState.OPEN}>
  <Story name="Multiple months range inline">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      return (
        <DatePicker
          monthsShown={2}
          onChange={(date) => setStartDate(date)}
          selected={startDate}
          inline
        />
      );
    }}
  </Story>
</Preview>

### Date range

<Preview withSource={SourceState.OPEN}>
  <Story name="Date range">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/18/2019"));
      const [endDate, setEndDate] = React.useState(new Date("11/27/2019"));
      return (
        <DemoContainer>
          <Flex>
            <FormGroup className="mr-2">
              <Label htmlFor="startDate">Start date</Label>
              <DatePicker
                id="startDate"
                onChange={(date) => {
                  const isEndDateBeforeStartDate =
                    compareAsc(endDate, date) === -1;
                  if (isEndDateBeforeStartDate) {
                    setEndDate(date);
                  }
                  setStartDate(date);
                }}
                selected={startDate}
                startDate={startDate}
                endDate={endDate}
                selectsStart
              />
            </FormGroup>
            <FormGroup>
              <Label htmlFor="endDate">End date</Label>
              <DatePicker
                id="endDate"
                onChange={(date) => setEndDate(date)}
                selected={endDate}
                startDate={startDate}
                endDate={endDate}
                minDate={startDate}
                selectsEnd
              />
            </FormGroup>
          </Flex>
        </DemoContainer>
      );
    }}
  </Story>
</Preview>

### Date range inline

<Preview withSource={SourceState.OPEN}>
  <Story name="Date range inline">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      const [endDate, setEndDate] = React.useState(new Date("11/28/2019"));
      const dateFormat = "M/d/yyyy";
      return (
        <DemoContainer>
          <Stack className="ml-11">
            <FormGroup>
              <Label>Start date</Label>
              <DatePickerInput
                className="w-full mb-2"
                value={startDate ? format(startDate, dateFormat) : ""}
                readOnly
              />
            </FormGroup>
            <FormGroup>
              <Label>End date</Label>
              <DatePickerInput
                className="w-full mb-2"
                value={endDate ? format(endDate, dateFormat) : ""}
                readOnly
              />
            </FormGroup>
          </Stack>
          <DatePicker
            onChange={(dates) => {
              setStartDate(dates[0]);
              setEndDate(dates[1]);
            }}
            selected={startDate}
            startDate={startDate}
            endDate={endDate}
            monthsShown={3}
            selectsRange
            inline
          />
        </DemoContainer>
      );
    }}
  </Story>
</Preview>

### Date range popover

<Preview withSource={SourceState.OPEN}>
  <Story name="Date range popover">
    {() => {
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      const [endDate, setEndDate] = React.useState(new Date("11/28/2019"));
      const dateFormat = "M/d/yyyy";
      return (
        <DemoContainer>
          <PopoverMenu style={{ width: "max-content" }}>
            <Stack className="border-b p-4">
              <FormGroup className="mb-0">
                <Label>Start date</Label>
                <DatePickerInput
                  className="w-full mb-2"
                  value={startDate ? format(startDate, dateFormat) : ""}
                  readOnly
                />
              </FormGroup>
              <FormGroup className="mb-0">
                <Label>End date</Label>
                <DatePickerInput
                  className="w-full mb-2"
                  value={endDate ? format(endDate, dateFormat) : ""}
                  readOnly
                />
              </FormGroup>
            </Stack>
            <DatePicker
              onChange={(dates) => {
                setStartDate(dates[0]);
                setEndDate(dates[1]);
              }}
              selected={startDate}
              startDate={startDate}
              endDate={endDate}
              selectsRange
              inline
              monthsShown={2}
              wrapperClassName="p-4"
            />
          </PopoverMenu>
        </DemoContainer>
      );
    }}
  </Story>
</Preview>

### Date range single calendar

<Preview withSource={SourceState.OPEN}>
  <Story name="Date range single calendar">
    {() => {
      const dateFormat = "M/d/yyyy";
      const [startDate, setStartDate] = React.useState(new Date("11/26/2019"));
      const [endDate, setEndDate] = React.useState(new Date("11/28/2019"));
      const onChange = (dates) => {
        const [start, end] = dates;
        setStartDate(start);
        setEndDate(end);
      };
      return (
        <DemoContainer>
          <PopoverMenu className="p-6" style={{ width: "max-content" }}>
            <Flex className="items-center mb-4 justify-between px-3">
              <DatePickerInput
                style={{
                  width: "89px",
                  paddingLeft: "8px",
                  paddingRight: "8px",
                }}
                placeholder="Start date"
                value={startDate ? format(startDate, dateFormat) : ""}
                readOnly
              />
              <Box className="w-4 mx-2 text-center">to</Box>
              <DatePickerInput
                style={{
                  width: "89px",
                  paddingLeft: "8px",
                  paddingRight: "8px",
                }}
                placeholder="Start date"
                value={endDate ? format(endDate, dateFormat) : ""}
                readOnly
              />
            </Flex>
            <DatePicker
              onChange={onChange}
              selectsRange
              selected={startDate}
              startDate={startDate}
              endDate={endDate}
              minDate={startDate && !endDate ? startDate : null}
              inline
            />
          </PopoverMenu>
        </DemoContainer>
      );
    }}
  </Story>
</Preview>
