import { AdvancedScrollerThin, ErrorBoundary, Icon, ContextMenu, Clickable, DiscoverySidebarHeader } from '@vizality/components';
import { getModule, contextMenu } from '@vizality/webpack';
import { joinClassNames } from '@vizality/util/dom';
import React, { memo } from 'react';

const { openContextMenu, closeContextMenu } = contextMenu;

/**
 * Dashboard sidebar header.
 * @component
 * @returns {React.MemoExoticComponent<function(): React.ReactElement>}
 */
export const Header = memo(({ text, children, className }) => {
  return (
    <div className={joinClassNames('vz-dashboard-sidebar-header', className)}>
      <DiscoverySidebarHeader text={text} />
      {children}
    </div>
  );
});

/**
 * Dashboard sidebar navigation item separator.
 * @component
 * @returns {React.MemoExoticComponent<function(): React.ReactElement>}
 */
export const Separator = memo(({ className }) => (
  <div className={joinClassNames('vz-dashboard-sidebar-separator', className)} />
));

/**
 * Context menu for dashboard sidebar navigation items.
 * @private
 * @component
 * @returns {React.MemoExoticComponent<function(): React.ReactElement>}
 */
const ItemContextMenu = memo(({ path }) => {
  return (
    <ContextMenu.Menu navId='dashboard-item' onClose={closeContextMenu}>
      <ContextMenu.Item
        id='copy-link'
        label='Copy Link'
        action={() => DiscordNative?.clipboard?.copy(`<vizality:/${path.replace('vizality/', '')}>`)}
      />
    </ContextMenu.Menu>
  );
});

/**
 * Dashboard sidebar navigation item.
 * @component
 * @returns {React.MemoExoticComponent<function(): React.ReactElement>}
 */
export const Item = memo(({ icon, children, route, selected, disabled, onContextMenu, tooltip, tooltipPosition = 'right', onClick, className }) => {
  selected = typeof selected === 'boolean' ? selected : vizality.api.routes.getLocation()?.pathname?.startsWith(route);
  const { categoryItem, selectedCategoryItem, itemInner } = getModule('categoryItem', 'selectedCategoryItem', 'itemInner');
  const { clickable, container, selected: selectedClass, wrappedLayout, layout, avatar, content, nameAndDecorators, name, wrappedName } = getModule('clickable', 'container', 'highlighted', 'layout', 'wrappedLayout');

  return (
    <Clickable
      onContextMenu={evt => {
        try {
          if (disabled) {
            return;
          }
          if (onContextMenu) {
            return onContextMenu(evt);
          } else if (route) {
            return openContextMenu(evt, () => <ItemContextMenu path={route} />);
          }
        } catch (err) {

        }
      }}
      onClick={evt => {
        try {
          if (disabled) {
            return;
          }
          if (onClick) {
            return onClick(evt);
          } else if (route) {
            return vizality.api.routes.navigateTo(route);
          }
        } catch (err) {

        }
      }}
      vz-selected={selected && ''}
      vz-disabled={disabled && ''}
      className={joinClassNames('vz-dashboard-sidebar-item', className, categoryItem, container, clickable, {
        disabled,
        [`${selectedClass} ${selectedCategoryItem}`]: selected
      })}
    >
      <div className={joinClassNames('vz-dashboard-sidebar-item-inner', itemInner, layout, wrappedLayout)}>
        <Icon
          className={joinClassNames('vz-dashboard-sidebar-item-icon-wrapper', avatar)}
          iconClassName='vz-dashboard-sidebar-item-icon'
          name={icon}
          tooltip={tooltip}
          tooltipPosition={tooltipPosition}
        />
        <div className={content}>
          <div className={nameAndDecorators}>
            <div className={joinClassNames(name, wrappedName)}>
              {children}
            </div>
          </div>
        </div>
      </div>
    </Clickable>
  );
});

/**
 * Dashboard sidebar.
 * @component
 * @returns {React.MemoExoticComponent<function(): React.ReactElement>}
 */
export default memo(({ header, className, children }) => {
  const [ collapsed, setCollapsed ] = vizality.api.settings.useSetting('dashboardSidebarCollapse', false);
  return (
    <ErrorBoundary>
      <AdvancedScrollerThin className={joinClassNames('vz-dashboard-sidebar-inner', className)}>
        {!header
          /**
           * If no header prop is provided, render the default Vizality dashboard sidebar header.
           */
          ? (
            <Header text='Dashboard'>
              <Icon
                name='download'
                iconClassName='vz-dashboard-sidebar-collapser-icon'
                className='vz-dashboard-sidebar-collapser'
                onClick={() => setCollapsed(!collapsed)}
                tooltip={collapsed ? 'Expand' : 'Collapse'}
                tooltipPosition='right'
              />
            </Header>
          )
          /**
           * If header prop provided is a string, use that.
           */
          : typeof header === 'string'
            ? <Header text={header} />
            /**
             * If header prop is provided but isn't a string, we'll assume it's a React component
             * and render that.
             */
            : header
        }
        {children
          ? children
          : (
            <>
              <Item
                icon='house'
                route='/vizality/dashboard'
                tooltip={collapsed && 'Home'}
              >
                Home
              </Item>
              <Item
                icon='gear'
                route='/vizality/settings'
                tooltip={collapsed && 'Settings'}
              >
                Settings
              </Item>
              <Item
                icon='plugin'
                route='/vizality/plugins'
                tooltip={collapsed && 'Plugins'}
                /**
                 * In order to match /vizality/plugins/ and /vizality/plugin/ routes
                 */
                selected={(/\/vizality\/plugin(s)?/).test(vizality.api.routes.getLocation()?.pathname)}
              >
                Plugins
              </Item>
              <Item
                icon='theme'
                route='/vizality/themes'
                tooltip={collapsed && 'Themes'}
                /**
                 * In order to match /vizality/themes/ and /vizality/theme/ routes
                 */
                selected={(/\/vizality\/theme(s)?/).test(vizality.api.routes.getLocation()?.pathname)}
              >
                Themes
              </Item>
              <Item
                icon='scissors'
                route='/vizality/snippets'
                tooltip={collapsed && 'Snippets'}
                disabled
              >
                Snippets
              </Item>
              <Item
                icon='palette'
                route='/vizality/palettes'
                tooltip={collapsed && 'Palettes'}
                disabled
              >
                Palettes
              </Item>
              {vizality.manager.builtins.isEnabled('quick-code') && (
                <Item
                  icon='compose'
                  route='/vizality/quick-code'
                  tooltip={collapsed && 'Quick Code'}
                >
                  Quick Code
                </Item>
              )}
              <Separator />
              <Item
                icon='unknown-user'
                tooltip={collapsed && 'Development'}
                disabled
              >
                Development
              </Item>
              <Separator />
              <Item
                icon='cloud-download'
                route='/vizality/updater'
                tooltip={collapsed && 'Updater'}
              >
                Updater
              </Item>
              <Item
                icon='more-info'
                route='/vizality/changelog'
                tooltip={collapsed && 'Changelog'}
              >
                Changelog
              </Item>
            </>
          )}
      </AdvancedScrollerThin>
    </ErrorBoundary>
  );
});
