"use client";

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

type HallazgosBootstrap = {
  locations: Array<{ id: string; name: string; code: string }>;
  users: Array<{ id: string; name: string }>;
};

type FindingStatus = "all" | "open" | "in_progress" | "resolved" | "closed";
type FindingPriority = "all" | "low" | "medium" | "high" | "critical";

export default function ExperienciometroHallazgosPage() {
  const [bootstrap, setBootstrap] = useState<HallazgosBootstrap>({
    locations: [],
    users: [],
  });
  const [findings, setFindings] = useState<ExperienceFindingDTO[]>([]);
  const [search, setSearch] = useState("");
  const [locationId, setLocationId] = useState("all");
  const [status, setStatus] = useState<FindingStatus>("all");
  const [priority, setPriority] = useState<FindingPriority>("all");
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

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

    const loadBootstrap = async () => {
      try {
        const [overviewResponse, evaluationsResponse] = await Promise.all([
          fetch("/api/experienciometro/overview", { method: "GET", cache: "no-store", signal: controller.signal }),
          fetch("/api/experienciometro/evaluations", { method: "GET", cache: "no-store", signal: controller.signal }),
        ]);

        const overview = (await overviewResponse.json()) as {
          error?: string;
          locations?: Array<{ id: string; name: string; code: string }>;
        };

        const evaluations = (await evaluationsResponse.json()) as {
          error?: string;
          users?: Array<{ id: string; name: string }>;
        };

        if (!overviewResponse.ok) {
          throw new Error(overview.error ?? "No se pudo cargar sucursales.");
        }

        if (!evaluationsResponse.ok) {
          throw new Error(evaluations.error ?? "No se pudo cargar usuarios.");
        }

        setBootstrap({
          locations: overview.locations ?? [],
          users: evaluations.users ?? [],
        });
      } catch (loadError) {
        if (controller.signal.aborted) {
          return;
        }

        setError(loadError instanceof Error ? loadError.message : "No se pudo cargar filtros de hallazgos.");
      }
    };

    void loadBootstrap();

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

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

    const loadFindings = async () => {
      setIsLoading(true);
      setError(null);
      try {
        const params = new URLSearchParams();
        if (search.trim()) {
          params.set("q", search.trim());
        }
        if (locationId !== "all") {
          params.set("locationId", locationId);
        }
        if (status !== "all") {
          params.set("status", status);
        }
        if (priority !== "all") {
          params.set("priority", priority);
        }

        const response = await fetch(`/api/experienciometro/findings?${params.toString()}`, {
          method: "GET",
          cache: "no-store",
          signal: controller.signal,
        });

        const payload = (await response.json()) as { error?: string; findings?: ExperienceFindingDTO[] };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudieron cargar hallazgos.");
        }

        setFindings(payload.findings ?? []);
      } catch (loadError) {
        if (controller.signal.aborted) {
          return;
        }

        setError(loadError instanceof Error ? loadError.message : "No se pudieron cargar hallazgos.");
      } finally {
        if (!controller.signal.aborted) {
          setIsLoading(false);
        }
      }
    };

    void loadFindings();

    return () => controller.abort();
  }, [locationId, priority, search, status]);

  const usersById = useMemo(() => Object.fromEntries(bootstrap.users.map((user) => [user.id, user.name])), [bootstrap.users]);

  const patchFinding = async (findingId: string, patch: Record<string, unknown>) => {
    const response = await fetch(`/api/experienciometro/findings/${findingId}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(patch),
    });

    const payload = (await response.json()) as { error?: string; finding?: ExperienceFindingDTO };
    if (!response.ok || !payload.finding) {
      throw new Error(payload.error ?? "No se pudo actualizar hallazgo.");
    }

    setFindings((prev) => prev.map((finding) => (finding.id === findingId ? payload.finding! : finding)));
  };

  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">Hallazgos</p>
        <h1 className="mt-1 text-2xl font-semibold text-benell-text">Seguimiento de observaciones</h1>
        <p className="mt-1 text-sm text-benell-text-soft">Gestiona prioridad, estatus y responsables vinculados a evaluaciones de sucursal.</p>
      </header>

      <ExperienciometroTabs />

      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
        <div className="grid gap-2 md:grid-cols-4">
          <input
            value={search}
            onChange={(event) => setSearch(event.target.value)}
            className="rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm"
            placeholder="Buscar hallazgo"
          />
          <select value={locationId} onChange={(event) => setLocationId(event.target.value)} className="rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm">
            <option value="all">Todas las sucursales</option>
            {bootstrap.locations.map((location) => (
              <option key={location.id} value={location.id}>
                {location.name}
              </option>
            ))}
          </select>
          <select value={status} onChange={(event) => setStatus(event.target.value as FindingStatus)} className="rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm">
            <option value="all">Todos los estatus</option>
            <option value="open">Open</option>
            <option value="in_progress">In progress</option>
            <option value="resolved">Resolved</option>
            <option value="closed">Closed</option>
          </select>
          <select value={priority} onChange={(event) => setPriority(event.target.value as FindingPriority)} className="rounded-xl border border-benell-stroke bg-white px-3 py-2 text-sm">
            <option value="all">Todas las prioridades</option>
            <option value="low">Baja</option>
            <option value="medium">Media</option>
            <option value="high">Alta</option>
            <option value="critical">Crítica</option>
          </select>
        </div>
      </section>

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

      <section className="space-y-2">
        {findings.map((finding) => (
          <article key={finding.id} className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
            <div className="grid gap-2 xl:grid-cols-[minmax(0,2fr)_150px_150px_220px]">
              <div>
                <p className="text-sm font-semibold text-benell-text">{finding.title}</p>
                <p className="text-xs text-benell-text-soft">{finding.categoryLabel ?? "General"} · {finding.description || "Sin descripción"}</p>
                <p className="text-xs text-benell-text-soft">Creado: {new Date(finding.createdAt).toLocaleString("es-MX")}</p>
              </div>

              <label className="space-y-1 text-xs font-semibold text-benell-text-soft">
                Prioridad
                <select
                  value={finding.priority}
                  onChange={(event) => {
                    void patchFinding(finding.id, { priority: event.target.value }).catch((patchError) => {
                      setError(patchError instanceof Error ? patchError.message : "No se pudo actualizar.");
                    });
                  }}
                  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="space-y-1 text-xs font-semibold text-benell-text-soft">
                Estatus
                <select
                  value={finding.status}
                  onChange={(event) => {
                    void patchFinding(finding.id, { status: event.target.value }).catch((patchError) => {
                      setError(patchError instanceof Error ? patchError.message : "No se pudo actualizar.");
                    });
                  }}
                  className="w-full rounded-lg border border-benell-stroke bg-white px-2 py-1.5 text-xs"
                >
                  <option value="open">Open</option>
                  <option value="in_progress">In progress</option>
                  <option value="resolved">Resolved</option>
                  <option value="closed">Closed</option>
                </select>
              </label>

              <label className="space-y-1 text-xs font-semibold text-benell-text-soft">
                Responsable
                <select
                  value={finding.responsibleUserId ?? ""}
                  onChange={(event) => {
                    void patchFinding(finding.id, { responsibleUserId: event.target.value || null }).catch((patchError) => {
                      setError(patchError instanceof Error ? patchError.message : "No se pudo actualizar.");
                    });
                  }}
                  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>
                <span className="block text-[11px] text-benell-text-soft">Actual: {finding.responsibleName ?? usersById[finding.responsibleUserId ?? ""] ?? "Sin asignar"}</span>
              </label>
            </div>
          </article>
        ))}
      </section>
    </div>
  );
}
