import { type FC, type ReactNode, useEffect, useState } from 'react';
import { Link, useLocation } from 'react-router-dom';

import Box from '@material-hu/mui/Box';
import Divider from '@material-hu/mui/Divider';
import Tab, { type TabProps } from '@material-hu/mui/Tab';
import TabsUI, { type TabsProps as TabsUIProps } from '@material-hu/mui/Tabs';

import { useAuth } from 'src/contexts/JWTContext';
import { hasAnyPermissions } from 'src/utils/permissions';
import { findTabIndexByParam, getPath } from 'src/utils/tabs';

import TabSeeMoreButton from 'src/components/tabs/TabSeeMoreButton';

import { default as TabPanel, type TabPanelProps } from './TabPanel';

export type TabObject = {
  id: string;
  title?: ReactNode;
  content: ReactNode;
  requiredPermissions?: string[];
  active?: boolean;
  routeParam?: string;
};

type TabsProps = {
  id: string;
  tabsProps?: TabsUIProps;
  tabProps?: TabProps<any, { component?: any }>;
  tabPanelProps?: Omit<TabPanelProps, 'id' | 'value' | 'index'>;
  tabs: TabObject[];
  withDivider?: boolean;
  withRouteParams?: boolean;
  tabDefault?: number;
  onTabChange?: (index: number) => void;
  withSeeMore?: boolean;
  withContainer?: boolean;
  maxTabs?: number;
  dynamicTabs?: boolean;
};

/**
 * @deprecated Use `@material-hu/components/design-system/Tabs` instead
 */
export const Tabs: FC<TabsProps> = props => {
  const {
    id,
    tabs,
    tabsProps = {},
    tabProps = {},
    tabPanelProps = {},
    withDivider = false,
    withRouteParams = false,
    onTabChange = () => null,
    tabDefault,
    withSeeMore = false,
    withContainer = false,
    maxTabs = 4,
    dynamicTabs = false,
  } = props;

  const [currentTab, setCurrentTab] = useState<number | string>(
    tabDefault || (dynamicTabs ? tabs[0]?.id : 0),
  );

  const { permissions } = useAuth();
  const { pathname, search } = useLocation();

  useEffect(() => {
    if (dynamicTabs) {
      const currentEmoji = tabs.find(item => item.id === currentTab);
      if (currentEmoji === undefined && tabs.length > 0) {
        setCurrentTab(tabs[0]?.id);
      }
    }
  }, [tabs, currentTab]);

  useEffect(() => {
    if (!withRouteParams) return;

    const index = findTabIndexByParam(tabs, search);

    if (index !== -1) {
      setCurrentTab(index);
    }
  }, [search]);

  const filteredTabs = tabs.filter(
    tab =>
      tab.active !== false &&
      hasAnyPermissions(permissions, tab.requiredPermissions || []),
  );

  const handleTabChange = (_: any, newTab: number) => {
    setCurrentTab(newTab);
    onTabChange(newTab);
  };

  const handleChangeCurrentTab = (newTab: number) => setCurrentTab(newTab);

  const renderTabPanel = (tab: TabObject, index: number) => {
    const { id: tabId, content } = tab;
    const key = dynamicTabs ? tabId : index;

    if (withContainer) {
      return (
        <Box sx={{ zIndex: '0 !important' }}>
          <TabPanel
            id={id}
            key={key}
            value={currentTab}
            index={key}
            {...tabPanelProps}
          >
            {content}
          </TabPanel>
        </Box>
      );
    }
    return (
      <TabPanel
        id={id}
        key={key}
        value={currentTab}
        index={key}
        {...tabPanelProps}
      >
        {content}
      </TabPanel>
    );
  };

  const renderTab = (tab: TabObject, index: number) => {
    const { id: key, title, routeParam } = tab;
    const keyValue = dynamicTabs ? key : index;

    const path = getPath(pathname, routeParam || '');

    return (
      <Tab
        key={key}
        id={`${id}-tab-${keyValue}`}
        aria-controls={`${id}-tabpanel-${keyValue}`}
        value={keyValue}
        label={title}
        component={withRouteParams ? Link : undefined}
        to={withRouteParams ? path : undefined}
        replace={withRouteParams ? true : undefined}
        {...tabProps}
        sx={{ maxWidth: withSeeMore ? '100px' : '100%' }}
      />
    );
  };

  if (withSeeMore) {
    const emojiIsSeen = filteredTabs
      .slice(0, maxTabs)
      .find(item => item.id === currentTab);

    return (
      <>
        <Box sx={{ display: 'flex' }}>
          <TabsUI
            {...tabsProps}
            value={emojiIsSeen === undefined ? false : currentTab}
            onChange={handleTabChange}
          >
            {filteredTabs.slice(0, maxTabs).map(renderTab)}
          </TabsUI>
          {filteredTabs.length > maxTabs && (
            <TabSeeMoreButton
              filteredTabs={filteredTabs}
              currentTab={currentTab}
              onChangeTab={handleChangeCurrentTab}
              maxShowIndex={maxTabs - 1}
            />
          )}
        </Box>
        {withDivider && <Divider />}
        {filteredTabs.map(renderTabPanel)}
      </>
    );
  }

  return (
    <>
      <TabsUI
        {...tabsProps}
        value={currentTab}
        onChange={handleTabChange}
      >
        {filteredTabs.map(renderTab)}
      </TabsUI>
      {withDivider && <Divider />}
      {filteredTabs.map(renderTabPanel)}
    </>
  );
};

export default Tabs;
