import { elevenLabsService } from '../services/elevenLabsService';

interface RawEvaluation {
  identifier: string;
  result: string;
  rationale: string;
}

// ElevenLabs auto-generates each criterion's `id` from the `name` typed in their panel
// and strips accented characters in the process (e.g. "Comprensión" -> "comprensin").
// Used only when the real name can't be resolved from the agent's config (e.g. the
// criterion was deleted/renamed since the conversation happened, or the API call fails).
const fallbackLabel = (id: string): string => {
  return id
    .replace(/_/g, ' ')
    .split(' ')
    .filter(Boolean)
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
};

/**
 * Replaces each evaluation's raw criterion `identifier` (ElevenLabs' auto-generated id)
 * with the human-readable name configured for that criterion in the agent's ElevenLabs
 * config, falling back to a capitalized version of the id when the name can't be resolved.
 */
export const resolveEvaluationIdentifiers = async (
  agentId: string | null | undefined,
  evaluations: RawEvaluation[]
): Promise<RawEvaluation[]> => {
  if (!evaluations.length) return evaluations;

  const names = agentId ? await elevenLabsService.getEvaluationCriteriaNames(agentId) : {};

  return evaluations.map((evaluation) => ({
    ...evaluation,
    identifier: names[evaluation.identifier] || fallbackLabel(evaluation.identifier)
  }));
};

/**
 * Normalizes the raw evaluation_criteria_results out of an ElevenLabs conversation details
 * payload and attaches a resolved `evaluations` array to it in place, so callers that pass
 * that payload straight through to the frontend (live preview endpoints, which don't persist
 * anything) still show the real criterion names instead of ElevenLabs' accent-stripped ids.
 */
export const attachResolvedEvaluations = async (
  data: any,
  agentId: string | null | undefined
): Promise<void> => {
  if (!data) return;

  const evaluationMap = data?.analysis?.evaluation_criteria_results
    || data?.analysis?.evaluation_results
    || data?.evaluations
    || {};

  const rawEvaluations: RawEvaluation[] = Array.isArray(evaluationMap)
    ? evaluationMap
    : Object.keys(evaluationMap || {}).map((key) => ({
        identifier: key,
        result: evaluationMap[key]?.result || evaluationMap[key]?.status || 'unknown',
        rationale: evaluationMap[key]?.rationale || evaluationMap[key]?.reason || ''
      }));

  if (!rawEvaluations.length) return;

  data.evaluations = await resolveEvaluationIdentifiers(agentId, rawEvaluations);
};
