import type { Evaluation, DimensionScore, TemplateDimension, Template } from "@prisma/client";

export interface EvaluationWithScores extends Evaluation {
  template?: Template | null;
  dimensionScores: (DimensionScore & { dimension: TemplateDimension })[];
}

/** Parse suggestedQuestions JSON array */
export function parseQuestions(s: string | null | undefined): string[] {
  if (!s) return [];
  try {
    const arr = JSON.parse(s) as unknown;
    return Array.isArray(arr) ? arr.filter((x): x is string => typeof x === "string") : [];
  } catch {
    return [];
  }
}

/** Parse rubric "1:X;2:Y;..." into labels */
export function parseRubric(rubric: string): string[] {
  if (rubric === "1-5" || !rubric) return ["1", "2", "3", "4", "5"];
  const labels: string[] = [];
  for (let i = 1; i <= 5; i++) {
    const m = rubric.match(new RegExp(`${i}:([^;]+)`));
    labels.push(m ? m[1].trim() : String(i));
  }
  return labels;
}

/** Compute average score across dimensions (1-5 scale) */
export function computeAverageScore(scores: { score: number | null }[]): number {
  const valid = scores.filter((s) => s.score != null && s.score >= 1 && s.score <= 5);
  if (valid.length === 0) return 0;
  return valid.reduce((a, s) => a + (s.score ?? 0), 0) / valid.length;
}

/** Generate findings paragraph from scores (deterministic template) */
export function generateFindings(
  scores: { score: number | null; dimension: { name?: string; title?: string } }[]
): string {
  const withScore = scores.filter((s) => s.score != null);
  if (withScore.length === 0) return "Aucun score enregistré pour l'instant.";

  const avg = computeAverageScore(withScore);
  const dimName = (d: { name?: string; title?: string }) => d.title ?? d.name ?? "";
  const weak = withScore.filter((s) => (s.score ?? 0) <= 2).map((s) => dimName(s.dimension));
  const strong = withScore.filter((s) => (s.score ?? 0) >= 4).map((s) => dimName(s.dimension));

  let text = `Score de maturité global : ${avg.toFixed(1)}/5. `;
  if (strong.length > 0) {
    text += `Points forts : ${strong.join(", ")}. `;
  }
  if (weak.length > 0) {
    text += `Axes d'amélioration : ${weak.join(", ")}.`;
  } else if (strong.length === 0) {
    text += "Les scores indiquent une maturité modérée sur les dimensions.";
  }
  return text;
}

/** Generate recommendations (deterministic template) */
export function generateRecommendations(
  scores: { score: number | null; dimension: { name?: string; title?: string } }[]
): string {
  const dimName = (d: { name?: string; title?: string }) => d.title ?? d.name ?? "";
  const weak = scores.filter((s) => (s.score ?? 5) <= 2).map((s) => dimName(s.dimension));
  if (weak.length === 0) return "Continuer à s'appuyer sur les pratiques actuelles. Envisager le mentorat pour les juniors.";
  return `Prioriser la formation et le développement pour : ${weak.join(", ")}. Envisager des programmes de montée en compétence structurés et une expertise externe si les écarts sont importants.`;
}

/** Convert evaluation to CSV rows (one per dimension + metadata row) */
export function evaluationToCsvRows(evalData: EvaluationWithScores): string[][] {
  const rows: string[][] = [];
  rows.push([
    "candidateName",
    "candidateRole",
    "candidateTeam",
    "evaluatorName",
    "evaluationDate",
    "template",
    "status",
    "dimension",
    "score",
    "justification",
    "examplesObserved",
    "confidence",
  ]);
  for (const ds of evalData.dimensionScores) {
    rows.push([
      evalData.candidateName,
      evalData.candidateRole,
      (evalData as { candidateTeam?: string | null }).candidateTeam ?? "",
      evalData.evaluatorName,
      evalData.evaluationDate.toISOString().split("T")[0],
      evalData.template?.name ?? "",
      evalData.status,
      (ds.dimension as { name?: string; title?: string }).title ?? (ds.dimension as { name?: string }).name ?? "",
      String(ds.score ?? ""),
      ds.justification ?? "",
      ds.examplesObserved ?? "",
      ds.confidence ?? "",
    ]);
  }
  return rows;
}

const CONFIDENCE_LABELS: Record<string, string> = {
  low: "Faible",
  med: "Moyenne",
  high: "Haute",
};

/** Convert evaluation template (dimensions + questions + rubric) to Markdown for Confluence paste */
export function evaluationToConfluenceMarkup(evalData: EvaluationWithScores): string {
  const lines: string[] = [];
  lines.push(`# Guide d'entretien — ${evalData.template?.name ?? "Évaluation"}`);
  lines.push("");
  lines.push(`**Candidat:** ${evalData.candidateName} | **Rôle:** ${evalData.candidateRole}`);
  if (evalData.candidateTeam) lines.push(`**Équipe:** ${evalData.candidateTeam}`);
  lines.push(`**Évaluateur:** ${evalData.evaluatorName} | **Date:** ${evalData.evaluationDate.toISOString().split("T")[0]}`);
  lines.push("");

  lines.push("## Système de notation");
  lines.push("");
  lines.push("Chaque dimension est notée de **1** (faible) à **5** (expert). La grille ci-dessous détaille les critères par niveau.");
  lines.push("");

  for (const ds of evalData.dimensionScores) {
    const dim = ds.dimension;
    const title = (dim as { title?: string; name?: string }).title ?? (dim as { name?: string }).name ?? "";
    lines.push(`## ${title}`);
    lines.push("");

    const questions = parseQuestions((dim as { suggestedQuestions?: string | null }).suggestedQuestions);
    if (questions.length > 0) {
      lines.push("### Questions suggérées");
      questions.forEach((q, i) => {
        lines.push(`${i + 1}. ${q}`);
      });
      lines.push("");
    }

    const rubricLabels = parseRubric((dim as { rubric?: string }).rubric ?? "");
    if (rubricLabels.length > 0) {
      lines.push("### Grille");
      rubricLabels.forEach((label, i) => {
        lines.push(`- ${i + 1}: ${label}`);
      });
      lines.push("");
    }

    lines.push("### Notes évaluateur");
    if (ds.score != null) {
      lines.push(`- **Score:** ${ds.score}/5`);
      if (ds.confidence)
        lines.push(`- **Confiance:** ${CONFIDENCE_LABELS[ds.confidence] ?? ds.confidence}`);
    } else {
      lines.push(`- **Score:** _à compléter_`);
      lines.push(`- **Confiance:** _à compléter_`);
    }
    lines.push(`- **Notes candidat:** ${ds.candidateNotes ?? "_à compléter_"}`);
    lines.push(`- **Justification:** ${ds.justification ?? "_à compléter_"}`);
    lines.push(`- **Exemples:** ${ds.examplesObserved ?? "_à compléter_"}`);
    lines.push("");
  }

  return lines.join("\n");
}
