import React, { memo, useState, isValidElement, useRef } from 'react';
import { joinClassNames } from '@vizality/util/dom';
import { isComponent } from '@vizality/util/react';
import { getModule } from '@vizality/webpack';
import { useMeasure, useToggle } from '@vizality/hooks';
import { motion } from 'framer-motion';

import { Icon } from '..';

/**
 * @component
 * Some parts sourced from @see {@link https://codesandbox.io/s/animate-height-framer-motion-yn59l?file=/src/AnimateHeight.js}
 */
export default memo(({ title, description, icon, children, opened, className, ...other }) => {
  const [ collapsed, toggleCollapsed ] = useToggle(opened === undefined ? !opened : true);
  const { description: _description, label } = getModule('icon', 'container', 'description');
  const { size12, size16 } = getModule('size10', 'size12', 'size16');
  const ref = useRef(null);
  const bounds = useMeasure(ref);

  /**
   * Get the duration of the animation depending upon the height provided.
   * @param {number} height of container
   */
  const getAutoHeightDuration = height => {
    if (!height) {
      return 0;
    }
    const constant = height / 36;
    return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10);
  };

  return (
    <div
      className={joinClassNames('vz-settings-item', 'vz-settings-category', className)}
      vz-expanded={!collapsed && ''}
      vz-collapsed={collapsed && ''}
      {...other}
    >
      <div
        className='vz-settings-category-title-wrapper'
        onClick={toggleCollapsed}
        tabindex='0'
      >
        {(isComponent(icon) || isValidElement(icon)) && icon}
        {icon && typeof icon === 'string' && (
          <Icon
            name={icon}
            className='vz-settings-category-icon-wrapper'
            iconClassName='vz-settings-category-icon'
          />
        )}
        <div className={joinClassNames('vz-settings-category-meta', _description)}>
          <div className={joinClassNames('vz-settings-category-title', label, size16)}>
            {title}
          </div>
          <div className={joinClassNames('vz-settings-category-description', size12)}>
            {description}
          </div>
        </div>
        <Icon
          className='vz-settings-category-title-icon-wrapper'
          iconClassName='vz-settings-category-title-icon'
          name='caret-right'
          size='18'
        />
      </div>
      <motion.div
        className='vz-settings-category-inner'
        initial={!collapsed ? 'open' : 'collapsed'}
        animate={!collapsed ? 'open' : 'collapsed'}
        inherit={false}
        variants={{
          open: {
            height: 'auto',
            overflow: 'visible',
            transition: {
              height: {
                duration: getAutoHeightDuration(bounds.height) / 2000
              },
              overflow: {
                duration: 0,
                delay: getAutoHeightDuration(bounds.height) / 2000
              }
            }
          },
          collapsed: {
            height: 0,
            overflow: 'hidden',
            transition: {
              height: {
                duration: getAutoHeightDuration(bounds.height) / 2000
              },
              overflow: {
                duration: 0,
                delay: 0
              }
            }
          }
        }}
      >
        <div ref={ref} className='vz-settings-category-contents'>
          {children}
        </div>
        {/* {typeof children === 'function'
          ? (
            children(ref)
          )
          : (
            <div ref={ref} className='vz-settings-category-contents'>
              {children}
            </div>
          )
        } */}
      </motion.div>
    </div>
  );
});
