import React, { useState } from 'react';

import { subYears, addMonths, subMonths, subWeeks } from 'date-fns';
import { ComponentStory, ComponentMeta } from '@storybook/react';

import { DatePicker } from './DatePicker';
import { DATE_PICKER_TYPE, DATE_PICKER_VARIANT, DateRange } from './types';
import { ONE, TWO } from './constants';

export default {
  title: 'ReactComponentLibrary/DatePicker',
  component: DatePicker,
  decorators: [(Story): JSX.Element => <Story />],
} as ComponentMeta<typeof DatePicker>;

const SingleTemplate: ComponentStory<typeof DatePicker> = (args) => {
  const [date, setDate] = useState<Date | undefined>(args.initialValue as Date);

  const applyValue = (value: Date): void => {
    setDate(value);
  };

  return (
    <DatePicker
      {...args}
      type={DATE_PICKER_TYPE.Single}
      initialValue={date}
      onApply={applyValue}
    />
  );
};

export const SingleDatePicker = SingleTemplate.bind({});
SingleDatePicker.args = {};

export const CompactSingleDatePicker = SingleTemplate.bind({});
CompactSingleDatePicker.args = {
  variant: DATE_PICKER_VARIANT.Compact,
};

export const DisabledSingleDatePicker = SingleTemplate.bind({});
DisabledSingleDatePicker.args = {
  isDisabled: true,
};

export const SingleDatePickerWithDisabledDates = SingleTemplate.bind({});
SingleDatePickerWithDisabledDates.args = {
  disabledDates: {
    before: subYears(new Date(), ONE),
    after: addMonths(new Date(), ONE),
  },
};

export const SingleDatePickerWithRequiredDate = SingleTemplate.bind({});
SingleDatePickerWithRequiredDate.args = {
  initialValue: new Date(),
  isRequired: true,
};

export const SingleDatePickerWithCustomPreferences = SingleTemplate.bind({});
SingleDatePickerWithCustomPreferences.args = {
  preferences: {
    mask: '99/99/99',
    placeholder: 'MM/DD/YY',
    format: 'MM/dd/yy',
  },
};

const RangeTemplate: ComponentStory<typeof DatePicker> = (args) => {
  const [range, setRange] = useState<DateRange | undefined>(args.initialValue as DateRange);

  const applyValue = (value: DateRange): void => {
    setRange(value);
  };

  return (
    <DatePicker
      {...args}
      type={DATE_PICKER_TYPE.Range}
      initialValue={range}
      onApply={applyValue}
    />
  );
};

export const RangeDatePicker = RangeTemplate.bind({});
RangeDatePicker.args = {};

export const CompactRangeDatePicker = RangeTemplate.bind({});
CompactRangeDatePicker.args = {
  variant: DATE_PICKER_VARIANT.Compact,
};

export const DisabledRangeDatePicker = RangeTemplate.bind({});
DisabledRangeDatePicker.args = {
  isDisabled: true,
};

export const RangeDatePickerWithDisabledDates = RangeTemplate.bind({});
RangeDatePickerWithDisabledDates.args = {
  disabledDates: {
    before: subYears(new Date(), ONE),
    after: addMonths(new Date(), TWO),
  },
};

export const RangeDatePickerWithRequiredDate = RangeTemplate.bind({});
RangeDatePickerWithRequiredDate.args = {
  initialValue: {
    from: new Date(),
    to: addMonths(new Date(), TWO),
  },
  isRequired: true,
};

export const RangeDatePickerWithCustomPreferences = RangeTemplate.bind({});
RangeDatePickerWithCustomPreferences.args = {
  preferences: {
    mask: '99/99/99',
    placeholder: 'MM/DD/YY',
    format: 'MM/dd/yy',
  },
};

const RangeSidebarTemplate: ComponentStory<typeof DatePicker> = (args) => {
  const [range, setRange] = useState<DateRange | undefined>(args.initialValue as DateRange);

  const applyValue = (value: DateRange): void => {
    setRange(value);
  };

  const disabledDates = {
    before: new Date(),
    after: addMonths(new Date(), TWO),
  };

  const presets = [
    {
      title: 'Last Date',
      value: { from: disabledDates.after, to: disabledDates.after },
    },
    {
      title: 'Last Week',
      value: { from: subWeeks(disabledDates.after, ONE), to: disabledDates.after },
    },
    {
      title: 'Last Month',
      value: { from: subMonths(disabledDates.after, ONE), to: disabledDates.after },
    },
  ];

  return (
    <DatePicker
      {...args}
      type={DATE_PICKER_TYPE.Range}
      initialValue={range}
      onApply={applyValue}
      presets={presets}
      disabledDates={disabledDates}
    />
  );
};

export const RangeDatePickerWithPresets = RangeSidebarTemplate.bind({});
