import { type TFunction } from 'i18next';
import { type CountryCode } from 'libphonenumber-js';
import { type FileAsset } from '@material-hu/types/attachments';

import { useAuth } from 'src/contexts/JWTContext';
import AutocompleteInput from 'src/pages/dashboard/serviceManagement/form/inputs/AutocompleteInput';
import DateInput from 'src/pages/dashboard/serviceManagement/form/inputs/DateInput';
import FloatInput from 'src/pages/dashboard/serviceManagement/form/inputs/FloatInput';
import IntegerInput from 'src/pages/dashboard/serviceManagement/form/inputs/IntegerInput';
import { ListChoiceInput } from 'src/pages/dashboard/serviceManagement/form/inputs/ListChoiceInput';
import TextInput from 'src/pages/dashboard/serviceManagement/form/inputs/TextInput';
import TimeInput from 'src/pages/dashboard/serviceManagement/form/inputs/TimeInput';
import {
  InputType,
  type InputValidations,
} from 'src/pages/dashboard/serviceManagement/types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import ComponentAttachments from '../servicePortal/serviceItem/components/ComponentAttachments';

import DigitalSignature from './inputs/DigitalSignature';
import DropdownInput from './inputs/DropdownInput';
import PhoneInput from './inputs/PhoneInput';
import StarRatingInput from './inputs/StarRatingInput';
import UploadFileInput from './inputs/UploadFileInput';

export type Input = {
  name: string;
  required?: boolean;
  answerInput?: any;
  properties?: {
    defaultCountryCode?: CountryCode;
  };
  formFilled?: boolean;
  choices?: string[];
  lang: string;
  validations?: InputValidations;
  defaultCountryCode?: CountryCode;
  t: TFunction;
  answer?: string | number | null;
};

const getInput = {
  [InputType.INFO]: () => null, // No input -> just title and description for this component type
  [InputType.STAR_RATING]: ({ name, required, formFilled }: Input) => (
    <StarRatingInput
      name={name}
      required={required}
      formFilled={formFilled}
    />
  ),
  [InputType.DATE]: ({ name, validations, required }: Input) => (
    <DateInput
      name={name}
      validations={validations}
      required={required}
    />
  ),
  [InputType.TIME]: ({ name, required }: Input) => (
    <TimeInput
      name={name}
      required={required}
    />
  ),
  [InputType.TEXT]: ({ name, required, formFilled, validations }: Input) => (
    <TextInput
      name={name}
      required={required}
      formFilled={formFilled}
      validations={validations}
    />
  ),
  [InputType.PHONE]: ({
    name,
    required,
    properties,
    defaultCountryCode,
    ...props
  }: Input) => (
    <PhoneInput
      name={name}
      countryCode={defaultCountryCode || properties?.defaultCountryCode || 'AR'}
      required={required}
      {...props}
    />
  ),
  [InputType.INTEGER]: ({ name, validations, required, formFilled }: Input) => (
    <IntegerInput
      name={name}
      validations={validations}
      required={required}
      formFilled={formFilled}
    />
  ),
  [InputType.FLOAT]: ({ name, required, lang }: Input) => (
    <FloatInput
      name={name}
      required={required}
      lang={lang}
    />
  ),
  [InputType.DROPDOWN]: ({ name, choices, required, formFilled }: Input) => {
    return (
      <DropdownInput
        name={name}
        required={required}
        choices={choices || []}
        formFilled={formFilled ?? false}
      />
    );
  },
  [InputType.CHECKBOX]: ({
    name,
    choices,
    validations,
    formFilled,
    required,
  }: Input) => (
    <ListChoiceInput
      name={name}
      choices={choices}
      formFilled={formFilled}
      required={required}
      multiple={true}
      validations={validations}
    />
  ),
  [InputType.MULTIPLE_CHOICE]: ({
    name,
    choices,
    formFilled,
    required,
  }: Input) => (
    <ListChoiceInput
      name={name}
      choices={choices}
      formFilled={formFilled}
      required={required}
      multiple={false}
    />
  ),
  [InputType.SIGNATURE]: ({ name, required, formFilled }: Input) => {
    return (
      <DigitalSignature
        name={name}
        formFilled={formFilled}
        required={required}
      />
    );
  },
  [InputType.FILE]: ({ name, required, formFilled }: Input) => {
    return (
      <UploadFileInput
        name={name}
        required={required}
        formFilled={formFilled}
      />
    );
  },
  [InputType.AUTOCOMPLETE]: ({ name, answer }: Input) => {
    return (
      <AutocompleteInput
        name={name}
        answer={answer}
      />
    );
  },
};

export type FormInputComponentProps = {
  name: string;
  inputType: string;
  required: boolean;
  answerInput?: any;
  formFilled?: boolean;
  choices?: string[];
  label?: string;
  multiline?: boolean;
  validations?: InputValidations;
  answer?: string | number | null;
  attachments?: FileAsset[];
  defaultCountryCode?: CountryCode;
};

export const FormInputComponent = ({
  inputType,
  name,
  attachments,
  ...props
}: FormInputComponentProps) => {
  const { t } = useLokaliseTranslation('service_management');
  const { user } = useAuth();
  const lang = user?.language;

  if (!(inputType && getInput[inputType as keyof typeof getInput])) {
    return null;
  }

  return (
    <>
      {attachments && <ComponentAttachments attachments={attachments} />}
      {getInput[inputType as keyof typeof getInput]({
        ...props,
        name,
        lang: lang || 'es',
        t: t as TFunction,
      })}
    </>
  );
};

export default FormInputComponent;
