"use client";

import { useState, useEffect, useCallback } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { updateEvaluation, deleteEvaluation, fetchEvaluation } from "@/actions/evaluations";
import { CandidateForm } from "@/components/CandidateForm";
import { DimensionCard } from "@/components/DimensionCard";
import { RadarChart } from "@/components/RadarChart";
import { ExportModal } from "@/components/ExportModal";
import { ShareModal } from "@/components/ShareModal";
import { ConfirmModal } from "@/components/ConfirmModal";
import { generateFindings, generateRecommendations, computeAverageScore } from "@/lib/export-utils";

interface Dimension {
  id: string;
  slug: string;
  title: string;
  rubric: string;
  suggestedQuestions?: string | null;
}

interface DimensionScore {
  id: string;
  dimensionId: string;
  score: number | null;
  justification: string | null;
  examplesObserved: string | null;
  confidence: string | null;
  candidateNotes: string | null;
  dimension: Dimension;
}

interface Evaluation {
  id: string;
  candidateName: string;
  candidateRole: string;
  candidateTeam?: string | null;
  evaluatorName: string;
  evaluatorId?: string | null;
  evaluationDate: string;
  templateId: string;
  template: { id: string; name: string; dimensions: Dimension[] };
  status: string;
  findings: string | null;
  recommendations: string | null;
  dimensionScores: DimensionScore[];
  sharedWith?: { id: string; user: { id: string; email: string; name: string | null } }[];
  isPublic?: boolean;
}

interface EvaluationEditorProps {
  id: string;
  initialEvaluation: Evaluation;
  templates: { id: string; name: string; dimensions?: { id: string; suggestedQuestions?: string | null }[] }[];
  users: { id: string; email: string; name: string | null }[];
}

export function EvaluationEditor({ id, initialEvaluation, templates, users }: EvaluationEditorProps) {
  const router = useRouter();
  const [evaluation, setEvaluation] = useState<Evaluation>(initialEvaluation);
  const [saving, setSaving] = useState(false);
  const [exportOpen, setExportOpen] = useState(false);
  const [shareOpen, setShareOpen] = useState(false);
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
  const [collapseAllTrigger, setCollapseAllTrigger] = useState(0);

  const fetchEval = useCallback(async () => {
    const result = await fetchEvaluation(id);
    if (result.success && result.data) {
      const d = result.data;
      setEvaluation({ ...d, dimensionScores: d.dimensionScores ?? [] } as Evaluation);
    }
  }, [id]);

  // Draft backup to localStorage (debounced)
  useEffect(() => {
    if (!evaluation || !id) return;
    const t = setTimeout(() => {
      try {
        localStorage.setItem(
          `eval-draft-${id}`,
          JSON.stringify({ ...evaluation, evaluationDate: evaluation.evaluationDate })
        );
      } catch {
        /* ignore */
      }
    }, 2000);
    return () => clearTimeout(t);
  }, [evaluation, id]);

  const handleFormChange = (field: string, value: string) => {
    setEvaluation((e) => (e ? { ...e, [field]: value } : null!));
  };

  const handleScoreChange = (dimensionId: string, data: Partial<DimensionScore>) => {
    setEvaluation((e) => {
      if (!e) return null!;
      const existing = e.dimensionScores.find((ds) => ds.dimensionId === dimensionId);
      const dim = e.template?.dimensions?.find((d) => d.id === dimensionId);
      const scores = existing
        ? e.dimensionScores.map((ds) =>
            ds.dimensionId === dimensionId ? { ...ds, ...data } : ds
          )
        : [
            ...e.dimensionScores,
            {
              id: `temp-${dimensionId}`,
              dimensionId,
              score: (data as { score?: number }).score ?? null,
              justification: (data as { justification?: string }).justification ?? null,
              examplesObserved: (data as { examplesObserved?: string }).examplesObserved ?? null,
              confidence: (data as { confidence?: string }).confidence ?? null,
              candidateNotes: (data as { candidateNotes?: string }).candidateNotes ?? null,
              dimension: dim ?? { id: dimensionId, slug: "", title: "", rubric: "" },
            },
          ];
      const next = { ...e, dimensionScores: scores };
      if (data.score !== undefined) {
        setTimeout(() => handleSave(next, { skipRefresh: true }), 0);
      }
      return next;
    });
  };

  const handleSave = async (evalOverride?: Evaluation | null, options?: { skipRefresh?: boolean }) => {
    const toSave = evalOverride ?? evaluation;
    if (!toSave) return;
    setSaving(true);
    try {
      const result = await updateEvaluation(id, {
        candidateName: toSave.candidateName,
        candidateRole: toSave.candidateRole,
        candidateTeam: toSave.candidateTeam ?? null,
        evaluatorName: toSave.evaluatorName,
        evaluationDate: typeof toSave.evaluationDate === "string" ? toSave.evaluationDate : new Date(toSave.evaluationDate).toISOString(),
        status: toSave.status,
        findings: toSave.findings,
        recommendations: toSave.recommendations,
        isPublic: toSave.isPublic ?? false,
        dimensionScores: (toSave.dimensionScores ?? []).map((ds) => ({
          dimensionId: ds.dimensionId,
          evaluationId: id,
          score: ds.score,
          justification: ds.justification,
          examplesObserved: ds.examplesObserved,
          confidence: ds.confidence,
          candidateNotes: ds.candidateNotes,
        })),
      });
      if (result.success) {
        if (!options?.skipRefresh) fetchEval();
      } else {
        alert(result.error);
      }
    } catch (err) {
      console.error("Save error:", err);
      alert("Erreur lors de la sauvegarde");
    } finally {
      setSaving(false);
    }
  };

  const handleGenerateFindings = () => {
    const findings = generateFindings(evaluation.dimensionScores ?? []);
    const recommendations = generateRecommendations(evaluation.dimensionScores ?? []);
    setEvaluation((e) => (e ? { ...e, findings, recommendations } : null!));
  };

  const allFives = evaluation?.dimensionScores?.every(
    (ds) => ds.score === 5 && (!ds.justification || ds.justification.trim() === "")
  );
  const showAllFivesWarning = allFives && evaluation?.status === "submitted";

  const dimensions = evaluation.template?.dimensions ?? [];
  const dimensionScores = evaluation.dimensionScores ?? [];
  const scoreMap = new Map(dimensionScores.map((ds) => [ds.dimensionId, ds]));
  const radarData = dimensions
    .filter((dim) => !(dim.title ?? "").startsWith("[Optionnel]"))
    .map((dim) => {
      const ds = scoreMap.get(dim.id);
      const score = ds?.score;
      if (score == null) return null;
      const title = dim.title ?? "";
      const s = Number(score);
      if (Number.isNaN(s) || s < 0 || s > 5) return null;
      return {
        dimension: title.length > 12 ? title.slice(0, 12) + "…" : title,
        score: s,
        fullMark: 5,
      };
    })
    .filter((d): d is { dimension: string; score: number; fullMark: number } => d != null);
  const avgScore = computeAverageScore(dimensionScores);

  const templatesForForm = templates.map((t) => ({ id: t.id, name: t.name }));

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center justify-between gap-4">
        <h1 className="font-mono text-base font-medium text-zinc-800 dark:text-zinc-100">
          {evaluation.candidateName}
          {evaluation.candidateTeam && (
            <span className="text-zinc-500"> ({evaluation.candidateTeam})</span>
          )}
          <span className="text-zinc-500"> / </span> {evaluation.candidateRole}
        </h1>
        <div className="flex gap-2">
          <button
            onClick={() => handleSave()}
            disabled={saving}
            className="rounded border border-zinc-300 dark:border-zinc-600 bg-zinc-100 dark:bg-zinc-700 px-3 py-1.5 font-mono text-xs text-zinc-700 dark:text-zinc-300 hover:bg-zinc-200 dark:hover:bg-zinc-700 disabled:opacity-50"
          >
            {saving ? "..." : "save"}
          </button>
          <button
            onClick={() => {
              const next = !(evaluation.isPublic ?? false);
              setEvaluation((e) => (e ? { ...e, isPublic: next } : null!));
              handleSave(evaluation ? { ...evaluation, isPublic: next } : null);
            }}
            className={`rounded border px-3 py-1.5 font-mono text-xs ${
              evaluation.isPublic
                ? "border-emerald-500/50 bg-emerald-500/20 text-emerald-600 dark:text-emerald-400"
                : "border-zinc-300 dark:border-zinc-600 bg-zinc-100 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-600"
            }`}
          >
            {evaluation.isPublic ? "publique" : "rendre publique"}
          </button>
          <button
            onClick={() => setShareOpen(true)}
            className="rounded border border-cyan-500/50 bg-cyan-500/10 px-3 py-1.5 font-mono text-xs text-cyan-600 dark:text-cyan-400 hover:bg-cyan-500/20"
          >
            partager
          </button>
          <button
            onClick={() => setExportOpen(true)}
            className="rounded border border-cyan-500/50 bg-cyan-500/10 px-3 py-1.5 font-mono text-xs text-cyan-600 dark:text-cyan-400 hover:bg-cyan-500/20"
          >
            export
          </button>
        </div>
      </div>

      {showAllFivesWarning && (
        <div className="rounded border border-amber-500/30 bg-amber-500/10 p-3 font-mono text-xs text-amber-600 dark:text-amber-400">
          ⚠ Tous les scores = 5 sans justification
        </div>
      )}

      <section className="relative overflow-hidden rounded-xl border border-zinc-200 dark:border-zinc-600 bg-gradient-to-br from-zinc-50 to-white dark:from-zinc-800/80 dark:to-zinc-800 p-5 shadow-sm dark:shadow-none">
        <div className="absolute left-0 top-0 h-full w-1 bg-gradient-to-b from-cyan-500/60 to-cyan-400/40" aria-hidden />
        <h2 className="mb-4 font-mono text-xs font-medium uppercase tracking-wider text-zinc-500 dark:text-zinc-400">
          Session
        </h2>
        <CandidateForm
          candidateName={evaluation.candidateName}
          candidateRole={evaluation.candidateRole}
          candidateTeam={evaluation.candidateTeam ?? ""}
          evaluatorName={evaluation.evaluatorName}
          evaluationDate={evaluation.evaluationDate.split("T")[0]}
          templateId={evaluation.templateId}
          templates={templatesForForm}
          onChange={handleFormChange}
          templateDisabled
        />
      </section>

      <section>
        <div className="mb-3 flex items-center justify-between gap-2">
          <h2 className="font-mono text-xs text-zinc-600 dark:text-zinc-500">Dimensions</h2>
          <button
            type="button"
            onClick={() => setCollapseAllTrigger((c) => c + 1)}
            className="font-mono text-xs text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300"
          >
            tout fermer
          </button>
        </div>
        <nav className="mb-4 flex flex-wrap gap-1.5">
          {dimensions.map((dim, i) => {
            const ds = scoreMap.get(dim.id);
            const hasScore = ds?.score != null;
            return (
              <a
                key={dim.id}
                href={`#dim-${dim.id}`}
                className={`rounded px-2 py-0.5 font-mono text-xs transition-colors ${
                  hasScore
                    ? "bg-cyan-500/20 text-cyan-600 dark:text-cyan-400 hover:bg-cyan-500/30"
                    : "text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800 hover:text-zinc-700 dark:hover:text-zinc-300"
                }`}
              >
                {i + 1}. {dim.title}
              </a>
            );
          })}
        </nav>
        <div className="space-y-2">
          {dimensions.map((dim, i) => (
            <div key={dim.id} id={`dim-${dim.id}`} className="scroll-mt-24">
              <DimensionCard
                dimension={dim}
                index={i}
                evaluationId={id}
                score={scoreMap.get(dim.id) ?? null}
                onScoreChange={handleScoreChange}
                collapseAllTrigger={collapseAllTrigger}
              />
            </div>
          ))}
        </div>
      </section>

      <section className="rounded-lg border border-zinc-200 dark:border-zinc-600 bg-white dark:bg-zinc-800 p-4 shadow-sm dark:shadow-none">
        <h2 className="mb-3 font-mono text-xs text-zinc-600 dark:text-zinc-500">Synthèse</h2>
        <p className="mb-4 font-mono text-sm text-zinc-700 dark:text-zinc-300">
          Moyenne <span className="text-cyan-600 dark:text-cyan-400">{avgScore.toFixed(1)}/5</span>
        </p>
        <RadarChart data={radarData} />
        <div className="mt-4 grid gap-4 sm:grid-cols-2">
          <div>
            <label className="mb-1 block text-xs text-zinc-600 dark:text-zinc-500">Synthèse</label>
            <textarea
              value={evaluation.findings ?? ""}
              onChange={(e) => setEvaluation((ev) => (ev ? { ...ev, findings: e.target.value } : null!))}
              rows={3}
              className="w-full rounded border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-700/80 px-2.5 py-1.5 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 focus:border-cyan-500"
            />
          </div>
          <div>
            <label className="mb-1 block text-xs text-zinc-600 dark:text-zinc-500">Recommandations</label>
            <textarea
              value={evaluation.recommendations ?? ""}
              onChange={(e) =>
                setEvaluation((ev) => (ev ? { ...ev, recommendations: e.target.value } : null!))
              }
              rows={3}
              className="w-full rounded border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-700/80 px-2.5 py-1.5 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 focus:border-cyan-500"
            />
          </div>
        </div>
        <button
          type="button"
          onClick={handleGenerateFindings}
          className="mt-2 font-mono text-xs text-cyan-600 dark:text-cyan-400 hover:text-cyan-500 dark:hover:text-cyan-300"
        >
          → auto-générer
        </button>
      </section>

      <div className="flex flex-wrap gap-3">
        <button
          onClick={() => {
            const updated = { ...evaluation, status: "submitted" };
            setEvaluation(updated);
            handleSave(updated);
          }}
          className="rounded border border-emerald-500/50 bg-emerald-500/20 px-3 py-1.5 font-mono text-xs text-emerald-600 dark:text-emerald-400 hover:bg-emerald-500/30"
        >
          soumettre
        </button>
        <button onClick={() => router.push("/dashboard")} className="rounded border border-zinc-300 dark:border-zinc-600 px-3 py-1.5 font-mono text-xs text-zinc-600 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700">
          ← dashboard
        </button>
        <button
          type="button"
          onClick={() => setDeleteConfirmOpen(true)}
          className="rounded border border-red-500/30 px-3 py-1.5 font-mono text-xs text-red-600 dark:text-red-400 hover:bg-red-500/10"
        >
          supprimer
        </button>
      </div>

      <ExportModal
        isOpen={exportOpen}
        onClose={() => setExportOpen(false)}
        evaluationId={id}
      />

      <ShareModal
        isOpen={shareOpen}
        onClose={() => setShareOpen(false)}
        evaluationId={id}
        evaluatorId={evaluation.evaluatorId}
        users={users}
        sharedWith={evaluation.sharedWith ?? []}
        onUpdate={fetchEval}
      />

      <ConfirmModal
        isOpen={deleteConfirmOpen}
        title="Supprimer l'évaluation"
        message={`Supprimer l'évaluation de ${evaluation.candidateName} ? Cette action est irréversible.`}
        confirmLabel="Supprimer"
        cancelLabel="Annuler"
        variant="danger"
        onConfirm={async () => {
          const result = await deleteEvaluation(id);
          if (result.success) router.push("/dashboard");
          else alert(result.error);
        }}
        onCancel={() => setDeleteConfirmOpen(false)}
      />
    </div>
  );
}
