import React, { useRef, useState, useEffect, memo } from 'react';
import { Container as SubContainer } from '@/AppBuilder/AppCanvas/Container';
import { resolveWidgetFieldValue, isExpectedDataType } from '@/_helpers/utils';
import useStore from '@/AppBuilder/_stores/store';
import Spinner from '@/_ui/Spinner';
import { useExposeState } from '@/AppBuilder/_hooks/useExposeVariables';
import SolidIcon from '@/_ui/Icon/SolidIcons';
import * as Icons from '@tabler/icons-react';
import { set } from 'lodash';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';
import OverflowTooltip from '@/_components/OverflowTooltip';
import { TAB_CANVAS_PADDING } from '@/AppBuilder/AppCanvas/appCanvasConstants';
import { useDynamicHeight } from '@/_hooks/useDynamicHeight';
import { shallow } from 'zustand/shallow';
import { getSafeRenderableValue } from '@/Editor/Components/utils';
const tinycolor = require('tinycolor2');

const TabsNavShimmer = ({ divider, headerBackground }) => {
  return (
    <div
      className="d-flex px-3 gap-4"
      style={{
        borderBottom: `0.5px solid ${divider}`,
        height: '60.41px',
        backgroundColor: headerBackground,
        alignItems: 'center',
      }}
    >
      {Array(3)
        .fill(0)
        .map((ind) => (
          <div
            key={ind}
            style={{
              width: '68px',
              height: '20px',
              backgroundColor: '#88909914',
              borderRadius: '6px',
              marginTop: '8px ',
              marginBottom: '8px',
            }}
          ></div>
        ))}
    </div>
  );
};

export const Tabs = function Tabs({
  id,
  component,
  width,
  height,
  containerProps,
  removeComponent,
  setExposedVariable,
  setExposedVariables,
  adjustComponentPositions,
  currentLayout,
  fireEvent,
  styles,
  darkMode,
  dataCy,
  properties,
}) {
  const { tabWidth, boxShadow } = styles;
  const { isDisabled, isVisible, isLoading } = useExposeState(
    properties.loadingState,
    properties.visibility,
    properties.disabledState,
    setExposedVariables,
    setExposedVariable
  );
  const { defaultTab, hideTabs, renderOnlyActiveTab, useDynamicOptions, dynamicHeight } = properties;
  const setSelectedComponents = useStore((state) => state.setSelectedComponents);

  const widgetVisibility = styles?.visibility ?? true;
  const disabledState = styles?.disabledState ?? false;
  // config for tabs. Includes title
  const tabs = isExpectedDataType(properties.tabs, 'array');
  let parsedTabs = tabs;
  if (!useDynamicOptions) {
    parsedTabs = properties.tabItems;
  } else {
    parsedTabs = resolveWidgetFieldValue(parsedTabs);
  }

  parsedTabs = parsedTabs
    ?.filter((tab) => tab.visible !== false)
    ?.map((parsedTab, index) => ({
      ...parsedTab,
      id: parsedTab.id ? parsedTab.id : index,
    }));
  const highlightColor = styles?.highlightColor ?? '#f44336';
  let parsedHighlightColor = highlightColor;
  parsedHighlightColor = resolveWidgetFieldValue(highlightColor);

  const headerBackground = styles?.headerBackground ?? '#fff';
  const unselectedText = styles?.unselectedText ?? '#6A727C';
  const selectedText = styles?.selectedText ?? '#fff';
  const hoverBackground = styles?.hoverBackground ?? '#F1F3F4';
  const unselectedIcon = styles?.unselectedIcon ?? '#6A727C';
  const selectedIcon = styles?.selectedIcon ?? '#fff';
  const accent = styles?.accent ?? '#3c92dc';
  const divider = styles?.divider ?? '#CCD1D5';
  const borderRadius = styles?.borderRadius ?? '0px';

  const border = styles?.border === '#CCD1D5' ? false : styles?.border;
  const padding = styles?.padding ?? 'none';
  const transition = styles?.transition ?? 'none';

  // Default tab
  let parsedDefaultTab = defaultTab;

  const defaultTabExists = parsedTabs?.some((tab) => tab.id === parsedDefaultTab);
  if (!defaultTabExists && parsedTabs.length > 0) {
    parsedDefaultTab = parsedTabs[0].id;
  }

  const parsedDisabledState =
    typeof disabledState !== 'boolean' ? resolveWidgetFieldValue(disabledState) : disabledState;

  const parsedHideTabs = typeof hideTabs !== 'boolean' ? resolveWidgetFieldValue(hideTabs) : hideTabs;
  const parsedRenderOnlyActiveTab =
    typeof renderOnlyActiveTab !== 'boolean' ? resolveWidgetFieldValue(renderOnlyActiveTab) : renderOnlyActiveTab;

  let parsedWidgetVisibility = widgetVisibility;

  try {
    parsedWidgetVisibility = resolveWidgetFieldValue(parsedWidgetVisibility);
  } catch (err) {
    console.log(err);
  }

  const parentRef = useRef(null);
  const [currentTab, setCurrentTab] = useState(parsedDefaultTab);
  const componentCount = useStore(
    (state) => state.getContainerChildrenMapping(`${id}-${currentTab}`)?.length || 0,
    shallow
  );
  const [tabItems, setTabItems] = useState(parsedTabs);
  const tabItemsRef = useRef(tabItems);
  const [bgColor, setBgColor] = useState('#fff');

  useDynamicHeight({
    dynamicHeight,
    id,
    height,
    adjustComponentPositions,
    currentLayout,
    isContainer: true,
    value: currentTab,
    componentCount,
    visibility: widgetVisibility,
  });

  useEffect(() => {
    setCurrentTab(parsedDefaultTab);
  }, [parsedDefaultTab]);

  useEffect(() => {
    if (JSON.stringify(tabItemsRef.current) !== JSON.stringify(parsedTabs)) {
      setTabItems(parsedTabs);
      tabItemsRef.current = parsedTabs;
    }
  }, [parsedTabs]);

  useEffect(() => {
    const currentTabData = parsedTabs.filter((tab) => tab.id == currentTab);
    setBgColor(currentTabData[0]?.backgroundColor ? currentTabData[0]?.backgroundColor : darkMode ? '#324156' : '#fff');
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentTab, darkMode, parsedTabs]);

  useEffect(() => {
    const exposedVariables = {
      setTab: async function (id) {
        if (currentTab != id) {
          setCurrentTab(id);
          setExposedVariable('currentTab', id);
          fireEvent('onTabSwitch');
          setSelectedComponents([]);
        }
      },
      setTabDisable: async function (id, value) {
        setTabItems((prevTabItems) => {
          return prevTabItems.map((tab) => {
            if (tab.id == id) {
              return { ...tab, disable: value };
            }
            return tab;
          });
        });
        setSelectedComponents([]);
      },
      setTabLoading: async function (id, value) {
        setTabItems((prevTabItems) => {
          return prevTabItems.map((tab) => {
            if (tab.id == id) {
              return { ...tab, loading: value };
            }
            return tab;
          });
        });
      },
      setTabVisibility: async function (id, value) {
        setTabItems((prevTabItems) => {
          return prevTabItems.map((tab) => {
            if (tab.id == id) {
              return { ...tab, visible: value };
            }
            return tab;
          });
        });
      },
      currentTab: currentTab,
    };
    setExposedVariables(exposedVariables);

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [setCurrentTab, currentTab]);

  const containerRef = useRef(null);
  const tabsRef = React.useRef(null);
  const [canScrollLeft, setCanScrollLeft] = useState(false);
  const [canScrollRight, setCanScrollRight] = useState(false);
  const [canScroll, setCanScroll] = useState(false);
  const [isHovered, setIsHovered] = useState(false);
  const [hoveredTabId, setHoveredTabId] = useState(null);
  const [isTransitioning, setIsTransitioning] = useState(false);

  const checkScroll = () => {
    if (tabsRef.current) {
      const { scrollLeft, scrollWidth, clientWidth } = tabsRef.current;
      setCanScroll(scrollLeft > 0 || scrollLeft + clientWidth < scrollWidth);
      setCanScrollLeft(scrollLeft > 0);
      setCanScrollRight(scrollLeft + clientWidth < scrollWidth);
    }
  };

  const scrollTabs = (direction) => {
    if (tabsRef.current) {
      const scrollAmount = tabsRef.current.clientWidth / 2;
      tabsRef.current.scrollBy({
        left: direction === 'left' ? -scrollAmount : scrollAmount,
        behavior: 'smooth',
      });
    }
    checkScroll();
  };

  useEffect(() => {
    checkScroll();
    const onScroll = () => checkScroll();
    const currentTabsRef = tabsRef.current;
    if (currentTabsRef) {
      currentTabsRef.addEventListener('scroll', onScroll);
    }

    return () => {
      if (currentTabsRef) {
        currentTabsRef.removeEventListener('scroll', onScroll);
      }
    };
  }, [tabsRef.current, tabWidth, tabItems]);

  useEffect(() => {
    checkScroll();
    const resizeObserver = new ResizeObserver(() => {
      checkScroll();
    });

    if (containerRef.current) {
      resizeObserver.observe(containerRef.current);
    }

    return () => {
      if (containerRef.current) {
        resizeObserver.unobserve(containerRef.current);
      }
    };
  }, []);

  function shouldRenderTabContent(tab) {
    if (parsedRenderOnlyActiveTab) {
      return tab.id == currentTab;
    }
    return true;
  }

  const findTabIndex = (tabId) => {
    return tabItems.findIndex((tab) => tab.id === tabId);
  };

  const handleMouseEnter = (id) => {
    setHoveredTabId(id);
    setIsHovered(true);
  };

  const handleMouseLeave = () => {
    setIsHovered(false);
  };

  function getTabIcon(tab) {
    const iconName = tab?.icon;
    // eslint-disable-next-line import/namespace
    const IconElement = Icons[iconName] == undefined ? Icons['IconHome2'] : Icons[iconName];

    return tab?.iconVisibility ? (
      <IconElement
        color={`${currentTab == tab?.id ? selectedIcon : unselectedIcon}`}
        style={{
          width: '20px',
          height: '20px',
          marginBottom: '3px',
          ...(currentTab == tab.id ? { color: selectedIcon } : { color: unselectedIcon }),
        }}
        stroke={1.5}
      />
    ) : null;
  }

  const equalSplitWidth = 100 / tabItems?.length || 1;
  const someTabsVisible = tabItems?.filter((tab) => tab?.visible !== false);
  return (
    <div
      data-disabled={isDisabled}
      className="card tabs-component scrollbar-container"
      style={{
        height: dynamicHeight ? '100%' : padding === 'default' ? height : height + 4,
        display: isVisible ? 'flex' : 'none',
        backgroundColor: darkMode ? '#324156' : '#fff',
        boxShadow,
        borderRadius: `${borderRadius}px`,
        overflow: 'hidden',
        ...(border ? { border: `1px solid ${border}` } : { border: 'none' }),
      }}
      data-cy={dataCy}
      ref={containerRef}
    >
      {isLoading ? (
        <TabsNavShimmer divider={divider} headerBackground={headerBackground} />
      ) : (
        <div
          style={{
            borderBottom: someTabsVisible?.length > 0 && `0.5px solid ${divider}`,
            alignItems: 'center',
            width: '100%',
            backgroundColor: headerBackground,
            height: '50px',
            display: parsedHideTabs ? 'none' : 'flex',
          }}
        >
          {canScroll && (
            <div
              className="px-2"
              onClick={() => scrollTabs('left')}
              style={{ cursor: canScrollLeft ? 'pointer' : 'default' }}
            >
              <SolidIcon fill={canScrollLeft ? '#6A727C' : '#C1C8CD'} name={'cheveronleft'} />
            </div>
          )}
          {/* this started change */}
          <ul
            ref={tabsRef}
            className="nav"
            data-bs-toggle="tabs"
            style={{
              zIndex: 1,
              display: parsedHideTabs ? 'none' : 'flex',
              backgroundColor: headerBackground,
              overflowX: 'auto',
              whiteSpace: 'nowrap',
              flexWrap: 'nowrap',
              scrollbarWidth: 'none',
              msOverflowStyle: 'none',
              scrollBehavior: 'smooth',
              flexGrow: 1,
              paddingLeft: '10px',
              paddingRight: '10px',
              height: '100%',
            }}
          >
            {tabItems
              ?.filter((tab) => tab?.visible !== false)
              ?.map((tab) => (
                <li
                  className={`nav-item ${currentTab == tab.id ? 'active' : ''}`}
                  style={{
                    opacity: tab?.disable && '0.5',
                    width: tabWidth == 'split' && equalSplitWidth + '%',
                    borderBottom: currentTab === tab.id && !tab?.disable ? `2px solid ${accent}` : ' #CCD1D5',
                    backgroundColor: 'transparent',
                    textOverflow: 'ellipsis',
                    whiteSpace: 'nowrap',
                    fontWeight: 'bold',
                    paddingTop: '.5rem',
                    paddingBottom: '.5rem',
                    cursor: tab?.disable ? 'not-allowed' : 'pointer',
                    ...(tabWidth == 'split' ? { minWidth: 'auto' } : {}), // Remove minWidth for tabWidth != 'split'
                  }}
                  onClick={() => {
                    if (currentTab == tab.id) return;
                    if (tab?.disable) return;

                    if (transition !== 'none') {
                      setIsTransitioning(true);
                      setTimeout(() => setIsTransitioning(false), 300); // Match transition duration
                    }

                    !tab?.disabled && setCurrentTab(tab.id);
                    !tab?.disabled && setExposedVariable('currentTab', tab.id);
                    fireEvent('onTabSwitch');
                  }}
                  onMouseEnter={() => handleMouseEnter(tab?.id)}
                  onMouseLeave={handleMouseLeave}
                  ref={(el) => {
                    if (el && currentTab == tab.id) {
                      el.style.setProperty('color', parsedHighlightColor, 'important');
                    }
                  }}
                  key={tab.id}
                >
                  <div
                    data-disabled={tab?.disable}
                    style={{
                      textAlign: 'center',
                      fontWeight: '500',
                      background:
                        isHovered && hoveredTabId == tab.id
                          ? tinycolor(hoverBackground).setAlpha(0.08).toString()
                          : 'transparent',
                      borderRadius: '6px',
                      paddingLeft: '1rem',
                      paddingRight: '1rem',
                      ...(currentTab == tab.id ? { color: selectedText } : { color: unselectedText }),
                      display: 'flex',
                      flexDirection: 'row',
                      alignItems: 'center',
                      justifyContent: 'center',
                      gap: '4px',
                      height: '28px',
                      paddingTop: '4px',
                      paddingBottom: '4px',
                    }}
                  >
                    {tabWidth === 'split' ? (
                      <>
                        <a style={{ marginRight: '4px' }}>{getTabIcon(tab)}</a>
                        <OverflowTooltip boxWidth={width}>
                          <>{getSafeRenderableValue(tab.title)}</>
                        </OverflowTooltip>
                      </>
                    ) : (
                      <span>
                        <a style={{ marginRight: '4px' }}>{getTabIcon(tab)}</a>
                        {getSafeRenderableValue(tab.title)}
                      </span>
                    )}
                  </div>
                </li>
              ))}
          </ul>
          {/* this ended change */}
          {canScroll && (
            <div
              className="px-2"
              onClick={() => scrollTabs('right')}
              style={{ cursor: canScrollRight ? 'pointer' : 'default' }}
            >
              <SolidIcon fill={canScrollRight ? '#6A727C' : '#C1C8CD'} name="cheveronright" width="25" height="25" />
            </div>
          )}
        </div>
      )}
      {isLoading ? (
        <div
          style={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            height: '100%',
          }}
        >
          <Spinner />
        </div>
      ) : (
        <div
          style={{
            overflow: 'hidden',
            width: '100%',
            height: dynamicHeight ? '100%' : parsedHideTabs ? height : height - 41,
            position: 'relative',
          }}
        >
          {transition === 'none' ? (
            // Simple show/hide when no transition
            tabItems.map((tab) => (
              <div
                key={tab.id}
                style={{
                  display: tab.id === currentTab ? 'block' : 'none',
                  width: '100%',
                  height: '100%',
                  overflow: 'hidden',
                  boxSizing: 'border-box',
                }}
              >
                {shouldRenderTabContent(tab) && (
                  <TabContent
                    id={id}
                    tab={tab}
                    height={height}
                    width={width}
                    parsedHideTabs={parsedHideTabs}
                    bgColor={bgColor}
                    darkMode={darkMode}
                    dynamicHeight={dynamicHeight}
                    currentTab={currentTab}
                    isTransitioning={isTransitioning}
                  />
                )}
              </div>
            ))
          ) : (
            // Sliding animation when transition is enabled
            <div
              style={{
                display: 'flex',
                width: `${tabItems.length * 100}%`,
                transform: `translateX(-${findTabIndex(currentTab) * (100 / tabItems.length)}%)`,
                transition: 'transform 0.3s ease-in-out',
                height: '100%',
                position: 'relative',
                overflow: 'hidden',
              }}
            >
              {tabItems.map((tab) => (
                <div
                  key={tab.id}
                  style={{
                    width: `${100 / tabItems.length}%`,
                    flexShrink: 0,
                    height: '100%',
                    overflow: 'hidden',
                    boxSizing: 'border-box',
                    minWidth: 0,
                    contain: 'layout style size',
                  }}
                >
                  {shouldRenderTabContent(tab) && (
                    <TabContent
                      id={id}
                      tab={tab}
                      height={height}
                      width={width}
                      parsedHideTabs={parsedHideTabs}
                      bgColor={bgColor}
                      darkMode={darkMode}
                      dynamicHeight={dynamicHeight}
                      currentTab={currentTab}
                      isTransitioning={isTransitioning}
                    />
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const areEqual = (prevProps, nextProps) => {
  const allKeys = new Set([...Object.keys(prevProps), ...Object.keys(nextProps)]);
  let hasChanges = false;

  for (let key of allKeys) {
    if (prevProps[key] !== nextProps[key]) {
      hasChanges = true;
    }
  }

  return !hasChanges;
};

const TabContent = memo(function TabContent({
  id,
  tab,
  height,
  width,
  parsedHideTabs,
  bgColor,
  darkMode,
  dynamicHeight,
  currentTab,
  isTransitioning,
}) {
  const loading = tab?.loading;
  const disable = tab?.disable;
  const visible = tab?.visible;

  const fieldBackgroundColor = tab?.fieldBackgroundColor;
  if (visible === false) return null;

  return (
    <div
      data-disabled={disable}
      activetab={currentTab}
      className={`tab-pane active ${dynamicHeight && currentTab === tab.id && `dynamic-${id}`}`}
      style={{
        display: 'block',
        height: dynamicHeight ? '100%' : parsedHideTabs ? height : height - 41,
        position: 'relative',
        top: '0px',
        width: '100%',
        backgroundColor: fieldBackgroundColor || bgColor,
        opacity: disable ? 0.5 : 1,
        pointerEvents: disable ? 'none' : 'auto',
        overflow: 'hidden', // Ensure TabContent doesn't overflow
        boxSizing: 'border-box', // Include padding/border in size calculation
      }}
    >
      {loading ? (
        <div
          style={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            height: '100%',
          }}
        >
          <Spinner />
        </div>
      ) : (
        <SubContainer
          id={`${id}-${tab.id}`}
          canvasHeight={dynamicHeight ? '100%' : '200'}
          canvasWidth={width}
          allowContainerSelect={true}
          styles={{
            overflow: isTransitioning ? 'hidden' : 'hidden auto',
            backgroundColor: fieldBackgroundColor || bgColor,
            opacity: disable ? 0.5 : 1,
            width: '100%', // Ensure it doesn't exceed container width
            maxWidth: '100%', // Additional constraint
            boxSizing: 'border-box', // Include padding/border in width
            contain: 'layout style', // Add containment for better overflow control
          }}
          darkMode={darkMode}
        />
      )}
    </div>
  );
},
areEqual);
