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

import { DateInput, Field } from '..';
import { lorem10 } from '../test-utils';

import Provider from '../provider/Provider';
import translations from '../i18n';
import { withVariantConfig } from '../../.storybook/helpers';

const meta: Meta<typeof DateInput> = {
  component: DateInput,
  title: 'Forms/DateInput/Tests',
  tags: ['!manifest'],
  args: {
    dayLabel: 'Day input',
    dayAutoComplete: 'bday-day',
    monthLabel: 'Month select',
    yearLabel: 'Year input',
    yearAutoComplete: 'bday-year',
    onChange: fn(),
  },
};

export default meta;

type Story = StoryObj<typeof DateInput>;

const Basic: Story = {
  args: {
    onChange: fn(),
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('combobox'));
  },
};

export const WithLabel: Story = {
  args: {
    onChange: fn(),
  },
  render: (args) => {
    return (
      <Field label="Date of Delivery">
        <DateInput {...args} />
      </Field>
    );
  },
};

export const InputError: Story = {
  render: (args) => (
    <>
      pure date input:
      <DateInput {...args} value={new Date('2010-04-05')} />
      <div className="p-b-3">show padding right below</div>
      date input wrapped in Field:
      <Field>
        <DateInput {...args} value={new Date('2010-04-05')} />
      </Field>
      <div className="p-b-3">show padding right below</div>
      error date input wrapped in Field:
      <Field sentiment="negative" message={lorem10}>
        <DateInput {...args} value={new Date('2010-04-05')} />
      </Field>
      <div className="p-b-3">show padding right below</div>
    </>
  ),
};

export const CustomPlaceholders: Story = {
  ...Basic,
  args: {
    placeholders: {
      day: 'D',
      month: 'M',
      year: 'YY',
    },
  },
};

export const SingleZero: Story = {
  ...Basic,
  play: async ({ canvasElement, step }) => {
    const canvas = within(canvasElement);
    await step('can enter leading zero on day field', async () => {
      const dayInput = await canvas.findByRole('textbox', { name: /day/i });
      await userEvent.click(dayInput);
      await userEvent.type(dayInput, '0');
    });
    await step('can enter 1 leading zero on year field', async () => {
      const yearInput = await canvas.findByRole('textbox', { name: /year/i });
      await userEvent.click(yearInput);
      await userEvent.type(yearInput, '0');
    });
  },
};

export const ZeroesAsValue: Story = {
  ...Basic,
  play: async ({ canvasElement, step }) => {
    const canvas = within(canvasElement);
    await step('can enter 2 leading zeroes on day field', async () => {
      const dayInput = await canvas.findByRole('textbox', { name: /day/i });
      await userEvent.click(dayInput);
      await userEvent.type(dayInput, '00');
    });
    await step('can enter 4 leading zeroes on year field', async () => {
      const yearInput = await canvas.findByRole('textbox', { name: /year/i });
      await userEvent.click(yearInput);
      await userEvent.type(yearInput, '0000');
    });
  },
};

export const ZeroesBeforeValue: Story = {
  ...Basic,
  play: async ({ canvasElement, step }) => {
    const canvas = within(canvasElement);
    await step('can enter leading zeroes on day followed by day', async () => {
      const dayInput = await canvas.findByRole('textbox', { name: /day/i });
      await userEvent.click(dayInput);
      await userEvent.type(dayInput, '01');
    });
    await step('can enter leading zeroes on year followed by year', async () => {
      const yearInput = await canvas.findByRole('textbox', { name: /year/i });
      await userEvent.click(yearInput);
      await userEvent.type(yearInput, '0001');
    });
  },
};

export const MaxLengthRespected: Story = {
  ...Basic,
  play: async ({ canvasElement, step }) => {
    const canvas = within(canvasElement);
    await step('can only enter 4 digits in the year field', async () => {
      const yearInput = await canvas.findByRole('textbox', { name: /year/i });
      await userEvent.click(yearInput);
      await userEvent.type(yearInput, '11111111');
    });
    await step('can only enter 2 digits in the day field', async () => {
      const dayInput = await canvas.findByRole('textbox', { name: /day/i });
      await userEvent.click(dayInput);
      await userEvent.type(dayInput, '11111111');
    });
  },
};

export const LocalizationWorks: Story = {
  ...Basic,
  decorators: [
    (Story) => {
      const locale = 'zh-HK';
      return (
        <Provider i18n={{ locale, messages: translations[locale] }}>
          <Story />
        </Provider>
      );
    },
  ],
};

export const YearFirst: Story = {
  ...Basic,
  decorators: [
    (Story) => {
      const locale = 'ja';
      return (
        <Provider i18n={{ locale, messages: translations[locale] }}>
          <Story />
        </Provider>
      );
    },
  ],
};

export const MonthFirst: Story = {
  ...Basic,
  decorators: [
    (Story) => {
      const locale = 'en-US';
      return (
        <Provider i18n={{ locale, messages: translations[locale] }}>
          <Story />
        </Provider>
      );
    },
  ],
};

export const DayFirst: Story = {
  ...Basic,
  decorators: [
    (Story) => {
      const locale = 'en';
      return (
        <Provider i18n={{ locale, messages: translations[locale] }}>
          <Story />
        </Provider>
      );
    },
  ],
};

export const NoNonDigitsAllowed: Story = {
  ...Basic,
  play: async ({ canvasElement, step }) => {
    const canvas = within(canvasElement);
    await step('can only enter digits in the day field', async () => {
      const dayInput = await canvas.findByRole('textbox', { name: /day/i });
      await userEvent.click(dayInput);
      await userEvent.type(dayInput, 'abcd1');
    });
    await step('can only enter digits in the year field', async () => {
      const yearInput = await canvas.findByRole('textbox', { name: /year/i });
      await userEvent.click(yearInput);
      await userEvent.type(yearInput, 'abcd2');
    });
  },
};

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

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