import { Fragment, useMemo } from 'react';

import { Box } from '@cleartrip/ct-design-box';
import { Divider } from '@cleartrip/ct-design-divider';
import { InputField, FieldChangeEvent } from '@cleartrip/ct-design-field';
import { Typography } from '@cleartrip/ct-design-typography';
import { AlertCallout } from '@cleartrip/ct-design-alert-callout';
import { Button } from '@cleartrip/ct-design-button';
import { isEmpty } from '@cleartrip/ct-design-common-utils';

import { GVListItem } from './GVListItem';
import { IGiftVoucher } from '../type';
import { CALLOUT_TYPORAPHY_COLOR } from '../constants';

const GVSection: React.FC<IGiftVoucher> = ({ gvApplyCTA, gvField, pinField, gvList = [], infoCallout }) => {
  const {
    text: infoCalloutText,
    prefixIcon: infoCalloutPrefixIcon,
    variant: infoCalloutVariant = CALLOUT_TYPORAPHY_COLOR.info,
  } = infoCallout || {};

  const {
    onChange: onGvChange,
    placeholder: gvPlaceholder,
    value: gvValue,
    errorMessage: gvErrorMessage,
    onBlur: onGvBlur,
    max: gvMaxLimit,
  } = gvField || {};

  const {
    onChange: onGvPinChange,
    placeholder: gvPinPlaceholder,
    value: gvPinValue,
    errorMessage: gvPinErrorMessage,
    onBlur: onGvPinBlur,
    max: pinMaxLimit,
  } = pinField || {};

  const {
    label: gvApplyCTALabel,
    onClick: onGVApplyClick,
    disabled: gvApplyCTADisabled = false,
    isLoading: gvApplyCTAIsLoading = false,
  } = gvApplyCTA || {};

  const gvFieldPrompt = useMemo(() => {
    return {
      hasError: gvErrorMessage ? true : false,
      message: gvErrorMessage,
    };
  }, [gvErrorMessage]);

  const gvPinFieldPrompt = useMemo(() => {
    return {
      hasError: gvPinErrorMessage ? true : false,
      message: gvPinErrorMessage,
    };
  }, [gvPinErrorMessage]);

  const onGvChangeHandler = (e: FieldChangeEvent) => {
    const value = e.target.value;
    const updatedValue = (value || '').replaceAll(' ', '');
    if (!gvMaxLimit || (gvMaxLimit && updatedValue.length <= gvMaxLimit)) {
      onGvChange?.(e);
    }
  };

  const onGvPinChangeHandler = (e: FieldChangeEvent) => {
    const value = e.target.value;
    if (!pinMaxLimit || (pinMaxLimit && value.length <= pinMaxLimit)) {
      onGvPinChange?.(e);
    }
  };

  return (
    <Box boxSize='medium'>
      {!isEmpty(infoCallout) && (
        <AlertCallout
          textNode={<Typography variant='P3'>{infoCalloutText}</Typography>}
          variant={infoCalloutVariant as keyof typeof CALLOUT_TYPORAPHY_COLOR}
          prefixIconNode={infoCalloutPrefixIcon}
        />
      )}
      <InputField
        value={gvValue}
        placeholder={gvPlaceholder}
        onChange={onGvChangeHandler}
        onBlur={onGvBlur}
        prompt={gvFieldPrompt}
        id={gvPlaceholder}
      />
      <InputField
        value={gvPinValue}
        placeholder={gvPinPlaceholder}
        onChange={onGvPinChangeHandler}
        onBlur={onGvPinBlur}
        prompt={gvPinFieldPrompt}
        id={gvPinPlaceholder}
        type='number'
      />
      <Button onClick={onGVApplyClick} disabled={gvApplyCTADisabled} loading={gvApplyCTAIsLoading}>
        {gvApplyCTALabel}
      </Button>
      {!isEmpty(gvList) && (
        <Fragment>
          <Divider dividerType='dashed' dividerColor='#E6E6E6' dividerWidth={1} />
          {gvList.map((gvListItem) => {
            const { gvCode } = gvListItem || {};
            return <GVListItem key={gvCode} {...gvListItem} />;
          })}
        </Fragment>
      )}
    </Box>
  );
};

export default GVSection;
