import { Meta } from '@storybook/react';

import map from 'lodash/map';
import noop from 'lodash/noop';
import startCase from 'lodash/startCase';
import uniqueId from 'lodash/uniqueId';

import Typography from '@mui/material/Typography';

import { ASSETS_URL } from '../../../../consts/common';
import { countryCodesMap } from '../../../../consts';
import { getMockUsersDropdownMenuItems } from '../../../dropdown-menu';
import type { DropdownMenuItem, MenuContentProps } from '../../../dropdown-menu';

import { Select } from '../select';

import type { AutocompleteOptionProps } from '../../autocomplete';
import {
  AutoCompleteTemplate,
  IconAndSearchTemplate,
  MultipleTemplate,
  NestedShowDeletedTemplate,
  NestedSelectAllTemplate,
  PrimaryTemplate
} from './templates';

export default {
  component: Select,
  title: 'Forms/Dropdown Menu/Drop-Downs',
  argTypes: {
    size: {
      options: ['small', 'medium'],
      control: { type: 'radio' }
    },
    color: {
      options: ['primary', 'secondary'],
      control: { type: 'select' }
    },
    label: {
      description: 'The label of the input.'
    },
    placeholder: {
      description: 'The short hint displayed in the input before the user enters a value.'
    },
    showLimitItemsTooltip: {
      description: 'Whether to show a tooltip with a list of limited items.',
      control: {
        type: 'boolean'
      }
    },
    showSelectClearButton: {
      description: 'Whether to show a select field clear button.',
      control: {
        type: 'boolean'
      }
    },
    menuContentProps: {
      description: 'Props which will be passed into the menu content component.'
    },
    handleSelectClickCB: {
      description: 'A callback function to handle a select field click.'
    }
  }
} as Meta;

export const Primary = PrimaryTemplate.bind({});
Primary.args = {
  menuContentProps: {
    listItems: [
      { name: 'Ini', selected: false },
      { name: 'Mini', selected: false },
      { name: 'Miny', selected: false },
      { name: 'Mo', selected: false }
    ],
    handleClick: () => noop
  },
  autoFocus: true,
  error: false,
  label: '',
  placeholder: 'Placeholder',
  disabled: false
};

export const IconAndSearch = IconAndSearchTemplate.bind({});
IconAndSearch.args = {
  ...Primary.args,
  menuContentProps: {
    ...(Primary.args.menuContentProps as MenuContentProps),
    showSelectedIcon: true,
    search: true,
    noOptionsText: 'No options'
  }
};

export const MenuWidth = IconAndSearchTemplate.bind({});
MenuWidth.args = {
  ...Primary.args,
  menuContentProps: {
    listItems: [
      { name: 'Lorem ipsum' },
      { name: 'Dolor sit amet' },
      { name: 'Consectetur adipiscing elit' },
      { name: 'Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua' },
      { name: 'Ut enim ad minim veniam' },
      { name: 'Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat' },
      { name: 'Duis aute irure dolor' },
      { name: 'Reprehenderit in voluptate' },
      { name: 'Velit esse cillum dolore eu fugiat nulla pariatur' }
    ],
    noOptionsText: 'No options',
    search: true
  },
  menuMaxWidth: 320,
  menuWidth: 0
};

export const Multiple = MultipleTemplate.bind({});
Multiple.args = {
  multiple: true,
  showLimitItemsTooltip: false,
  menuContentProps: {
    search: true,
    listItems: [
      { name: 'Ini', selected: false },
      { name: 'Mini', selected: false },
      { name: 'Miny', selected: false },
      { name: 'Mo', selected: false },
      { name: 'Test1', selected: false },
      { name: 'Test2', selected: false },
      { name: 'Test3', selected: false },
      { name: 'Test4', selected: false },
      { name: 'Test5', selected: false }
    ],
    noOptionsText: 'No options',
    handleClick: () => noop
  },
  placeholder: 'Placeholder'
};

export const Countries = MultipleTemplate.bind({});
Countries.args = {
  ...Multiple.args,
  showLimitItemsTooltip: true,
  showSelectClearButton: true,
  menuContentProps: {
    ...Multiple.args.menuContentProps,
    listItems: map(countryCodesMap, item => {
      const itemName = startCase(item.code.toString());
      const countryData = countryCodesMap[item.code];
      const countryFlag = countryData?.flag || 'worldwide';
      const countryFlagSrc = `${ASSETS_URL}/flags/${countryFlag}.svg`;

      return {
        name: itemName,
        textNode: countryData.name,
        selected: false,
        checkboxProps: {
          icon: <img width={16} src={countryFlagSrc} alt={countryData.name + ' flag'} />
        }
      };
    }),
    variableSizeList: true,
    searchBy: ['textNode', 'name'],
    noOptionsText: 'No options',
    handleClick: () => noop
  },
  style: { width: 280 }
};

export const WithTitleInside = NestedSelectAllTemplate.bind({});
WithTitleInside.args = {
  ...Multiple.args,
  showLimitItemsTooltip: true,
  showSelectClearButton: true,
  menuContentProps: {
    ...Multiple.args.menuContentProps,
    listItems: [
      {
        id: '__first',
        name: 'Very First Title',
        textNode: <Typography variant="h5">Very First Title</Typography>,
        options: [
          {
            id: uniqueId(),
            name: 'Check body text 1'
          },
          {
            id: uniqueId(),
            name: 'Check body text 2'
          },
          {
            id: uniqueId(),
            name: 'Check body text 3'
          }
        ]
      },
      {
        id: '__second',
        name: 'Second Title',
        textNode: <Typography variant="h5">Second Title</Typography>,
        options: [
          {
            id: uniqueId(),
            name: 'Check body text 4'
          },
          {
            id: uniqueId(),
            name: 'Check body text 5'
          }
        ]
      } as DropdownMenuItem
    ],
    InsertBeforeList: () => null, // overrides template's checkbox
    search: false,
    handleClick: () => noop
  },
  style: { width: 280 }
};

export const WithTitleCounter = NestedSelectAllTemplate.bind({});
WithTitleCounter.args = {
  ...Multiple.args,
  showLimitItemsTooltip: true,
  showSelectClearButton: true,
  menuContentProps: {
    ...Multiple.args.menuContentProps,
    listItems: [
      {
        id: '__compare',
        name: 'Compare',
        options: [
          {
            id: uniqueId(),
            name: 'Check body text 1'
          },
          {
            id: uniqueId(),
            name: 'Check body text 2'
          },
          {
            id: uniqueId(),
            name: 'Check body text 3'
          },
          {
            id: uniqueId(),
            name: 'Check body text 4'
          }
        ]
      }
    ],
    search: false,
    handleClick: () => noop
  },
  style: { width: 280 }
};

// Create groups of users, 50% of which are disabled
const mockUsersGroup0 = getMockUsersDropdownMenuItems(21, 0.5);
const mockUsersGroup1 = getMockUsersDropdownMenuItems(7, 0.5);

export const Users = NestedShowDeletedTemplate.bind({});
Users.args = {
  ...Multiple.args,
  showLimitItemsTooltip: true,
  showSelectClearButton: true,
  menuContentProps: {
    ...Multiple.args.menuContentProps,
    listItems: [
      {
        id: '__group0',
        name: 'All Users',
        textNode: <Typography variant="h5">All Users</Typography>,
        options: mockUsersGroup0
      },
      {
        id: '__group1',
        name: 'Managers',
        textNode: <Typography variant="h5">Managers</Typography>,
        options: mockUsersGroup1
      } as DropdownMenuItem
    ],
    search: false,
    handleClick: () => noop
  },
  style: { width: 280 }
};

export const DragAndDrop = MultipleTemplate.bind({});
DragAndDrop.args = {
  ...Multiple.args,
  showLimitItemsTooltip: false,
  menuContentProps: {
    ...(Multiple.args.menuContentProps as MenuContentProps),
    deletable: true,
    sortable: true,
    showSort: true,
    noOptionsText: 'No options',
    handleDelete: name => () => alert(`Will delete ${name}`),
    onSortEnd: noop
  }
};

const mockItems: AutocompleteOptionProps[] = [];
for (let i = 1; i <= 20; i++) {
  const randomNum = Math.random() * 10;
  const randomStr = randomNum.toString(36).substring(2);
  const randomText = randomNum < 5 ? ' - ' + randomStr.substring(Math.floor(randomNum)) : '';
  mockItems.push({
    name: `Item${i}${randomText}`,
    selected: false
  });
}
const autocompleteItems = mockItems;

export const AutoComplete = AutoCompleteTemplate.bind({});
AutoComplete.args = {
  size: 'medium',
  placeholder: 'Autocomplete',
  multiple: false,
  defaultLimitTags: 2,
  showLimitTagsTooltip: false,
  freeSolo: false,
  options: autocompleteItems,
  handleDelete: () => alert('Will delete a single chip'),
  handleClear: () => alert('Will clear all chips')
};
