import { Controller, useFormContext } from 'react-hook-form';

import Box from '@material-hu/mui/Box';
import Tooltip from '@material-hu/mui/Tooltip';

import { useAuth } from 'src/contexts/JWTContext';
import { InputType, BoxProperty, BoxData } from 'src/types/forms';
import {
  getAnswerAutocompleteField,
  getInputTooltipTitle,
} from 'src/utils/form';
import { useLokaliseTranslation } from 'src/utils/i18n';

import DigitalSignInput from '../formDetail/inputs/DigitalSignInput';

const PDF_BORDER_BRAND = '#C5D4F8'; // Border/Neutral/Brand — Brand/200 (DS 2.1)
const PDF_BORDER_DEFAULT = '#DFE0E6'; // Border/Neutral/Default — Grey/200 (DS 2.1)
const PDF_BG_GREY = '#EEEEF1'; // Background/Elements/Grey — Grey/100 (DS 2.1)

export type PDFInput = {
  id?: number;
  inputType?: InputType;
  description?: string;
  currentPage?: number;
  userField?: string;
  autoCompleteBoss?: string;
  // The original data plus pixel-based fields for zoom-adjusted positioning
  boxData: BoxData & {
    xPx?: number;
    yPx?: number;
    widthPx?: number;
    heightPx?: number;
  };
  boxProperties: BoxProperty;
  required?: boolean;
};

const getInput = {
  [InputType.DIGITAL_SIGN]: (props: PDFInput) => {
    const { control } = useFormContext();
    const { id, inputType, required, boxData, currentPage } = props;
    const { xPx, yPx, widthPx, heightPx, page } = boxData;

    return (
      <Box
        sx={{
          // Show only on correct page
          display: page === (currentPage ?? 1) - 1 ? 'inherit' : 'none',
          border: `1px solid ${PDF_BORDER_BRAND}`,
          position: 'absolute',
          width: widthPx,
          height: heightPx,
          top: yPx,
          left: xPx,
        }}
      >
        <Controller
          name={`${inputType}-${id}`}
          rules={{ required }}
          control={control}
          render={({ field: { onChange, value } }) => (
            <DigitalSignInput
              signOnPdf
              onChange={onChange}
              inputDigitalSign={value}
              required={required}
              disabled={false}
            />
          )}
        />
      </Box>
    );
  },

  [InputType.TEXT]: (props: PDFInput) => {
    const { control } = useFormContext();
    const {
      id,
      inputType,
      description,
      required,
      boxData,
      boxProperties,
      currentPage,
    } = props;
    const { xPx, yPx, widthPx, heightPx, page } = boxData;
    const { inputLimit, color, fontFamily, fontSize, fontStyle, fontWeight } =
      boxProperties;

    return (
      <Controller
        control={control}
        name={`${inputType}-${id}`}
        rules={{ required }}
        defaultValue={''}
        render={({ field: { onChange, onBlur, value, name } }) => (
          <Tooltip
            title={getInputTooltipTitle(
              value,
              description,
              required,
              inputLimit,
            )}
          >
            <input
              onBlur={onBlur}
              onChange={onChange}
              type="text"
              value={value}
              key={`${inputType}-${id}`}
              name={name}
              placeholder={`${required ? '*' : ''}${description}`}
              maxLength={inputLimit}
              style={{
                border: `2px solid ${PDF_BORDER_BRAND}`,
                display: page === (currentPage ?? 1) - 1 ? 'inherit' : 'none',
                backgroundColor: 'transparent',
                position: 'absolute',
                width: widthPx,
                height: heightPx,
                top: yPx,
                left: xPx,
                padding: '6px 2px',
                fontSize: `${fontSize}px`,
                color,
                fontFamily,
                fontWeight,
                fontStyle,
              }}
            />
          </Tooltip>
        )}
      />
    );
  },

  [InputType.TEXT_AREA]: (props: PDFInput) => {
    const { control } = useFormContext();
    const {
      id,
      inputType,
      description,
      required,
      boxData,
      boxProperties,
      currentPage,
    } = props;
    const { xPx, yPx, widthPx, heightPx, page } = boxData;
    const { inputLimit, color, fontFamily, fontSize, fontStyle, fontWeight } =
      boxProperties;

    return (
      <Controller
        control={control}
        name={`${inputType}-${id}`}
        rules={{ required }}
        defaultValue={''}
        render={({ field: { onChange, onBlur, value, name } }) => (
          <Tooltip
            title={getInputTooltipTitle(
              value,
              description,
              required,
              inputLimit,
            )}
          >
            <textarea
              onBlur={onBlur}
              onChange={onChange}
              value={value}
              key={`${inputType}-${id}`}
              name={name}
              placeholder={`${required ? '*' : ''}${description}`}
              maxLength={inputLimit}
              style={{
                border: `2px solid ${PDF_BORDER_BRAND}`,
                display: page === (currentPage ?? 1) - 1 ? 'inherit' : 'none',
                backgroundColor: 'transparent',
                position: 'absolute',
                width: widthPx,
                height: heightPx,
                top: yPx,
                left: xPx,
                padding: '6px 2px',
                fontSize: `${fontSize}px`,
                color,
                fontFamily,
                fontWeight,
                fontStyle,
              }}
            />
          </Tooltip>
        )}
      />
    );
  },

  [InputType.AUTOCOMPLETE]: (props: PDFInput) => {
    const { user } = useAuth();
    const { t } = useLokaliseTranslation('forms');
    const { control } = useFormContext();
    const {
      id,
      inputType,
      description,
      userField,
      autoCompleteBoss,
      required,
      boxData,
      boxProperties,
      currentPage,
    } = props;
    const { xPx, yPx, widthPx, heightPx, page } = boxData;
    const { inputLimit, color, fontFamily, fontSize, fontStyle, fontWeight } =
      boxProperties;

    return (
      <Controller
        control={control}
        name={`${inputType}-${id}-${userField}`}
        rules={{ required }}
        defaultValue={getAnswerAutocompleteField(
          userField,
          autoCompleteBoss,
          user,
          t,
        )}
        render={({ field: { onChange, onBlur, value, name } }) => (
          <Tooltip title={`${description} 🔒`}>
            <input
              disabled
              onBlur={onBlur}
              onChange={onChange}
              type="text"
              value={value}
              key={`${inputType}-${id}-${userField}`}
              name={name}
              placeholder={`${required ? '*' : ''}${description}`}
              maxLength={inputLimit}
              style={{
                border: `2px solid ${PDF_BORDER_DEFAULT}`,
                display: page === (currentPage ?? 1) - 1 ? 'inherit' : 'none',
                backgroundColor: PDF_BG_GREY,
                position: 'absolute',
                width: widthPx,
                height: heightPx,
                top: yPx,
                left: xPx,
                padding: '6px 2px',
                fontSize: `${fontSize}px`,
                color,
                fontFamily,
                fontWeight,
                fontStyle,
              }}
            />
          </Tooltip>
        )}
      />
    );
  },

  [InputType.INTEGER]: (props: PDFInput) => {
    const { t } = useLokaliseTranslation('forms');
    const { control } = useFormContext();
    const {
      id,
      inputType,
      description,
      required,
      boxData,
      boxProperties,
      currentPage,
    } = props;
    const { xPx, yPx, widthPx, heightPx, page } = boxData;
    const { inputLimit, color, fontFamily, fontSize, fontStyle, fontWeight } =
      boxProperties;

    const handleInput = event => {
      const input = event.target;
      const { value } = input;

      if (/^[+]?\d*$/.test(value)) {
        input.previousValue = value;
      } else {
        input.value = input.previousValue || '';
      }
    };

    const getTitle = (value: string) => {
      let showDescription = `${description} ${t('PDF_ONLY_NUMBERS')}`;
      if (required) {
        showDescription = `* ${showDescription}`;
      }
      if (inputLimit) {
        showDescription = `${showDescription} • (${value.length}/${inputLimit})`;
      }
      return showDescription;
    };

    return (
      <Controller
        control={control}
        name={`${inputType}-${id}`}
        rules={{ required }}
        defaultValue={''}
        render={({ field: { onChange, onBlur, value, name } }) => (
          <Tooltip title={getTitle(value)}>
            <input
              onInput={handleInput}
              onBlur={onBlur}
              onChange={onChange}
              type="text"
              value={value}
              key={`${inputType}-${id}`}
              name={name}
              placeholder={`${required ? '*' : ''}${description}`}
              maxLength={inputLimit}
              style={{
                border: `2px solid ${PDF_BORDER_BRAND}`,
                display: page === (currentPage ?? 1) - 1 ? 'inherit' : 'none',
                backgroundColor: 'transparent',
                position: 'absolute',
                width: widthPx,
                height: heightPx,
                top: yPx,
                left: xPx,
                padding: '6px 2px',
                fontSize: `${fontSize}px`,
                color,
                fontFamily,
                fontWeight,
                fontStyle,
              }}
            />
          </Tooltip>
        )}
      />
    );
  },
};

export const GetPdfInputComponent = (props: PDFInput) => {
  const { inputType } = props;
  if (!inputType || !getInput[inputType]) return null;
  return getInput[inputType](props);
};

export default GetPdfInputComponent;
