import MuiBox from '@mui/material/Box';
import {
  randCity,
  randCompanyName,
  randDomainName,
  randEmail,
  randFullName,
  randMovie,
  randEmoji
} from '@ngneat/falso';
import { Button } from '../../../button';
import { newIconSources } from '../../../custom-icon/helpers';
import { GlobalSearch } from '../global-search';
import { IDefaultOption, ITenantOption, IUserOption } from '../types';
import { action } from '@storybook/addon-actions';
import { ArgTypes, ComponentStory } from '@storybook/react';
import { stringToColor } from '../../../../utils';

type PickGlobalSearchArgTypes =
  | 'multiple'
  | 'disableGrouping'
  | 'freeSolo'
  | 'disabled'
  | 'readOnly'
  | 'noOptionsText'
  | 'onChange'
  | 'onInputChange'
  | 'limitTags'
  | 'optionsBeforeScroll'
  | 'openOnFocus'
  | 'hideEndAdornment'
  | 'endAdornmentIconSrc'
  | 'onEndAdornmentClick';

const companies: ITenantOption[] = randCompanyName({ length: 15 }).map(c => ({
  label: c,
  subtitle: c,
  companyIconProps: Math.random() >= 0.5 ? { domain: randDomainName() } : undefined,
  componentType: 'Tenant'
}));

const users: IUserOption[] = randFullName({ length: 20, withAccents: false }).map((u, i) => ({
  label: u,
  email: randEmail(),
  componentType: 'User',
  avatarImgSrc:
    Math.random() >= 0.5 ? `https://i.pravatar.cc/100?random=${Math.random()}` : undefined
}));

export const cities: IDefaultOption[] = randCity({ length: 11 }).map(city => ({
  label: city,
  someOtherProp: 'PROPS',
  group: 'We can add actions to options',
  Actions: (
    <MuiBox display="flex" gap="8px">
      <Button onClick={action('Action clicked')} size="small">
        Action
      </Button>
      <Button onClick={action('Another Action clicked')} size="small">
        Another Action
      </Button>
    </MuiBox>
  )
}));

export const custom: IDefaultOption[] = randMovie({ length: 9 }).map(movie => ({
  label: movie,
  CustomComponent: (
    <div
      style={{
        color: stringToColor(movie),
        fontSize: '14px',
        fontWeight: 'bold',
        display: 'flex',
        gap: '16px'
      }}
    >
      {movie} {randEmoji()} {randEmoji()} {randEmoji()}
    </div>
  ),
  group: 'We can also use custom option components'
}));

export const groupedOptions = {
  users,
  tenants: companies,
  cities,
  custom
};

export const argTypes: Partial<
  ArgTypes<Pick<React.ComponentProps<typeof GlobalSearch>, PickGlobalSearchArgTypes>>
> = {
  disableGrouping: { description: 'Disable grouping', type: 'boolean' },
  disabled: {
    description: 'Toggle disabled state',
    type: 'boolean',
    defaultValue: false
  },
  readOnly: {
    description: 'Toggle read only state',
    type: 'boolean',
    defaultValue: false
  },
  noOptionsText: {
    description: 'The text that renders when no options',
    type: 'string',
    defaultValue: 'No options'
  },
  freeSolo: {
    description:
      'Enabling free solo will enable the input to not be constraint to the available options',
    type: 'boolean',
    defaultValue: false
  },
  limitTags: {
    description: 'Max number of tags before showing a counter',
    type: 'number',
    defaultValue: -1
  },
  optionsBeforeScroll: {
    description: 'Number of options to show in group before scroll',
    type: 'number',
    defaultValue: 5
  },
  openOnFocus: {
    description: 'Open options list on focus',
    type: 'boolean',
    defaultValue: false
  },
  hideEndAdornment: {
    description: 'Hide end adornment',
    type: 'boolean',
    defaultValue: false
  },
  endAdornmentIconSrc: {
    description: 'End adornment icon src',
    type: 'string',
    options: [undefined, ...newIconSources],
    defaultValue: undefined,
    control: {
      type: 'select'
    }
  },
  onEndAdornmentClick: {
    description: 'A Callback that fires when end adornment clicked',
    type: 'function'
  },
  onChange: {
    description: 'A Callback that fires when value has changed',
    type: 'function'
  },
  onInputChange: {
    description: 'A Callback that fires when input has changed',
    type: 'function'
  }
};

export const args: React.ComponentProps<typeof GlobalSearch> = {
  disableGrouping: false,
  disabled: false,
  readOnly: false,
  noOptionsText: 'No options',
  groupedOptions,
  // TODO: for some reason the action get undefined as the option, which does not happens when you use onChange outside of this scope. should investigate it
  onChange: action('Value change'),
  onInputChange: action('Input change'),
  freeSolo: false,
  limitTags: -1,
  optionsBeforeScroll: 5,
  openOnFocus: false,
  hideEndAdornment: false,
  endAdornmentIconSrc: undefined,
  onEndAdornmentClick: action('End adornment clicked')
};

export const Template: ComponentStory<typeof GlobalSearch> = args => <GlobalSearch {...args} />;
