import React, { useContext, useEffect, useRef } from 'react';
import SkeletonThemeWrapper from "../../customization-cornor/skeletonCustomization";
import useSelectionControl from "../../custom-hooks/useSelectionControl";
import TabContext from './TabContext';
import { Tab, TabBar, TabBarNavLine, TabContent, TabPanel } from './Tab';
import useTabAriaProps from './useTabAriaProps';
import useFocusVisible from "@zohodesk/hooks/es/accessiblity/useFocusVisible";
/**
 * To check equal condition of logic of Tab checked
 * @param {*} currentValue 
 * @param {*} selectedValue
 * @returns 
 */

const tabCondition = (currentValue, selectedValue) => {
  return currentValue === selectedValue;
};
/**
 * To check the orientation matches returned object
 * @param {*} orientation 
 * @returns 
 */


const getSizeProperties = orientation => {
  if (orientation === 'vertical') {
    return {
      width: offsetWidth,
      left: offsetLeft
    };
  } else {
    return {
      top: offsetTop,
      height: offsetHeight
    };
  }
};
/**
 * To handle the item-onChange-Callback and group-onChangeCallback in skeleton 
 * @param {*} onChange 
 * @param {*} itemOnChange 
 * @returns 
 */


const onChangeCallbackHandler = (onChange, itemOnChange, callBack) => {
  if (!itemOnChange) {
    return (value, itemId, e) => {
      onChange && onChange(value, e);
      callBack && callBack(itemId, e);
    };
  }

  return (value, itemId, e) => {
    onChange && onChange(value, e);
    itemOnChange && itemOnChange(value, e);
    callBack && callBack(itemId, e);
  };
};

export default function TabContainerBehaviour(props) {
  let {
    renderComponent,
    children,
    ...basicProps
  } = props;
  const [selectedValue, onChange] = useSelectionControl(props, props.reducer);
  let {
    tabListProps,
    tabProps,
    tabPanelProps,
    focusFirst
  } = useTabAriaProps(props);
  let renderChildren = React.Children.map(children, (child, i) => {
    if (child && (child.type === TabBar || child.type === TabBarNavLine || child.type === TabContent)) {
      return /*#__PURE__*/React.cloneElement(child, {
        key: i,
        selectedValue,
        onChange,
        tabListProps,
        tabProps,
        tabPanelProps,
        focusFirst
      });
    }
  });
  let renderProps = {
    selectedValue,
    onChange,
    children: renderChildren
  };
  return /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  });
}
export function TabContextBehaviour(props) {
  const [selectedValue, onChange] = useSelectionControl(props, props.reducer);
  let {
    tabListProps,
    tabProps,
    tabPanelProps,
    focusFirst
  } = useTabAriaProps(props);
  let {
    renderComponent,
    defaultValue,
    ...basicProps
  } = props;
  let renderProps = {
    selectedValue,
    onChange
  };
  return /*#__PURE__*/React.createElement(TabContext.Provider, {
    value: {
      selectedValue: selectedValue || defaultValue,
      onChange,
      tabListProps,
      tabProps,
      tabPanelProps,
      focusFirst
    }
  }, /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  }));
}
export function TabBarBehaviour(props) {
  let {
    renderComponent,
    children,
    selectedValue,
    onChange,
    tabListProps,
    tabProps,
    focusFirst,
    ...basicProps
  } = props;
  let tabContext = useContext(TabContext);

  if (tabContext) {
    tabListProps = tabContext.tabListProps, focusFirst = tabContext.focusFirst;
  }

  let renderChildren = React.Children.map(children, (child, i) => {
    if (child && child.type === Tab) {
      return /*#__PURE__*/React.cloneElement(child, {
        key: i,
        selectedValue,
        onChange: onChangeCallbackHandler(onChange, child.props.onChange, itemId => {
          focusFirst(itemId);
        }),
        tabProps,
        focusFirst
      });
    }
  });
  let renderProps = {
    children: renderChildren,
    tabListAriaProps: tabListProps && tabListProps(props)
  };
  return /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  });
}
export function TabBarNavLineBehaviour(props) {
  let {
    renderComponent,
    selectedValue,
    children,
    onChange,
    tabListProps,
    tabProps,
    focusFirst,
    ...basicProps
  } = props;
  let tabContext = useContext(TabContext);

  if (tabContext) {
    selectedValue = tabContext.selectedValue;
    tabListProps = tabContext.tabListProps;
    focusFirst = tabContext.focusFirst;
  }

  let tabItemEle = useRef({});
  let navLineEle = null;

  let navLineRef = ele => {
    navLineEle = ele;
  };

  let tabIemRef = (ele, value) => {
    tabItemEle.current[value] = ele;
  };

  let renderChildren = React.Children.map(children, (child, i) => {
    if (child && child.type === Tab) {
      return /*#__PURE__*/React.cloneElement(child, {
        key: i,
        selectedValue,
        onChange: onChangeCallbackHandler(onChange, child.props.onChange, itemId => {
          focusFirst(itemId);
        }),
        tabIemRef: tabIemRef,
        tabProps,
        focusFirst
      });
    }
  });
  let renderProps = {
    children: renderChildren,
    navLineRef,
    tabListAriaProps: tabListProps && tabListProps(props)
  };
  useEffect(() => {
    Object.keys(tabItemEle.current).forEach(value => {
      if (value === selectedValue) {
        navLineEle.style.width = tabItemEle.current[value].offsetWidth + 'px';
        navLineEle.style.left = tabItemEle.current[value].offsetLeft + 'px';
      }
    });
  }, [selectedValue]);
  return /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  });
}
export function TabBehaviour(props) {
  let {
    selectedValue,
    onChange: onChangeWrapping,
    value,
    tabIemRef,
    tabProps,
    focusFirst
  } = props;
  let tabContext = useContext(TabContext);

  if (tabContext) {
    selectedValue = tabContext.selectedValue;
    onChangeWrapping = onChangeCallbackHandler(tabContext.onChange, props.onChange, itemId => {
      tabContext.focusFirst(itemId);
    });
    tabProps = tabContext.tabProps;
  }

  let getRef = ele => {
    tabIemRef && tabIemRef(ele, value);
  };

  let active = tabCondition(value, selectedValue);
  let {
    itemId,
    ...ariaItems
  } = tabProps && tabProps({
    active,
    ...props
  });
  let {
    focusProps
  } = useFocusVisible({
    onFocus: () => {
      focusFirst(itemId);
    }
  });
  let renderProps = {
    selectedValue,
    onChange: onChangeWrapping.bind(null, value, itemId),
    active,
    getRef,
    tabAriaProps: ariaItems,
    focusProps
  };
  let {
    renderComponent,
    ...basicProps
  } = props;
  return /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  });
}
export function TabContentBehaviour(props) {
  let {
    renderComponent,
    selectedValue,
    children,
    tabPanelProps,
    ...basicProps
  } = props;
  let renderChildren = React.Children.map(children, (child, i) => {
    if (child && child.type === TabPanel) {
      return /*#__PURE__*/React.cloneElement(child, {
        key: i,
        selectedValue,
        tabPanelProps
      });
    }
  });
  let renderProps = {
    selectedValue,
    children: renderChildren
  };
  return /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  });
}
export function TabPanelBehaviour(props) {
  let {
    selectedValue,
    tabPanelProps
  } = props;
  let tabContext = useContext(TabContext);

  if (tabContext) {
    selectedValue = tabContext.selectedValue, tabPanelProps = tabContext.tabPanelProps;
  }

  let renderProps = {
    selectedValue,
    tabCondition,
    tabPanelAriaProps: tabPanelProps && tabPanelProps(props)
  };
  let {
    renderComponent,
    ...basicProps
  } = props;
  return /*#__PURE__*/React.createElement(SkeletonThemeWrapper, {
    basicProps: basicProps,
    renderProps: renderProps,
    component: renderComponent
  });
}