import {
  type FillCalibrationQuestionAnswer,
  type PerformanceReviewCoreFormQuestion,
  type PerformanceReviewFormStatus,
  type ReviewCommentableStatus,
  type ReviewDetailFormQuestions,
  type ReviewQuestionType,
} from 'src/pages/dashboard/performance/types';
import { type LokaliseTFunction } from 'src/utils/i18n';

import {
  ReviewInputSectionType,
  reviewSectionTitleTranslationKey,
} from '../../components/ReviewInputSection';
import { createReviewAnswers } from '../../utils';

import { buildCommentFieldName, EDITABLE_STATUSES } from './constants';
import { type CalibrationBuckets, type CalibrationFormValues } from './types';

/**
 * Builds the initial form values for react-hook-form.
 *
 * Each question contributes two entries: one for the answer (keyed by question id)
 * and one for the optional comment (keyed by id + COMMENT suffix). Goal-only
 * entries (no id) are skipped.
 *
 * IMPORTANT: a `null` answer is stored as `undefined`, NOT as `''`. ScoreInput
 * runs `parseScoreAnswer` which coerces `''` to `0`, which would otherwise
 * auto-select the first option of a rating question on initial render.
 */
export const getDefaultValues = (
  questions: PerformanceReviewCoreFormQuestion[],
): CalibrationFormValues => {
  const values: CalibrationFormValues = {};

  questions.forEach(question => {
    if (!question.id) return;
    values[question.id] = question.answer ?? undefined;
    values[buildCommentFieldName(question.id)] = question.comment ?? '';
  });

  return values;
};

/**
 * Adapts the calibration-flavoured question shape to the legacy
 * `ReviewDetailFormQuestions` consumed by ReviewInputSection / GetReviewInputComponent.
 * Preserves `goal` and `competency` so `splitReviewInputs` buckets them correctly.
 */
export const toReviewQuestion = (
  question: PerformanceReviewCoreFormQuestion,
): ReviewDetailFormQuestions =>
  ({
    id: question.id,
    title: question.title,
    description: question.description,
    type: question.type as ReviewQuestionType,
    commentableStatus: question.commentableStatus as ReviewCommentableStatus,
    required: question.required,
    choices: question.choices,
    rows: null,
    pattern: question.pattern ?? null,
    defaultCountryCode: question.defaultCountryCode ?? null,
    userField: null,
    answer: question.answer as ReviewDetailFormQuestions['answer'],
    comment: question.comment ?? undefined,
    goal: question.goal,
    competency: question.competency,
  }) as ReviewDetailFormQuestions;

/**
 * Builds a lookup `Map` of questions keyed by `id`. Questions without an id
 * are skipped. Useful for O(1) cross-form matching (e.g. calibrated vs
 * subordinate answer for the same question).
 */
export const buildQuestionMap = (
  questions: PerformanceReviewCoreFormQuestion[] | undefined,
): Map<string, PerformanceReviewCoreFormQuestion> => {
  const map = new Map<string, PerformanceReviewCoreFormQuestion>();
  questions?.forEach(q => {
    if (q.id) map.set(q.id, q);
  });
  return map;
};

/** Whether the calibrator can still edit the form (vs. read-only). */
export const isStatusEditable = (
  status: PerformanceReviewFormStatus,
): boolean => EDITABLE_STATUSES.includes(status);

/** Whether the question already has a non-empty answer from the calibrator. */
export const isQuestionAnswered = (
  question: ReviewDetailFormQuestions,
): boolean => question.answer != null && question.answer !== '';

/**
 * Turns react-hook-form values into the `questionAnswers` payload accepted by
 * the fill endpoint. Delegates to the shared `createReviewAnswers` helper and
 * narrows comments to `string | undefined`.
 */
export const buildFillCalibrationAnswers = (
  values: CalibrationFormValues,
  reviewQuestions: ReviewDetailFormQuestions[],
): FillCalibrationQuestionAnswer[] =>
  createReviewAnswers(values, reviewQuestions).map(answer => ({
    questionId: answer.questionId,
    answer: answer.answer,
    comment: typeof answer.comment === 'string' ? answer.comment : undefined,
  }));

/** Section types that have at least one question, in display order. */
export const getAvailableSectionTypes = (
  buckets: CalibrationBuckets,
): ReviewInputSectionType[] => {
  const sections: ReviewInputSectionType[] = [];
  if (buckets.formQuestions.length > 0)
    sections.push(ReviewInputSectionType.FORM);
  if (buckets.goalQuestions.length > 0)
    sections.push(ReviewInputSectionType.GOAL);
  if (buckets.competencyQuestions.length > 0)
    sections.push(ReviewInputSectionType.COMPETENCY);
  return sections;
};

/** Tabs payload for `HuTabs` (read-only mode). */
export const buildSectionTabs = (
  sectionTypes: ReviewInputSectionType[],
  t: LokaliseTFunction,
) =>
  sectionTypes.map(value => ({
    value,
    label: t(reviewSectionTitleTranslationKey[value]),
  }));

/** Steps payload for `HuStepper` (editable mode). */
export const buildStepperSteps = (
  sectionTypes: ReviewInputSectionType[],
  t: LokaliseTFunction,
) =>
  sectionTypes.map((sectionType, index) => ({
    id: sectionType,
    title: t(reviewSectionTitleTranslationKey[sectionType]),
    number: index + 1,
  }));

/** Questions shown on the currently active step. */
export const getQuestionsForSection = (
  sectionType: ReviewInputSectionType | undefined,
  buckets: CalibrationBuckets,
): ReviewDetailFormQuestions[] => {
  if (sectionType === ReviewInputSectionType.FORM) return buckets.formQuestions;
  if (sectionType === ReviewInputSectionType.GOAL) return buckets.goalQuestions;
  if (sectionType === ReviewInputSectionType.COMPETENCY)
    return buckets.competencyQuestions;
  return [];
};
