"use client";

import { useEffect, useMemo, useState } from "react";
import ExperienciometroTabs from "@/components/experienciometro/ExperienciometroTabs";

type EvaluationBootstrap = {
  template: {
    id: string;
    categories: Array<{
      id: string;
      key: string;
      name: string;
      items: Array<{
        id: string;
        label: string;
        requiresObservation: boolean;
      }>;
    }>;
  };
  locations: Array<{ id: string; name: string; code: string }>;
  users: Array<{ id: string; name: string }>;
};

type ResponseDraft = {
  score: number;
  comment: string;
  observation: string;
  createFinding: boolean;
  findingPriority: "low" | "medium" | "high" | "critical";
  responsibleUserId: string;
};

export default function ExperienciometroEvaluacionesPage() {
  const [bootstrap, setBootstrap] = useState<EvaluationBootstrap | null>(null);
  const [locationId, setLocationId] = useState("");
  const [responses, setResponses] = useState<Record<string, ResponseDraft>>({});
  const [filesByItemId, setFilesByItemId] = useState<Record<string, File | null>>({});
  const [generalObservations, setGeneralObservations] = useState("");
  const [strengths, setStrengths] = useState("");
  const [improvementAreas, setImprovementAreas] = useState("");
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [resultMessage, setResultMessage] = useState<string | null>(null);

  useEffect(() => {
    if (typeof window === "undefined") {
      return;
    }

    const fromQuery = new URLSearchParams(window.location.search).get("locationId") ?? "";
    if (fromQuery) {
      setLocationId(fromQuery);
    }
  }, []);

  useEffect(() => {
    const controller = new AbortController();

    const load = async () => {
      setIsLoading(true);
      setError(null);
      try {
        const response = await fetch("/api/experienciometro/evaluations", {
          method: "GET",
          cache: "no-store",
          signal: controller.signal,
        });

        const payload = (await response.json()) as { error?: string } & EvaluationBootstrap;
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo cargar la plantilla de evaluación.");
        }

        setBootstrap(payload);

        const initialResponses: Record<string, ResponseDraft> = {};
        const initialFiles: Record<string, File | null> = {};

        for (const category of payload.template.categories) {
          for (const item of category.items) {
            initialResponses[item.id] = {
              score: 2,
              comment: "",
              observation: "",
              createFinding: false,
              findingPriority: "medium",
              responsibleUserId: "",
            };
            initialFiles[item.id] = null;
          }
        }

        setResponses(initialResponses);
        setFilesByItemId(initialFiles);
      } catch (loadError) {
        if (controller.signal.aborted) {
          return;
        }

        setError(loadError instanceof Error ? loadError.message : "No se pudo cargar la plantilla de evaluación.");
      } finally {
        if (!controller.signal.aborted) {
          setIsLoading(false);
        }
      }
    };

    void load();

    return () => controller.abort();
  }, []);

  const totalScorePreview = useMemo(() => {
    const values = Object.values(responses);
    if (values.length === 0) {
      return 0;
    }

    const avgRaw = values.reduce((acc, response) => acc + response.score, 0) / values.length;
    return Math.round(((avgRaw / 3) * 100) * 10) / 10;
  }, [responses]);

  const handleSubmit = async () => {
    if (!bootstrap) {
      return;
    }

    if (!locationId) {
      setError("Selecciona una sucursal.");
      return;
    }

    setIsSaving(true);
    setError(null);
    setResultMessage(null);

    try {
      const responsePayload = Object.entries(responses).map(([itemId, draft]) => ({
        itemId,
        score: draft.score,
        comment: draft.comment,
        observation: draft.observation,
        createFinding: draft.createFinding,
        findingPriority: draft.findingPriority,
        responsibleUserId: draft.responsibleUserId || undefined,
      }));

      const response = await fetch("/api/experienciometro/evaluations", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          locationId,
          templateId: bootstrap.template.id,
          generalObservations,
          strengths,
          improvementAreas,
          responses: responsePayload,
        }),
      });

      const payload = (await response.json()) as {
        error?: string;
        evaluation?: {
          id: string;
          responses: Array<{
            itemId: string;
            id: string;
            itemLabelSnapshot: string;
          }>;
        };
      };

      if (!response.ok || !payload.evaluation) {
        throw new Error(payload.error ?? "No se pudo guardar la evaluación.");
      }

      const pendingFiles = Object.entries(filesByItemId).filter(([, file]) => Boolean(file));
      let uploadErrors = 0;

      if (pendingFiles.length > 0) {
        const responseByItemId = new Map(payload.evaluation.responses.map((entry) => [entry.itemId, entry]));

        await Promise.all(
          pendingFiles.map(async ([itemId, file]) => {
            const related = responseByItemId.get(itemId);
            if (!file || !related) {
              return;
            }

            const formData = new FormData();
            formData.set("title", `Evidencia ${related.itemLabelSnapshot}`);
            formData.set("locationId", locationId);
            formData.set("evaluationId", payload.evaluation!.id);
            formData.set("responseId", related.id);
            formData.set("file", file);

            const uploadResponse = await fetch("/api/experienciometro/evidence/upload", {
              method: "POST",
              body: formData,
            });

            if (!uploadResponse.ok) {
              uploadErrors += 1;
            }
          })
        );
      }

      setResultMessage(
        uploadErrors > 0
          ? `Evaluación guardada. ${uploadErrors} evidencia(s) no se pudieron subir.`
          : "Evaluación guardada y evidencias cargadas correctamente."
      );

      setGeneralObservations("");
      setStrengths("");
      setImprovementAreas("");
      setResponses((prev) =>
        Object.fromEntries(
          Object.entries(prev).map(([itemId]) => [
            itemId,
            {
              score: 2,
              comment: "",
              observation: "",
              createFinding: false,
              findingPriority: "medium",
              responsibleUserId: "",
            },
          ])
        )
      );
      setFilesByItemId((prev) => Object.fromEntries(Object.keys(prev).map((key) => [key, null])));
    } catch (submitError) {
      setError(submitError instanceof Error ? submitError.message : "No se pudo guardar la evaluación.");
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <div className="space-y-5">
      <header className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <p className="text-sm font-semibold uppercase tracking-wide text-benell-brown">Nueva evaluación</p>
        <h1 className="mt-1 text-2xl font-semibold text-benell-text">Formulario de experiencia</h1>
        <p className="mt-1 text-sm text-benell-text-soft">Completa todos los reactivos en escala 0-3 y adjunta evidencia cuando aplique.</p>
      </header>

      <ExperienciometroTabs />

      {error ? <p className="text-sm font-semibold text-benell-red">{error}</p> : null}
      {resultMessage ? <p className="text-sm font-semibold text-benell-green">{resultMessage}</p> : null}
      {isLoading ? <p className="text-sm text-benell-text-soft">Cargando formulario...</p> : null}

      {bootstrap ? (
        <div className="space-y-4">
          <section className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
            <div className="grid gap-3 md:grid-cols-[minmax(0,1fr)_220px]">
              <label className="space-y-1">
                <span className="text-sm font-semibold text-benell-text">Sucursal</span>
                <select
                  value={locationId}
                  onChange={(event) => setLocationId(event.target.value)}
                  className="w-full rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-benell-brown"
                >
                  <option value="">Selecciona una sucursal</option>
                  {bootstrap.locations.map((location) => (
                    <option key={location.id} value={location.id}>
                      {location.name}
                    </option>
                  ))}
                </select>
              </label>
              <article className="rounded-xl border border-benell-stroke bg-white px-3 py-2">
                <p className="text-xs text-benell-text-soft">Score automático (preview)</p>
                <p className="text-h2 font-semibold text-benell-text">{totalScorePreview.toFixed(1)}</p>
              </article>
            </div>
          </section>

          {bootstrap.template.categories.map((category) => (
            <section key={category.id} className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
              <h2 className="text-h2 font-semibold text-benell-text">{category.name}</h2>
              <div className="mt-3 space-y-3">
                {category.items.map((item) => {
                  const draft = responses[item.id];
                  if (!draft) {
                    return null;
                  }

                  return (
                    <article key={item.id} className="rounded-xl border border-benell-stroke bg-white p-3">
                      <p className="text-sm font-semibold text-benell-text">{item.label}</p>

                      <div className="mt-2 grid gap-2 md:grid-cols-2 xl:grid-cols-4">
                        <label className="space-y-1">
                          <span className="text-xs font-semibold text-benell-text-soft">Score</span>
                          <select
                            value={draft.score}
                            onChange={(event) =>
                              setResponses((prev) => ({
                                ...prev,
                                [item.id]: {
                                  ...prev[item.id],
                                  score: Number(event.target.value),
                                },
                              }))
                            }
                            className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                          >
                            <option value={0}>0 · Mal</option>
                            <option value={1}>1 · Regular</option>
                            <option value={2}>2 · Bien</option>
                            <option value={3}>3 · Excelente</option>
                          </select>
                        </label>

                        <label className="space-y-1 md:col-span-2">
                          <span className="text-xs font-semibold text-benell-text-soft">Comentario</span>
                          <input
                            value={draft.comment}
                            onChange={(event) =>
                              setResponses((prev) => ({
                                ...prev,
                                [item.id]: {
                                  ...prev[item.id],
                                  comment: event.target.value,
                                },
                              }))
                            }
                            className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                            placeholder="Comentario opcional"
                          />
                        </label>

                        <label className="space-y-1">
                          <span className="text-xs font-semibold text-benell-text-soft">Evidencia</span>
                          <input
                            type="file"
                            accept="image/jpeg,image/png,image/webp,application/pdf"
                            onChange={(event) =>
                              setFilesByItemId((prev) => ({
                                ...prev,
                                [item.id]: event.target.files?.[0] ?? null,
                              }))
                            }
                            className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                          />
                        </label>
                      </div>

                      <div className="mt-2 grid gap-2 md:grid-cols-3">
                        <label className="space-y-1 md:col-span-2">
                          <span className="text-xs font-semibold text-benell-text-soft">Observación / hallazgo</span>
                          <input
                            value={draft.observation}
                            onChange={(event) =>
                              setResponses((prev) => ({
                                ...prev,
                                [item.id]: {
                                  ...prev[item.id],
                                  observation: event.target.value,
                                },
                              }))
                            }
                            className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                            placeholder="Describe el hallazgo"
                          />
                        </label>
                        <label className="space-y-1">
                          <span className="text-xs font-semibold text-benell-text-soft">Prioridad</span>
                          <select
                            value={draft.findingPriority}
                            onChange={(event) =>
                              setResponses((prev) => ({
                                ...prev,
                                [item.id]: {
                                  ...prev[item.id],
                                  findingPriority: event.target.value as ResponseDraft["findingPriority"],
                                },
                              }))
                            }
                            className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                          >
                            <option value="low">Baja</option>
                            <option value="medium">Media</option>
                            <option value="high">Alta</option>
                            <option value="critical">Crítica</option>
                          </select>
                        </label>

                        <label className="inline-flex items-center gap-2 text-xs font-semibold text-benell-text-soft">
                          <input
                            type="checkbox"
                            checked={draft.createFinding}
                            onChange={(event) =>
                              setResponses((prev) => ({
                                ...prev,
                                [item.id]: {
                                  ...prev[item.id],
                                  createFinding: event.target.checked,
                                },
                              }))
                            }
                          />
                          Crear hallazgo
                        </label>

                        <label className="space-y-1 md:col-span-2">
                          <span className="text-xs font-semibold text-benell-text-soft">Responsable</span>
                          <select
                            value={draft.responsibleUserId}
                            onChange={(event) =>
                              setResponses((prev) => ({
                                ...prev,
                                [item.id]: {
                                  ...prev[item.id],
                                  responsibleUserId: event.target.value,
                                },
                              }))
                            }
                            className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                          >
                            <option value="">Sin asignar</option>
                            {bootstrap.users.map((user) => (
                              <option key={user.id} value={user.id}>
                                {user.name}
                              </option>
                            ))}
                          </select>
                        </label>
                      </div>
                    </article>
                  );
                })}
              </div>
            </section>
          ))}

          <section className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
            <h2 className="text-h2 font-semibold text-benell-text">Cierre de evaluación</h2>
            <div className="mt-3 grid gap-2">
              <label className="space-y-1">
                <span className="text-xs font-semibold text-benell-text-soft">Observaciones generales</span>
                <textarea
                  value={generalObservations}
                  onChange={(event) => setGeneralObservations(event.target.value)}
                  className="min-h-20 w-full rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm"
                />
              </label>
              <label className="space-y-1">
                <span className="text-xs font-semibold text-benell-text-soft">Fortalezas detectadas</span>
                <textarea
                  value={strengths}
                  onChange={(event) => setStrengths(event.target.value)}
                  className="min-h-20 w-full rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm"
                />
              </label>
              <label className="space-y-1">
                <span className="text-xs font-semibold text-benell-text-soft">Áreas de mejora</span>
                <textarea
                  value={improvementAreas}
                  onChange={(event) => setImprovementAreas(event.target.value)}
                  className="min-h-20 w-full rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm"
                />
              </label>
            </div>

            <div className="mt-4 flex justify-end">
              <button
                type="button"
                onClick={() => void handleSubmit()}
                disabled={isSaving}
                className="rounded-pill bg-benell-brown px-4 py-2 text-sm font-semibold text-white disabled:opacity-60"
              >
                {isSaving ? "Guardando..." : "Guardar evaluación"}
              </button>
            </div>
          </section>
        </div>
      ) : null}
    </div>
  );
}
