import { createElement, PropsWithChildren, useState } from 'react';

import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import CloseIcon from '@mui/icons-material/Close';

import { getInstructions, getInstructionsType, getDismissBanner, mapInstructionsTypeToBannerVariant } from '@pega/react-sdk-components/lib/components/helpers/template-utils';
import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
import connectToState from '@pega/react-sdk-components/lib/components/helpers/state-utils';

import { getKeyForMappedField, mapStateToProps } from './utils';
import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';

import './DefaultForm.css';
import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';

interface {{COMPONENT_CLASS_NAME}}Props extends PConnProps {
  // If any, enter additional props that only exist on this component
  NumCols: string;
  instructions: string;
}

const Child = connectToState(mapStateToProps)(props => {
  const { key, visibility, ...rest } = props;

  return createElement(createPConnectComponent(), { ...rest, key, visibility });
});

const bannerIconMap = {
  info: <InfoOutlinedIcon fontSize='small' />,
  warning: <WarningAmberIcon fontSize='small' />,
  success: <CheckCircleOutlineIcon fontSize='small' />
};

// Duplicated runtime code from React SDK

// props passed in combination of props from property panel (config.json) and run time props from Constellation
export default function {{COMPONENT_CLASS_NAME}}(props: PropsWithChildren<{{COMPONENT_CLASS_NAME}}Props>) {
  const { getPConnect, NumCols = '1' } = props;
  const instructions = getInstructions(getPConnect(), props.instructions);
  const [bannerDismissed, setBannerDismissed] = useState(false);

  const instructionsType = getInstructionsType(props.instructions);
  const isBanner = typeof props.instructions === 'object' && (props.instructions as any)?.isBanner;
  const dismissBanner = getDismissBanner(props.instructions);
  const bannerVariant = mapInstructionsTypeToBannerVariant(instructionsType);

  let divClass: string;

  const numCols = NumCols || '1';
  switch (numCols) {
    case '1':
      divClass = 'psdk-default-form-one-column';
      break;
    case '2':
      divClass = 'psdk-default-form-two-column';
      break;
    case '3':
      divClass = 'psdk-default-form-three-column';
      break;
    default:
      divClass = 'psdk-default-form-one-column';
      break;
  }

  // debugger;

  // repoint the children because they are in a region and we need to not render the region
  // to take the children and create components for them, put in an array and pass as the
  // defaultForm kids
  const arChildren = getPConnect().getChildren()[0].getPConnect().getChildren();
  const dfChildren = arChildren?.map(kid => <Child key={getKeyForMappedField(kid)} {...kid} />);

  const renderInstructions = () => {
    if (!instructions || bannerDismissed) return null;

    if (isBanner) {
      return (
        {{! pick new delimiters for mustache }}
        {{=<% %>=}}
        <div className={`psdk-banner psdk-banner-${bannerVariant}`}>
          <div className='psdk-banner-icon'>{bannerIconMap[bannerVariant]}</div>
          <div className='psdk-banner-content' dangerouslySetInnerHTML={{ __html: instructions }} />
          {dismissBanner && (
            <button type='button' className='psdk-banner-dismiss' aria-label='Dismiss banner' onClick={() => setBannerDismissed(true)}>
              <CloseIcon fontSize='small' />
            </button>
          )}
        </div>
        <%={{ }}=%>     {{! revert delimiters for mustache }}
      );
    }

    return (
      <div className='psdk-default-form-instruction-text'>
        {/* server performs sanitization method for instructions html content */}
        {{! pick new delimiters for mustache }}
        {{=<% %>=}}
        <div key='instructions' id='instruction-text' dangerouslySetInnerHTML={{ __html: instructions }} />
        <%={{ }}=%>     {{! revert delimiters for mustache }}
      </div>
    );
  };

  return (
    <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
      <>
        {renderInstructions()}
        <div className={divClass}>{dfChildren}</div>
      </>
    </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
  );
}
