"use client";

import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import { clearSession, getApiUrl, loadSession } from "@/lib/auth";
import { getMyProjects } from "@/lib/projects-client";
import {
  deleteParentPhoto,
  deleteTrimesterPhoto,
  getProjectIndices,
  uploadParentPhoto,
  uploadTrimesterPhoto,
  upsertBabyIndices,
  upsertBabyTrimester,
  upsertParentIndices,
} from "@/lib/indices-client";
import type {
  BabyIndices,
  ParentIndices,
  ParentType,
  ProjectIndicesResponse,
  Trimester,
} from "@/types/indices";
import type { ProjectSummary } from "@/types/projects";
import { PhotoField } from "@/features/indices/components/PhotoField";
import styles from "./page.module.css";
import wizardStyles from "../../new/page.module.css";

const TRIMESTERS: Trimester[] = ["DATATION", "T1", "T2", "T3"];
const TRIMESTER_LABELS: Record<Trimester, string> = {
  DATATION: "Datation (1ère échographie)",
  T1: "1er trimestre",
  T2: "2ème trimestre",
  T3: "3ème trimestre",
};

type ParentDraft = {
  poids: string;
  taille: string;
  perimCranien: string;
  dateNaissance: string;
};

type TrimesterDraft = {
  date: string;
  note: string;
  poids: string;
  taille: string;
  perimCranien: string;
};

function emptyParentDraft(): ParentDraft {
  return { poids: "", taille: "", perimCranien: "", dateNaissance: "" };
}

function emptyTrimesterDraft(): TrimesterDraft {
  return { date: "", note: "", poids: "", taille: "", perimCranien: "" };
}

function parentToForm(p: ParentIndices | undefined): ParentDraft {
  if (!p) return emptyParentDraft();
  return {
    poids: p.poids != null ? String(p.poids) : "",
    taille: p.taille != null ? String(p.taille) : "",
    perimCranien: p.perimCranien != null ? String(p.perimCranien) : "",
    dateNaissance: p.dateNaissance ? p.dateNaissance.slice(0, 10) : "",
  };
}

function babyTrimesterToForm(baby: BabyIndices | undefined, tri: Trimester): TrimesterDraft {
  const entry = baby?.trimesters.find((t) => t.trimester === tri);
  if (!entry) return emptyTrimesterDraft();
  return {
    date: entry.date ? entry.date.slice(0, 10) : "",
    note: entry.note ?? "",
    poids: entry.poids != null ? String(entry.poids) : "",
    taille: entry.taille != null ? String(entry.taille) : "",
    perimCranien: entry.perimCranien != null ? String(entry.perimCranien) : "",
  };
}

function parseOptionalFloat(val: string): number | undefined {
  const n = parseFloat(val);
  return Number.isNaN(n) ? undefined : n;
}

/* ─────────────────────────── Page ─────────────────────────── */

export default function AdminIndicesPage() {
  const params = useParams<{ projectId: string }>();
  const projectId = params.projectId;
  const router = useRouter();

  const [ready, setReady] = useState(false);
  const [loading, setLoading] = useState(false);
  const [message, setMessage] = useState("");
  const [stepIndex, setStepIndex] = useState(0);

  const [project, setProject] = useState<ProjectSummary | null>(null);
  const [indices, setIndices] = useState<ProjectIndicesResponse | null>(null);

  // Papa
  const [papaDraft, setPapaDraft] = useState<ParentDraft>(emptyParentDraft());
  const [papaPhotos, setPapaPhotos] = useState<Array<{ id: string; url: string }>>([]);

  // Maman
  const [mamanDraft, setManamDraft] = useState<ParentDraft>(emptyParentDraft());
  const [mamanPhotos, setManamPhotos] = useState<Array<{ id: string; url: string }>>([]);

  // Bébés — datation + trimestres + DPA
  const [babyDpas, setBabyDpas] = useState<Record<number, string>>({});
  const [trimesterDrafts, setTrimesterDrafts] = useState<Record<string, TrimesterDraft>>({});
  const [trimesterPhotos, setTrimesterPhotos] = useState<Record<string, Array<{ id: string; url: string }>>>({});

  const apiBaseUrl = getApiUrl();

  const babyCount = project?.babyCount ?? 1;

  // Steps: 0=papa mesures, 1=papa photos, 2=maman mesures, 3=maman photos,
  // puis par bébé: 4+4n=datation(+DPA), 4+4n+1=T1, 4+4n+2=T2, 4+4n+3=T3
  // Dernier step = recap
  const totalBabySteps = babyCount * 4;
  const totalSteps = 4 + totalBabySteps + 1; // +1 recap
  const recapStepIndex = totalSteps - 1;

  const getBabyLabel = useCallback(
    (idx: number) => project?.babies?.find((b) => b.babyIndex === idx)?.label ?? `Bébé ${idx}`,
    [project],
  );

  const getBabyStepInfo = (step: number): { babyIndex: number; trimester: Trimester } | null => {
    if (step < 4 || step >= 4 + totalBabySteps) return null;
    const offset = step - 4;
    const babyIndex = Math.floor(offset / 4) + 1;
    const triIndex = offset % 4;
    return { babyIndex, trimester: TRIMESTERS[triIndex] };
  };

  const triKey = (babyIndex: number, tri: Trimester) => `${babyIndex}-${tri}`;

  /* ─── Init ─── */
  useEffect(() => {
    const session = loadSession();
    if (!session) { router.replace("/"); return; }
    if (session.user.role !== "ADMIN") { router.replace("/predictions"); return; }

    Promise.all([getMyProjects(), getProjectIndices(projectId)])
      .then(([projects, idx]) => {
        const proj = projects.find((p) => p.id === projectId) ?? null;
        setProject(proj);
        setIndices(idx);

        // Init papa
        const papa = idx.parentIndices.find((p) => p.parentType === "PAPA");
        setPapaDraft(parentToForm(papa));
        setPapaPhotos(papa?.photos.map((ph) => ({ id: ph.id, url: ph.url })) ?? []);

        // Init maman
        const maman = idx.parentIndices.find((p) => p.parentType === "MAMAN");
        setManamDraft(parentToForm(maman));
        setManamPhotos(maman?.photos.map((ph) => ({ id: ph.id, url: ph.url })) ?? []);

        // Init bébés
        const dpas: Record<number, string> = {};
        const triDrafts: Record<string, TrimesterDraft> = {};
        const triPh: Record<string, Array<{ id: string; url: string }>> = {};
        const bc = proj?.babyCount ?? 1;
        for (let i = 1; i <= bc; i++) {
          const baby = idx.babyIndices.find((b) => b.babyIndex === i);
          dpas[i] = baby?.dpa ? baby.dpa.slice(0, 10) : "";
          for (const tri of TRIMESTERS) {
            triDrafts[triKey(i, tri)] = babyTrimesterToForm(baby, tri);
            const existingTri = baby?.trimesters.find((t) => t.trimester === tri);
            triPh[triKey(i, tri)] = existingTri?.photos.map((ph) => ({ id: ph.id, url: ph.url })) ?? [];
          }
        }
        setBabyDpas(dpas);
        setTrimesterDrafts(triDrafts);
        setTrimesterPhotos(triPh);
      })
      .catch((err) => {
        setMessage(err instanceof Error ? err.message : "Erreur de chargement");
      })
      .finally(() => setReady(true));
  }, [projectId, router]);

  /* ─── Save current step ─── */
  const saveCurrentStep = useCallback(async () => {
    setLoading(true);
    setMessage("");
    try {
      if (stepIndex === 0) {
        await upsertParentIndices(projectId, "PAPA", {
          poids: parseOptionalFloat(papaDraft.poids),
          taille: parseOptionalFloat(papaDraft.taille),
          perimCranien: parseOptionalFloat(papaDraft.perimCranien),
          dateNaissance: papaDraft.dateNaissance || null,
        });
      } else if (stepIndex === 2) {
        await upsertParentIndices(projectId, "MAMAN", {
          poids: parseOptionalFloat(mamanDraft.poids),
          taille: parseOptionalFloat(mamanDraft.taille),
          perimCranien: parseOptionalFloat(mamanDraft.perimCranien),
          dateNaissance: mamanDraft.dateNaissance || null,
        });
      } else {
        const babyStep = getBabyStepInfo(stepIndex);
        if (babyStep) {
          const { babyIndex, trimester } = babyStep;
          const triOffset = stepIndex - 4 - (babyIndex - 1) * 4;
          if (triOffset === 0) {
            // Datation step: DPA + données de la première échographie
            await upsertBabyIndices(projectId, babyIndex, { dpa: babyDpas[babyIndex] || null });
          }
          const draft = trimesterDrafts[triKey(babyIndex, trimester)] ?? emptyTrimesterDraft();
          await upsertBabyTrimester(projectId, babyIndex, trimester, {
            date: draft.date || null,
            note: draft.note || null,
            poids: parseOptionalFloat(draft.poids),
            taille: parseOptionalFloat(draft.taille),
            perimCranien: parseOptionalFloat(draft.perimCranien),
          });
        }
      }
    } catch (err) {
      if (err instanceof Error && err.message.includes("Session")) {
        clearSession();
        router.replace("/");
        return false;
      }
      setMessage(err instanceof Error ? err.message : "Erreur de sauvegarde");
      return false;
    } finally {
      setLoading(false);
    }
    return true;
  }, [stepIndex, projectId, papaDraft, mamanDraft, babyDpas, trimesterDrafts, getBabyStepInfo, router]);

  const goNext = async () => {
    if (stepIndex === recapStepIndex) return;
    const photoStep = stepIndex === 1 || stepIndex === 3;
    let ok = true;
    if (!photoStep) {
      ok = (await saveCurrentStep()) !== false;
    }
    if (ok) setStepIndex((s) => s + 1);
  };

  const goBack = () => setStepIndex((s) => Math.max(0, s - 1));

  /* ─── Photo upload ─── */
  const handleParentPhotosAdd = async (parentType: ParentType, files: File[]) => {
    setLoading(true);
    try {
      for (const file of files) {
        const photo = await uploadParentPhoto(projectId, parentType, file);
        if (parentType === "PAPA") {
          setPapaPhotos((prev) => [...prev, { id: photo.id, url: photo.url }]);
        } else {
          setManamPhotos((prev) => [...prev, { id: photo.id, url: photo.url }]);
        }
      }
    } catch (err) {
      setMessage(err instanceof Error ? err.message : "Erreur upload");
    } finally {
      setLoading(false);
    }
  };

  const handleTrimesterPhotosAdd = async (babyIndex: number, trimester: Trimester, files: File[]) => {
    setLoading(true);
    try {
      for (const file of files) {
        const photo = await uploadTrimesterPhoto(projectId, babyIndex, trimester, file);
        const k = triKey(babyIndex, trimester);
        setTrimesterPhotos((prev) => ({ ...prev, [k]: [...(prev[k] ?? []), { id: photo.id, url: photo.url }] }));
      }
    } catch (err) {
      setMessage(err instanceof Error ? err.message : "Erreur upload");
    } finally {
      setLoading(false);
    }
  };

  const removeParentPhoto = async (parentType: ParentType, photoId: string) => {
    setLoading(true);
    try {
      await deleteParentPhoto(projectId, parentType, photoId);
      if (parentType === "PAPA") {
        setPapaPhotos((prev) => prev.filter((p) => p.id !== photoId));
      } else {
        setManamPhotos((prev) => prev.filter((p) => p.id !== photoId));
      }
    } catch (err) {
      setMessage(err instanceof Error ? err.message : "Erreur suppression");
    } finally {
      setLoading(false);
    }
  };

  const removeTrimesterPhoto = async (babyIndex: number, trimester: Trimester, photoId: string) => {
    setLoading(true);
    try {
      await deleteTrimesterPhoto(projectId, babyIndex, trimester, photoId);
      const k = triKey(babyIndex, trimester);
      setTrimesterPhotos((prev) => ({ ...prev, [k]: (prev[k] ?? []).filter((p) => p.id !== photoId) }));
    } catch (err) {
      setMessage(err instanceof Error ? err.message : "Erreur suppression");
    } finally {
      setLoading(false);
    }
  };

  /* ─── Helpers render ─── */
  const renderParentForm = (parentType: ParentType, draft: ParentDraft, setDraft: (d: ParentDraft) => void) => {
    const label = parentType === "PAPA" ? "Papa" : "Maman";
    return (
      <div className={wizardStyles.formGrid}>
        <p className={wizardStyles.helpText}>
          Renseigne les informations physiques de naissance de {label}. Tous les champs sont optionnels.
        </p>
        <div className="field">
          <label htmlFor={`${parentType}-poids`}>Poids de naissance (kg)</label>
          <input
            id={`${parentType}-poids`}
            type="number"
            step="0.1"
            placeholder="ex: 3.4"
            value={draft.poids}
            onChange={(e) => setDraft({ ...draft, poids: e.target.value })}
          />
        </div>
        <div className="field">
          <label htmlFor={`${parentType}-taille`}>Taille de naissance (cm)</label>
          <input
            id={`${parentType}-taille`}
            type="number"
            step="1"
            placeholder="ex: 51"
            value={draft.taille}
            onChange={(e) => setDraft({ ...draft, taille: e.target.value })}
          />
        </div>
        <div className="field">
          <label htmlFor={`${parentType}-perim`}>Périmètre crânien de naissance (cm)</label>
          <input
            id={`${parentType}-perim`}
            type="number"
            step="0.1"
            placeholder="ex: 35"
            value={draft.perimCranien}
            onChange={(e) => setDraft({ ...draft, perimCranien: e.target.value })}
          />
        </div>
        <div className="field">
          <label htmlFor={`${parentType}-dob`}>Date de naissance</label>
          <input
            id={`${parentType}-dob`}
            type="date"
            value={draft.dateNaissance}
            onChange={(e) => setDraft({ ...draft, dateNaissance: e.target.value })}
          />
        </div>
      </div>
    );
  };

  const renderPhotoStep = (
    parentType: ParentType,
    photos: Array<{ id: string; url: string }>,
    label: string,
  ) => (
    <div className={styles.photoStepGrid}>
      <p className={wizardStyles.helpText}>
        Ajoute jusqu&apos;à 5 photos pour {label} (échographies, portraits...).
      </p>
      <PhotoField
        photos={photos}
        maxPhotos={5}
        loading={loading}
        apiBaseUrl={apiBaseUrl}
        onAdd={(files) => void handleParentPhotosAdd(parentType, files)}
        onRemove={(id) => void removeParentPhoto(parentType, id)}
      />
    </div>
  );

  const renderTrimesterStep = (babyIndex: number, trimester: Trimester) => {
    const k = triKey(babyIndex, trimester);
    const draft = trimesterDrafts[k] ?? emptyTrimesterDraft();
    const photos = trimesterPhotos[k] ?? [];
    const triOffset = (stepIndex - 4) % 4;
    const isDpaStep = triOffset === 0;

    return (
      <div className={wizardStyles.formGrid}>
        {isDpaStep && (
          <div className="field">
            <label htmlFor={`dpa-${babyIndex}`}>
              Date prévue d&apos;accouchement — {getBabyLabel(babyIndex)}
            </label>
            <input
              id={`dpa-${babyIndex}`}
              type="date"
              value={babyDpas[babyIndex] ?? ""}
              onChange={(e) => setBabyDpas((prev) => ({ ...prev, [babyIndex]: e.target.value }))}
            />
            <p className={wizardStyles.helpText}>Optionnel — peut être renseignée plus tard.</p>
          </div>
        )}

        <p className={wizardStyles.helpText}>
          {TRIMESTER_LABELS[trimester]} — données d&apos;échographie pour {getBabyLabel(babyIndex)}. Tous les champs sont optionnels.
        </p>

        <div className="field">
          <label htmlFor={`${k}-date`}>Date de l&apos;échographie</label>
          <input
            id={`${k}-date`}
            type="date"
            value={draft.date}
            onChange={(e) => setTrimesterDrafts((prev) => ({ ...prev, [k]: { ...draft, date: e.target.value } }))}
          />
        </div>
        <div className="field">
          <label htmlFor={`${k}-poids`}>Poids estimé (kg)</label>
          <input
            id={`${k}-poids`}
            type="number"
            step="0.001"
            placeholder="ex: 0.185"
            value={draft.poids}
            onChange={(e) => setTrimesterDrafts((prev) => ({ ...prev, [k]: { ...draft, poids: e.target.value } }))}
          />
        </div>
        <div className="field">
          <label htmlFor={`${k}-taille`}>Taille estimée (cm)</label>
          <input
            id={`${k}-taille`}
            type="number"
            step="0.1"
            placeholder="ex: 16"
            value={draft.taille}
            onChange={(e) => setTrimesterDrafts((prev) => ({ ...prev, [k]: { ...draft, taille: e.target.value } }))}
          />
        </div>
        <div className="field">
          <label htmlFor={`${k}-perim`}>Périmètre crânien (cm)</label>
          <input
            id={`${k}-perim`}
            type="number"
            step="0.1"
            placeholder="ex: 12"
            value={draft.perimCranien}
            onChange={(e) => setTrimesterDrafts((prev) => ({ ...prev, [k]: { ...draft, perimCranien: e.target.value } }))}
          />
        </div>
        <div className="field">
          <label htmlFor={`${k}-note`}>Note / observations</label>
          <textarea
            id={`${k}-note`}
            rows={3}
            placeholder="Tout va bien, bébé est en bonne santé..."
            value={draft.note}
            onChange={(e) => setTrimesterDrafts((prev) => ({ ...prev, [k]: { ...draft, note: e.target.value } }))}
          />
        </div>

        {/* Photos trimestre */}
        <div>
          <p className={wizardStyles.helpText}>Photos / échographies (max 5)</p>
          <PhotoField
            photos={photos}
            maxPhotos={5}
            loading={loading}
            apiBaseUrl={apiBaseUrl}
            onAdd={(files) => void handleTrimesterPhotosAdd(babyIndex, trimester, files)}
            onRemove={(id) => void removeTrimesterPhoto(babyIndex, trimester, id)}
          />
        </div>
      </div>
    );
  };

  const getStepTitle = (): string => {
    if (stepIndex === 0) return "Papa — informations de naissance";
    if (stepIndex === 1) return "Papa — photos";
    if (stepIndex === 2) return "Maman — informations de naissance";
    if (stepIndex === 3) return "Maman — photos";
    if (stepIndex === recapStepIndex) return "Récapitulatif";
    const babyStep = getBabyStepInfo(stepIndex);
    if (babyStep) {
      return `${getBabyLabel(babyStep.babyIndex)} — ${TRIMESTER_LABELS[babyStep.trimester]}`;
    }
    return "";
  };

  if (!ready) {
    return (
      <main className={`app-shell ${wizardStyles.page}`}>
        <section className={`panel ${wizardStyles.panel}`}>
          <p>Chargement...</p>
        </section>
      </main>
    );
  }

  return (
    <main className={`app-shell ${wizardStyles.page}`}>
      <section className={`panel ${wizardStyles.header}`}>
        <div>
          <p className="mono">Admin / Projets / {project?.name ?? projectId} / Indices</p>
          <h1>Indices de grossesse</h1>
          <p>Renseigne les informations physiques de naissance des parents et les données du bébé, trimestre par trimestre.</p>
        </div>
        <div className={wizardStyles.headerActions}>
          <Link className="btn btn-soft" href="/admin">
            Retour admin
          </Link>
        </div>
      </section>

      <section className={`panel ${wizardStyles.panel}`}>
        <div className={wizardStyles.stepHeader}>
          <span className={wizardStyles.stepPill}>
            Étape {stepIndex + 1} / {totalSteps}
          </span>
          <strong style={{ fontSize: "0.95rem" }}>{getStepTitle()}</strong>
        </div>

        {/* ── Étapes ── */}
        {stepIndex === 0 && renderParentForm("PAPA", papaDraft, setPapaDraft)}
        {stepIndex === 1 && renderPhotoStep("PAPA", papaPhotos, "papa")}
        {stepIndex === 2 && renderParentForm("MAMAN", mamanDraft, setManamDraft)}
        {stepIndex === 3 && renderPhotoStep("MAMAN", mamanPhotos, "maman")}

        {stepIndex >= 4 && stepIndex < 4 + totalBabySteps && (() => {
          const babyStep = getBabyStepInfo(stepIndex);
          if (!babyStep) return null;
          return renderTrimesterStep(babyStep.babyIndex, babyStep.trimester);
        })()}

        {stepIndex === recapStepIndex && (
          <div className={wizardStyles.reviewPanel}>
            <h3>Récapitulatif</h3>
            <p><strong>Projet :</strong> {project?.name ?? projectId}</p>
            <p><strong>Papa (naissance) :</strong> {papaDraft.poids ? `${papaDraft.poids} kg` : "—"}, {papaDraft.taille ? `${papaDraft.taille} cm` : "—"} — {papaPhotos.length} photo(s)</p>
            <p><strong>Maman (naissance) :</strong> {mamanDraft.poids ? `${mamanDraft.poids} kg` : "—"}, {mamanDraft.taille ? `${mamanDraft.taille} cm` : "—"} — {mamanPhotos.length} photo(s)</p>
            {Array.from({ length: babyCount }, (_, i) => i + 1).map((bi) => (
              <p key={bi}>
                <strong>{getBabyLabel(bi)} :</strong>{" "}
                DPA {babyDpas[bi] || "—"} —{" "}
                {TRIMESTERS.map((t) => {
                  const ph = trimesterPhotos[triKey(bi, t)]?.length ?? 0;
                  return `${TRIMESTER_LABELS[t]}: ${ph} photo(s)`;
                }).join(", ")}
              </p>
            ))}
            <p>Les informations ont été sauvegardées au fil des étapes.</p>
          </div>
        )}

        {message ? <p className={wizardStyles.message}>{message}</p> : null}

        <div className={wizardStyles.wizardActions}>
          <button
            type="button"
            className="btn btn-soft"
            onClick={goBack}
            disabled={loading || stepIndex === 0}
          >
            Retour
          </button>

          {stepIndex === recapStepIndex ? (
            <Link className="btn btn-primary" href="/admin">
              Terminer
            </Link>
          ) : (
            <button
              type="button"
              className="btn btn-primary"
              disabled={loading}
              onClick={() => void goNext()}
            >
              {loading ? "Sauvegarde..." : "Continuer"}
            </button>
          )}
        </div>
      </section>
    </main>
  );
}
