"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useSession } from "next-auth/react";
import { Search } from "lucide-react";
import { useUIStore } from "@/lib/store/ui-store";
import { ROLE_LABELS } from "@/lib/utils";
import type { UserRole } from "@/lib/types";

type PersonRecord = {
  id: string;
  name: string;
  email: string;
  role: UserRole;
  roleLabel: string;
  departmentLabel: string | null;
  departmentRole: string | null;
  status: string;
};

function getInitials(name: string) {
  const trimmed = name.trim();
  if (!trimmed) {
    return "U";
  }

  const chunks = trimmed.split(/\s+/).filter(Boolean);
  if (chunks.length === 1) {
    return chunks[0].slice(0, 2).toUpperCase();
  }

  return `${chunks[0][0] ?? ""}${chunks[1][0] ?? ""}`.toUpperCase();
}

export default function PeoplePage() {
  const { data: session } = useSession();
  const search = useUIStore((state) => state.search.trim().toLowerCase());
  const [people, setPeople] = useState<PersonRecord[]>([]);
  const [draftRoleByUserId, setDraftRoleByUserId] = useState<Record<string, UserRole>>({});
  const [isLoading, setIsLoading] = useState(true);
  const [isUpdatingByUserId, setIsUpdatingByUserId] = useState<Record<string, boolean>>({});
  const [isDeletingByUserId, setIsDeletingByUserId] = useState<Record<string, boolean>>({});
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const canManagePeople = session?.user?.role === "owner" || Boolean(session?.user?.canElevate);

  const loadPeople = useCallback(async () => {
    setIsLoading(true);
    setErrorMessage(null);

    try {
      const response = await fetch("/api/people", {
        method: "GET",
        cache: "no-store",
      });

      const payload = (await response.json()) as { people?: PersonRecord[]; error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo cargar el directorio.");
      }

      const records = payload.people ?? [];
      setPeople(records);
      setDraftRoleByUserId(
        Object.fromEntries(records.map((person) => [person.id, person.role]))
      );
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "No se pudo cargar el directorio.");
    } finally {
      setIsLoading(false);
    }
  }, []);

  useEffect(() => {
    loadPeople();
  }, [loadPeople]);

  const filteredPeople = useMemo(
    () =>
      people.filter((person) => {
        const matchesSearch =
          !search ||
          person.name.toLowerCase().includes(search) ||
          person.roleLabel.toLowerCase().includes(search) ||
          person.departmentLabel?.toLowerCase().includes(search) ||
          person.email.toLowerCase().includes(search);

        return matchesSearch;
      }),
    [people, search]
  );

  const handleSaveRole = async (person: PersonRecord) => {
    const draftRole = draftRoleByUserId[person.id];
    if (!draftRole || draftRole === person.role) {
      return;
    }

    setErrorMessage(null);
    setIsUpdatingByUserId((prev) => ({ ...prev, [person.id]: true }));

    try {
      const response = await fetch(`/api/people/${person.id}/role`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ role: draftRole }),
      });

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

      await loadPeople();
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "No se pudo actualizar el rol.");
    } finally {
      setIsUpdatingByUserId((prev) => ({ ...prev, [person.id]: false }));
    }
  };

  const handleDeletePerson = async (person: PersonRecord) => {
    if (!canManagePeople) {
      return;
    }

    const shouldDelete = window.confirm(`Eliminar usuario ${person.name} (${person.email})? Esta accion no se puede deshacer.`);
    if (!shouldDelete) {
      return;
    }

    setErrorMessage(null);
    setIsDeletingByUserId((prev) => ({ ...prev, [person.id]: true }));

    try {
      const response = await fetch(`/api/people/${person.id}`, {
        method: "DELETE",
      });

      const payload = (await response.json().catch(() => ({}))) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo eliminar el usuario.");
      }

      await loadPeople();
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "No se pudo eliminar el usuario.");
    } finally {
      setIsDeletingByUserId((prev) => ({ ...prev, [person.id]: false }));
    }
  };

  return (
    <div className="space-y-6">
      <header>
        <h1 className="text-display">Personas</h1>
        <p className="text-body-lg text-benell-text-soft">Directorio de empleados y seguimiento</p>
      </header>

      <label className="relative block max-w-2xl" htmlFor="people-search-readonly">
        <Search className="pointer-events-none absolute left-3 top-2.5 size-5 text-benell-text-soft" aria-hidden />
        <input
          id="people-search-readonly"
          readOnly
          value={search}
          placeholder="Buscar por nombre o rol..."
          className="text-body w-full rounded-xl border border-benell-stroke bg-benell-surface px-10 py-2 text-benell-text-soft"
        />
      </label>

      {errorMessage ? <p className="text-label text-benell-red">{errorMessage}</p> : null}

      {isLoading ? <p className="text-body text-benell-text-soft">Cargando personas...</p> : null}

      <section className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
        {filteredPeople.map((person) => (
          <article key={person.id} className="rounded-benell border border-benell-stroke bg-benell-surface p-5">
            <div className="flex gap-4">
              <span className="text-h3 inline-flex size-14 shrink-0 items-center justify-center rounded-full bg-benell-caramel font-semibold text-white md:size-16">
                {getInitials(person.name)}
              </span>
              <div className="min-w-0">
                <h2 className="text-h2 truncate font-semibold">{person.name}</h2>
                <p className="text-body text-benell-text-soft">{person.roleLabel}</p>
                <p className="text-label truncate text-benell-text-soft">{person.email}</p>
                <div className="text-caption mt-2 flex flex-wrap gap-2">
                  {person.departmentLabel ? (
                    <span className="rounded-pill border border-benell-stroke px-2 py-0.5 font-semibold">{person.departmentLabel}</span>
                  ) : null}
                  {person.departmentRole ? (
                    <span className="rounded-pill border border-benell-stroke px-2 py-0.5">{person.departmentRole}</span>
                  ) : null}
                  <span className="text-benell-text-soft">{person.status}</span>
                </div>
              </div>
            </div>

            {canManagePeople ? (
              <div className="mt-4 border-t border-benell-stroke pt-3">
                <label className="block space-y-1">
                  <span className="text-label font-semibold">Acceso de plataforma</span>
                  <div className="flex items-center gap-2">
                    <select
                      value={draftRoleByUserId[person.id] ?? person.role}
                      onChange={(event) =>
                        setDraftRoleByUserId((prev) => ({
                          ...prev,
                          [person.id]: event.target.value as UserRole,
                        }))
                      }
                      className="text-body flex-1 rounded-xl border border-benell-stroke bg-white px-3 py-2"
                    >
                      <option value="owner">{ROLE_LABELS.owner}</option>
                      <option value="leader">{ROLE_LABELS.leader}</option>
                      <option value="employee">{ROLE_LABELS.employee}</option>
                    </select>
                    <button
                      type="button"
                      disabled={isUpdatingByUserId[person.id] || (draftRoleByUserId[person.id] ?? person.role) === person.role}
                      onClick={() => handleSaveRole(person)}
                      className="rounded-pill bg-benell-brown px-3 py-2 text-label font-semibold text-white disabled:opacity-50"
                    >
                      Guardar
                    </button>
                  </div>
                </label>
                <button
                  type="button"
                  onClick={() => void handleDeletePerson(person)}
                  disabled={isDeletingByUserId[person.id] || person.id === session?.user?.id}
                  className="mt-3 rounded-pill border border-benell-red/40 bg-benell-red/10 px-3 py-2 text-label font-semibold text-benell-red disabled:opacity-50"
                >
                  {isDeletingByUserId[person.id] ? "Eliminando..." : person.id === session?.user?.id ? "No puedes eliminarte" : "Eliminar usuario"}
                </button>
              </div>
            ) : null}

            <Link
              href={`/people/${person.id}`}
              className="text-label mt-3 inline-flex font-semibold text-benell-caramel hover:text-benell-brown"
            >
              Ver perfil →
            </Link>
          </article>
        ))}
      </section>
    </div>
  );
}
