import {
  ManagerSurvey,
  ManagerSurveyStatus,
  QuestionScaleResponse,
  QuestionSubtypeResponse,
  QuestionTemplateType,
  QuestionType,
  QuestionTypeResponse,
  SurveyResponse,
  TransformedManagerSurvey,
  TransformedSurvey,
} from './types';
import { LokaliseTFunction } from 'src/utils/i18n';

import { NUMBER_FORMAT_LOCALE } from './constants';

const transformQuestionType = (
  type: QuestionTypeResponse,
  subType: QuestionSubtypeResponse,
): QuestionType => {
  const questionTypeMapping: { [key in QuestionTypeResponse]: QuestionType } = {
    RATING: subType === 'LIKERT' ? QuestionType.LIKERT : QuestionType.NPS,
    CHECKBOX: QuestionType.MULTI_CHOICE,
    MULTIPLE_CHOICE: QuestionType.UNIQ_CHOICE,
    TEXT: QuestionType.TEXT,
  };

  return questionTypeMapping[type];
};

export const transformSurvey = (data: SurveyResponse): TransformedSurvey => {
  const { questions } = data.form;

  return {
    id: data.id,
    title: data.survey.name,
    description: data.survey.description,
    status: data.status,
    finishDate: data.survey.finishDate,
    anonymityThreshold: data.survey.anonymityThreshold,
    questions: questions.map(question => {
      return {
        id: question.id,
        title: question.title,
        allowComments: question.commentableStatus === 'OPTIONAL',
        isMandatory: question.required,
        type: transformQuestionType(question.type, question.subType),
        answer: question.answer,
        answered: question.answered,
        isEnps: question.subType === 'NPS',
        comment: question.comment,
        choices: question.choices,
        options: question.options,
      };
    }),
  };
};

export const getFormProgress = (value: number, total: number) =>
  (value * 100) / total;

export const getInitAnswerValue = (
  type: QuestionType,
  optionsLength?: number,
) => {
  switch (type) {
    case QuestionType.NPS:
    case QuestionType.LIKERT:
      return null;
    case QuestionType.UNIQ_CHOICE:
    case QuestionType.MULTI_CHOICE:
      return Array.from({ length: optionsLength ?? 0 }, () => false);
    case QuestionType.TEXT:
      return '';
  }
};

export const formatValue = Math.round;

export const getPercent = (value: number, total: number) =>
  formatValue((value * 100) / total);

export const formatValueSafe = (value: number, fallback = 0) =>
  formatValue(!Number.isFinite(value) ? fallback : value);

export const safeTextSelectHandler = (callback: () => void) => () => {
  const selection = window.getSelection()!;

  if (selection.toString().length === 0) {
    callback();
  }
};

export const formatNumber = Intl.NumberFormat(NUMBER_FORMAT_LOCALE).format;

type GetCountTextProps = {
  t: LokaliseTFunction;
  translationKey: string;
  hasPassedThreshold: boolean;
  count: number;
};

export const getFavorabilityCountText = ({
  t,
  translationKey,
  hasPassedThreshold,
  count,
}: GetCountTextProps) =>
  t(`${translationKey}_custom_count`, {
    value: hasPassedThreshold ? formatNumber(count) : '--',
    count: hasPassedThreshold ? count : 10,
  });

/**
 * Gets the translated label for the answer type.
 * For Likert scale questions, if a custom scale is provided, the label will include the scale name.
 *
 * @param t The translation function.
 * @param type The type of the answer.
 * @param scale The scale of the question, if applicable.
 * @returns The translated string representing the answer type.
 */
export const getAnswerTypeTrans = ({
  t,
  type,
  scale,
}: {
  t: LokaliseTFunction;
  type: QuestionTemplateType;
  scale?: QuestionScaleResponse | null;
}) => {
  switch (type) {
    case QuestionTemplateType.LIKERT:
      return scale
        ? t('custom_scale.label_with_name', { scaleName: scale.name })
        : t('likert_score_scale');
    case QuestionTemplateType.TEXT:
      return t('comment.comment');
    case QuestionTemplateType.CHECKBOX:
      return t('multiple_selection');
    case QuestionTemplateType.MULTIPLE_CHOICE:
      return t('unique_selection');
    case QuestionTemplateType.NPS:
      return t('e_nps.title');
    default:
      return '';
  }
};

const getSurveyStatusTranslationKey = (status: ManagerSurveyStatus) => {
  switch (status) {
    case ManagerSurveyStatus.ACTIVE:
      return 'survey.active_one';
    case ManagerSurveyStatus.FINISHED:
      return 'survey.finished_one';
    case ManagerSurveyStatus.IMPORTED:
      return 'survey.imported_one';
    default:
      return status;
  }
};

const parseStatus = ({
  status,
  t,
}: {
  status: ManagerSurveyStatus;
  t: LokaliseTFunction;
}) => {
  return {
    label: t(getSurveyStatusTranslationKey(status)),
    value: status,
  };
};

export const parseManagerSurvey = ({
  data,
  t,
}: {
  data: ManagerSurvey;
  t: LokaliseTFunction;
}): TransformedManagerSurvey => {
  return {
    ...data,
    status: parseStatus({ status: data.status, t }),
  };
};
