import { type FC, useMemo } from 'react';
import { Controller } from 'react-hook-form';

import Stack from '@material-hu/mui/Stack';
import { AdapterDateFns } from '@material-hu/mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@material-hu/mui/x-date-pickers/LocalizationProvider';

import { type AutocompleteOption } from '@material-hu/components/design-system/Inputs/Autocomplete/types';

import {
  type AutocompleteAnswer,
  InputType,
  type SectionComponent,
} from 'src/pages/dashboard/serviceManagement/types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { usePdfCompletion } from '../../contexts/PdfFormCompletionProvider';
import {
  DEFAULT_COLOR,
  DEFAULT_FONT_FAMILY,
  DEFAULT_FONT_SIZE,
  DEFAULT_FONT_STYLE,
  DEFAULT_FONT_WEIGHT,
  DEFAULT_FONT_WEIGHT_BOLD,
} from '../utils/constants';

import AutocompleteField from './AutocompleteField';
import CheckboxField from './CheckboxField';
import DateField from './DateField';
import DropdownField from './DropdownField';
import MultipleChoiceField from './MultipleChoiceField';
import SignatureField from './SignatureField';
import TextField from './TextField';

type Props = {
  field: SectionComponent;
  pageDimensions: {
    width: number;
    height: number;
  };
};

const FieldWrapper: FC<Props> = ({ field, pageDimensions }) => {
  const { t } = useLokaliseTranslation(['service_management', 'general']);
  const { scale } = usePdfCompletion();

  // Convert relative dimensions to pixels
  const pxDimensions = {
    width: (field.pdfLayout?.width ?? 0) * pageDimensions.width * scale,
    height: (field.pdfLayout?.height ?? 0) * pageDimensions.height * scale,
    x: (field.pdfLayout?.x ?? 0) * pageDimensions.width * scale,
    y: (field.pdfLayout?.y ?? 0) * pageDimensions.height * scale,
  };

  const styles = useMemo(
    () => ({
      color: field.pdfStyles?.color || DEFAULT_COLOR,
      fontFamily: field.pdfStyles?.fontFamily || DEFAULT_FONT_FAMILY,
      fontSize:
        Math.round(
          Number(field.pdfStyles?.fontSize || DEFAULT_FONT_SIZE) * scale * 100,
        ) / 100,
      fontWeight:
        field.pdfStyles?.fontWeight === 'bold'
          ? DEFAULT_FONT_WEIGHT_BOLD
          : DEFAULT_FONT_WEIGHT,
      fontStyle: field.pdfStyles?.fontStyle || DEFAULT_FONT_STYLE,
      lineHeight: 1,
    }),
    [scale, field.pdfStyles],
  );

  const getInputFieldByType = () => {
    switch (field.type) {
      case InputType.TEXT:
      case InputType.INTEGER:
      case InputType.FLOAT:
        return (
          <TextField
            field={field}
            textStyles={styles}
            dimensions={pxDimensions}
          />
        );
      case InputType.SIGNATURE:
        return (
          <Controller
            name={field.nameId}
            rules={{ required: field.content.required }}
            render={({ field: { onChange, value } }) => (
              <SignatureField
                field={field}
                onChange={onChange}
                inputDigitalSign={value}
                dimensions={pxDimensions}
              />
            )}
          />
        );

      case InputType.DROPDOWN: {
        const options: AutocompleteOption[] =
          field.content.choices?.map((choice: string, index: number) => ({
            value: index,
            label: choice,
          })) || [];
        return (
          <DropdownField
            field={field}
            dimensions={pxDimensions}
            options={options}
            textStyles={styles}
          />
        );
      }
      case InputType.AUTOCOMPLETE:
        return (
          <AutocompleteField
            name={field.nameId}
            title={field.content.title}
            dimensions={pxDimensions}
            answer={field.answer as unknown as AutocompleteAnswer}
            textStyles={styles}
          />
        );
      case InputType.DATE:
        return (
          <LocalizationProvider
            dateAdapter={AdapterDateFns}
            localeText={{
              clearButtonLabel: t('general:clear'),
              okButtonLabel: t('general:accept'),
            }}
          >
            <DateField
              field={field}
              dimensions={pxDimensions}
              textStyles={styles}
            />
          </LocalizationProvider>
        );

      case InputType.CHECKBOX:
        return (
          <CheckboxField
            field={field}
            dimensions={pxDimensions}
          />
        );
      case InputType.MULTIPLE_CHOICE:
        return (
          <MultipleChoiceField
            field={field}
            dimensions={pxDimensions}
          />
        );
      default:
        return null;
    }
  };

  return (
    <Stack
      sx={{
        position: 'absolute',
        left: Number(pxDimensions.x.toFixed(2)),
        top: Number(pxDimensions.y.toFixed(2)),
        height: Number(pxDimensions.height.toFixed(2)),
        width: Number(pxDimensions.width.toFixed(2)),
      }}
    >
      {getInputFieldByType()}
    </Stack>
  );
};

export default FieldWrapper;
