import { useContext, useMemo, Suspense, lazy } from '@wordpress/element';
import { useStore } from 'zustand';
import { DesignContext } from '@components/DesignPanel/DesignStore';
import { CurrentOptionProps } from '@components/DesignPanel/types';
import ModifierDefault from '@components/DesignPanel/ModifierDefault';

import {
  createCompleteOptions,
  getMergedDesignList,
} from '@components/DesignPanel/Helpers';

import { DesignClassToStore } from '@components/DesignPanel/DesignStoreActions';
import { DesignState } from '@components/DesignPanel/DesignStore';

import { useActiveOptionValue } from '@components/DesignPanel/hooks/useActiveOptionvalue';

import { ControlModifierProps } from '@components/DesignPanel/types';

/*
  Wrapper for the controls that inits the modifiers
  Dynamic controls are supported here
  Handles the current options of the design
*/
export const ControlModifier: React.FC<ControlModifierProps> = ({
  control,
}) => {
  const store = useStore(useContext(DesignContext));
  const {
    currentDesign,
    setCurrentDesign,
    currentResponsive,
    currentInteraction,
    currentStrategies,
  } = store;

  /*
     Here we only load dynamic controls on a control base (above the modifiers)
  */
  const DynamicComponent = useMemo(() => {
    return control?.dynamicControl
      ? lazy(
          () =>
            import(
              `@components/DesignPanel/DynamicControls/${control.dynamicControl}`
            )
        )
      : ModifierDefault;
  }, [control?.dynamicControl]);

  /*
    Handles the current options of the design
  */
  const handleCurrentOptions = (options: CurrentOptionProps) => {
    // Prepare the options with the current design context state (screen, interaction, strategies)
    const completeOptions = createCompleteOptions(
      options,
      currentResponsive,
      currentInteraction,
      currentStrategies
    );
    // Merge the new options of with the current design list
    const newDesignList = getMergedDesignList(
      [...currentDesign],
      [...completeOptions]
    );

    setCurrentDesign([...newDesignList]);
    DesignClassToStore(newDesignList, store as DesignState);
  };

  /* Conditional Hook */
  const activeConditionalVale = useActiveOptionValue(
    control?.conditional?.id,
    store,
    true
  );

  return (
    <div>
      {(activeConditionalVale === control?.conditional?.value ||
        !control?.conditional?.id) && (
        <div>
          <Suspense fallback={<div className="block min-h-[170px]"></div>}>
            <DynamicComponent
              currentControlId={control.id}
              currentControlLabel={control.label}
              display={control?.display}
              modifiers={control.modifiers}
              emitOptions={(options: CurrentOptionProps) => {
                handleCurrentOptions(options);
              }}
            />
          </Suspense>
        </div>
      )}
    </div>
  );
};

export default ControlModifier;
