import { Fragment } from 'react';

import { format } from 'date-fns';
import { parsePhoneNumberFromString } from 'libphonenumber-js';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';
import { type FileAsset } from '@material-hu/types/attachments';

import HuRating from '@material-hu/components/design-system/Rating';

import FileAnswer from 'src/pages/dashboard/serviceManagement/form/files/FileAnswer';
import SignatureModal from 'src/pages/dashboard/serviceManagement/form/signature/SignatureModal';
import {
  type FormSectionBody,
  InputType,
  type SectionContent,
  SectionEvent,
} from 'src/pages/dashboard/serviceManagement/types';
import { countryCodeToFlagEmoji } from 'src/pages/dashboard/sportsPool/utils';
import { type MeUser } from 'src/types/user';
import {
  formatDateToMonthYear,
  formatFullDate,
  formatToTime,
} from 'src/utils/date';
import { getFullName } from 'src/utils/userUtils';

const UPLOADING_FIELD_SUFFIX = '__uploading';

export const getUploadingFieldName = (name: string) =>
  `${name}${UPLOADING_FIELD_SUFFIX}`;

export const getUploadingFieldNames = (form: SectionContent | null) =>
  form?.components
    .filter(c => c.type === InputType.FILE)
    .map(c => getUploadingFieldName(c.nameId)) ?? [];

export const isSelection = (type: InputType) =>
  type === InputType.CHECKBOX ||
  type === InputType.DROPDOWN ||
  type === InputType.MULTIPLE_CHOICE;

export const parseAutocompleteAnswer = (component: any) => {
  switch (component?.fieldName) {
    case 'STRING_LIST':
    case 'NUMBER_LIST':
    case 'MULTIPLE_OPTION':
      return component?.fieldValue.join(', ');
    case 'NUMBER':
      return component?.fieldValue.toString();
    case 'DIRECT_BOSS':
      return getFullName(component?.fieldValue);
    case 'DEPARTMENT':
    case 'JOB_POSITION':
      return component?.fieldValue.name;
    default:
      return component?.fieldValue;
  }
};

export const getFormAnswer = (
  component: any,
  user: MeUser,
  providedAnswer = undefined,
  isPreview = false,
) => {
  const { type, answer: componentAnswer, validations } = component;
  const answer =
    providedAnswer !== undefined ? providedAnswer : componentAnswer;
  if (answer !== null && answer !== undefined) {
    if (isSelection(type)) {
      if (Array.isArray(answer)) {
        return answer.map((index, i) => (
          <Fragment key={i}>
            {component.content.choices[index]}
            {i < answer.length - 1 && ', '}
          </Fragment>
        ));
      } else {
        return component.content.choices[answer];
      }
    } else if (type === InputType.STAR_RATING) {
      return (
        <HuRating
          value={answer}
          size="medium"
          sx={{
            '& .MuiRating-icon': {
              marginRight: 0.5,
            },
            color: theme => theme.palette.new.action.button.background.primary,
            mt: 1,
          }}
          readOnly
        />
      );
    } else if (type === InputType.PHONE) {
      const phoneNumber = parsePhoneNumberFromString(answer);
      const flagEmoji = phoneNumber?.country
        ? countryCodeToFlagEmoji(phoneNumber.country)
        : null;
      return (
        <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 0.6 }}>
          {flagEmoji && (
            <Typography sx={{ fontSize: 18, lineHeight: 1 }}>
              {flagEmoji}
            </Typography>
          )}
          {answer}
        </Stack>
      );
    } else if (type === InputType.DATE) {
      const formattedDate =
        validations.pattern.toUpperCase() === 'YYYY-MM-DD'
          ? formatFullDate(answer, user)
          : formatDateToMonthYear(answer, user);
      return formattedDate;
    } else if (type === InputType.TIME && isPreview) {
      const formattedTime = formatToTime(answer);
      return formattedTime;
    } else if (type === InputType.SIGNATURE) {
      return <SignatureModal url={answer.url} />;
    } else if (type === InputType.AUTOCOMPLETE) {
      return isPreview ? answer : parseAutocompleteAnswer(answer);
    } else if (type === InputType.FILE) {
      return (
        <Stack sx={{ gap: 1 }}>
          {answer.map((file: FileAsset) => (
            <FileAnswer
              key={file.id}
              file={file}
            />
          ))}
        </Stack>
      );
    }
  } else return '-';

  return answer;
};

const formatFormAnswer = (type: InputType, value: any, validation: any) => {
  const hasValue =
    value !== null &&
    value !== undefined &&
    value !== '' &&
    !(Array.isArray(value) && value.length === 0);
  switch (type) {
    case InputType.FLOAT:
      if (hasValue) {
        const normalized = String(value).replace(',', '.');
        const n = Number(normalized);
        return Number.isFinite(n) ? Number(n.toFixed(2)) : null;
      }
      return null;
    case InputType.INTEGER:
      if (hasValue) {
        return Number(value);
      }
      return null;
    case InputType.DATE:
      if (hasValue) {
        return format(new Date(value), validation.pattern);
      }
      return null;
    case InputType.TIME:
      if (hasValue) {
        return format(new Date(value), 'HH:mm');
      }
      return null;
    case InputType.SIGNATURE:
      if (hasValue) {
        return { id: value.id };
      }
      return null;
    case InputType.FILE:
      if (hasValue && Array.isArray(value)) {
        return value.map(file => ({ id: file.id }));
      }
      return null;
    case InputType.DROPDOWN:
      if (hasValue) {
        return value.value;
      }
      return null;
    case InputType.STAR_RATING:
      if (hasValue) {
        return parseInt(value, 10);
      }
      return null;
    default:
      return value;
  }
};

export const generateFormProgressData = (
  section: SectionContent,
  formValues: Record<string, any>,
  goBack = false,
) => {
  const answers = section.components
    .filter(component => component.type !== InputType.AUTOCOMPLETE)
    .map(component => {
      const formAnswer = formatFormAnswer(
        component.type,
        formValues[component.nameId],
        component.validations,
      );
      return {
        componentNameId: component.nameId,
        answer: formAnswer,
      };
    });

  const fileAssetIds = section?.components
    ?.filter(
      component =>
        component.type === InputType.SIGNATURE ||
        component.type === InputType.FILE,
    )
    .flatMap(component => {
      if (component.type === InputType.SIGNATURE) {
        return formValues[component.nameId]?.id;
      } else if (component.type === InputType.FILE) {
        return formValues[component.nameId]?.map(
          (attachment: FileAsset) => attachment?.id,
        );
      }
    })
    .filter(id => id !== null && id !== undefined);

  const response: FormSectionBody = {
    sectionNameId: section.nameId,
    sectionEvent: goBack ? SectionEvent.BACK : SectionEvent.COMPLETE,
    fillingTime: 3428,
    answers,
  };

  if (fileAssetIds.length > 0) {
    response.fileAssetIds = fileAssetIds;
  }

  return response;
};
