import { faker } from '@faker-js/faker';
import { action } from '@storybook/addon-actions';
import { Meta, StoryObj } from '@storybook/react';
import React, { useState } from 'react';
import { createGroups, generateItemArray } from '../../../helpers/storybook';
import { Tags } from './Tags';

const groups = createGroups({
  Behavior: ['autoFocus', 'disabled', 'inlineMode', 'name', 'id'],
  Content: [
    'label',
    'error',
    'tooltipContent',
    'value',
    'tagsOptions',
    'dropDownLabel',
    'displayKey',
    'valueKey',
  ],
  Styling: ['className'],
  Events: ['onChange', 'onBlur', 'onFocus'],
});

const meta: Meta<typeof Tags> = {
  title: 'Primary Components/Form Elements/Tags',
  component: Tags,
  argTypes: {
    ...groups,
  },
};
export default meta;

export const Main: StoryObj<typeof Tags> = {
  args: {
    name: 'number',
    value: ['1', '2'],
    label: 'Number',
    dropDownLabel: 'Select',
    tagsOptions: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
    tooltipContent: faker.lorem.paragraph(2),
  },
  render: (args) =>
    React.createElement(() => {
      const [value, setValue] = useState(args.value);

      return (
        <Tags
          {...args}
          value={value}
          onChange={(e) => {
            action('onChange')(e);
            setValue(e.currentTarget.value as unknown as string[]);
          }}
        />
      );
    }),
};

type ObjectsStoryType = StoryObj<
  typeof Tags<{
    id: number;
    title: string;
  }>
>;

export const Objects: ObjectsStoryType = {
  args: {
    ...Main.args,
    value: ['1', '2'],
    tagsOptions: generateItemArray(10, (index) => ({
      id: index,
      title: `Item ${index}: ${faker.random.words(
        faker.datatype.number({ min: 1, max: 3 }),
      )}`,
    })),
    valueKey: 'id',
    displayKey: 'title',
  },
};

enum Data {
  ZERO = '0',
  ONE = '1',
  TWO = '2',
  THREE = '3',
  FOUR = '4',
  FIVE = '5',
  SIX = '6',
  SEVEN = '7',
  EIGHT = '8',
  NINE = '9',
}

const enumMapper = <T extends { [key: string]: string }>(
  e: T,
): {
  readonly key: string;
  readonly value: string;
}[] => {
  return Object.keys(e).map((key) => {
    return {
      key,
      value: e[key],
    };
  });
};

type EmumStoryType = typeof Tags<{
  readonly key: string;
  readonly value: string;
}>;

export const Enums: StoryObj<EmumStoryType> = {
  args: {
    ...Main.args,
    value: ['1', '2'],
    tagsOptions: enumMapper(Data),
    valueKey: 'value',
    displayKey: 'key',
  },
  render: (args) =>
    React.createElement(() => {
      const [value, setValue] = useState(args.value);
      return (
        <Tags
          {...args}
          value={value}
          onChange={(e) => {
            action('onChange')(e);
            setValue(e.currentTarget.value as unknown as string[]);
          }}
        />
      );
    }),
};
