import type { Story, Meta } from '@storybook/react';
import { useCallback, useMemo, useState } from 'react';
import { useToggle } from 'react-use';
import noop from 'lodash/noop';

import makeStyles from '@mui/styles/makeStyles';
import { Drawer } from '../@navigation/drawer';
import { Button } from '../button';

import { InfoList } from './info-list';
import type { InfoListProps } from './types';

export default {
  component: InfoList,
  title: 'Right Side Bar Components/Notifications Items',
  argTypes: {
    title: {
      description: 'Title of the component.'
    },
    onClose: {
      description: 'Callback which will be fired on click the close icon.'
    },
    tabsProps: {
      description: 'Props that will be passed into the Tabs component.'
    },
    tabsButtons: {
      description: 'Array of buttons which will be displayed next to the tabs.'
    },
    tabs: {
      description: 'Props that will be passed into the individual Tabs components.'
    },
    handleListItemClick: {
      description: 'Callback which will be fired on list item click when `isActive: true`.'
    },
    handleStatusDotClick: {
      description:
        "Callback which will be fired on list item's status dot click when `isActive: false`."
    },
    listItems: {
      description: 'Array which will form the list.'
    },
    markAsReadBtnTxt: {
      description: 'Pass text to mark as read button.'
    },
    hideBtnTxt: {
      description: 'Pass text to hide button.'
    }
  }
} as Meta;

const Template: Story<InfoListProps> = args => <InfoList {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  handleListItemClick: () => e => {
    e.stopPropagation();
    alert('item click');
  },
  handleStatusDotClick: () => e => {
    e.stopPropagation();
    alert('Status click');
  },
  tabsButtons: [
    {
      children: 'Mark All as Read',
      onClick: () => alert('Will mark all as read')
    },
    {
      children: 'Show all',
      onClick: () => alert('Will show all')
    }
  ],
  listItems: [
    {
      id: '1',
      title: 'Item 1',
      text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
      description: 'description',
      isActive: true,
      avatarProps: {
        src: 'https://upload.wikimedia.org/wikipedia/commons/8/8f/Cute-kittens-12929201-1600-1200.jpg'
      },
      statusTooltipProps: {
        title: 'Mark as read',
        placement: 'left'
      }
    },
    {
      id: '2',
      title: 'Item 2',
      text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
      description: 'description',
      isActive: false,
      avatarProps: {
        src: 'https://upload.wikimedia.org/wikipedia/commons/8/8f/Cute-kittens-12929201-1600-1200.jpg'
      },
      statusTooltipProps: {
        title: 'Hide'
      }
    }
  ],
  onClose: () => alert('Will close'),
  title: 'Title',
  tabsProps: {
    onChange: () => alert('Will change tabs'),
    value: 0
  },
  tabs: [{ label: 'Item One' }, { label: 'Item Two' }],
  infiniteScrollProps: {
    dataLength: 2,
    hasMore: false,
    loader: 'Loading...',
    next: noop
  }
};

const createClasses = makeStyles(() => ({
  paper: {
    width: '400px'
  }
}));

const DrawerTemplate: Story<InfoListProps> = args => {
  const classes = createClasses();
  const [open, toggleOpen] = useToggle(false);
  return (
    <>
      <Button color="primary" onClick={toggleOpen}>
        Toggle open
      </Button>
      <Drawer
        anchor="right"
        classes={{
          paper: classes.paper
        }}
        open={open}
        onClose={toggleOpen}
      >
        <InfoList {...args} />
      </Drawer>
    </>
  );
};

export const WithDrawer = DrawerTemplate.bind({});
WithDrawer.args = Primary.args;

const createListItems = (num: number) => {
  const arr: InfoListProps['listItems'] = [];
  for (let i = 0; i < num; i++) {
    arr.push({
      id: i.toString(),
      title: 'Item 1',
      text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
      description: 'description',
      isActive: true,
      avatarProps: {
        src: 'https://upload.wikimedia.org/wikipedia/commons/8/8f/Cute-kittens-12929201-1600-1200.jpg'
      },
      statusTooltipProps: {
        title: 'Mark as read',
        placement: 'left'
      }
    });
  }
  return arr;
};
const infiniteScrollListItems = createListItems(100);
const STEP = 10;
const drawerId = 'scrollableDrawer';

const InfiniteScrollerTemplate: Story<InfoListProps> = args => {
  const classes = createClasses();
  const [open, toggleOpen] = useToggle(false);

  const [currentPage, setCurrentPage] = useState(0);
  const [listItems, setListItems] = useState(args.listItems);

  const getMoreItems = useCallback(() => {
    setTimeout(() => {
      const newPage = currentPage + 1;
      const newState = listItems.concat(
        infiniteScrollListItems.slice(STEP * newPage, STEP * (newPage + 1))
      );
      setCurrentPage(newPage);
      setListItems(newState);
    }, 1000);
  }, [currentPage, listItems]);

  const defaultProps: InfoListProps['infiniteScrollProps'] = useMemo(
    () => ({
      ...args.infiniteScrollProps,
      dataLength: listItems.length,
      hasMore: listItems.length < infiniteScrollListItems.length,
      next: getMoreItems,
      scrollableTarget: drawerId
    }),
    [args.infiniteScrollProps, getMoreItems, listItems.length]
  );

  return (
    <>
      <Button color="primary" onClick={toggleOpen}>
        Toggle open
      </Button>
      <Drawer
        anchor="right"
        classes={{
          paper: classes.paper
        }}
        open={open}
        onClose={toggleOpen}
        PaperProps={{
          id: drawerId
        }}
      >
        <InfoList
          {...args}
          listItems={listItems}
          infiniteScrollProps={defaultProps}
          markAsReadBtnTxt="Mark As Read"
          hideBtnTxt="Hide"
        />
      </Drawer>
    </>
  );
};

export const InfiniteScroller = InfiniteScrollerTemplate.bind({});
InfiniteScroller.args = {
  ...Primary.args,
  listItems: infiniteScrollListItems.slice(0, STEP)
};
