"use client";

import { useEffect, useMemo, useState } from "react";
import { useSession } from "next-auth/react";
import type {
  HumanCapitalFileRequirementDTO,
  HumanCapitalWorkspaceTabConfig,
  HumanCapitalWorkspaceTabKey,
  HumanCapitalWorkspaceVersion,
  HumanCapitalWorkspaceWidgetKey,
} from "@/lib/human-capital/types";

const TAB_CATALOG: Array<{
  key: HumanCapitalWorkspaceTabKey;
  label: string;
  description: string;
  widgets: HumanCapitalWorkspaceWidgetKey[];
}> = [
  {
    key: "resumen",
    label: "Resumen",
    description: "Score, tendencias y vision general de Capital Humano.",
    widgets: ["summary_metrics"],
  },
  {
    key: "expedientes",
    label: "Expedientes",
    description: "Checklist de documentos por persona y estatus de completitud.",
    widgets: ["people_files_table"],
  },
  {
    key: "nomina",
    label: "Nomina",
    description: "Percepciones, deducciones y aportaciones por periodo y ubicacion.",
    widgets: ["payroll_summary"],
  },
  {
    key: "reclutamiento",
    label: "Reclutamiento",
    description: "Headcount actual, vacantes y organizacion ideal por sucursal/rol.",
    widgets: ["recruitment_headcount", "recruitment_vacancies", "recruitment_org_target"],
  },
  {
    key: "desarrollo",
    label: "Desarrollo",
    description: "Anuncios internos y cursos para crecimiento de carrera.",
    widgets: ["career_feed"],
  },
  {
    key: "cumplimiento",
    label: "Cumplimiento",
    description: "IMSS, Infonavit, Fonacot y seguimiento de pagos.",
    widgets: ["compliance_overview"],
  },
];

const WIDGET_OPTIONS: Array<{ key: HumanCapitalWorkspaceWidgetKey; label: string }> = [
  { key: "summary_metrics", label: "Resumen y KPI" },
  { key: "people_files_table", label: "Tabla de expedientes" },
  { key: "payroll_summary", label: "Resumen de nomina" },
  { key: "recruitment_headcount", label: "Headcount" },
  { key: "recruitment_vacancies", label: "Vacantes" },
  { key: "recruitment_org_target", label: "Organizacion ideal" },
  { key: "career_feed", label: "Anuncios y cursos" },
  { key: "compliance_overview", label: "Cumplimiento y pagos" },
];

const FIELD_TYPE_OPTIONS = ["document", "text", "email", "phone", "date", "number"] as const;

type RequirementDraft = HumanCapitalFileRequirementDTO & { isNew?: boolean };

function normalizeOrder(tabs: HumanCapitalWorkspaceTabConfig[]) {
  return tabs.map((tab, idx) => ({ ...tab, order: idx }));
}

function sortByOrder(tabs: HumanCapitalWorkspaceTabConfig[]) {
  return [...tabs].sort((a, b) => a.order - b.order);
}

export default function HumanCapitalWorkspaceConfigPage() {
  const { data: session } = useSession();
  const canManage =
    session?.user?.role === "owner" ||
    (session?.user?.role === "leader" &&
      (session?.user?.department === "capital_humano" || session?.user?.department === "administracion"));

  const [tabs, setTabs] = useState<HumanCapitalWorkspaceTabConfig[]>([]);
  const [history, setHistory] = useState<HumanCapitalWorkspaceVersion[]>([]);
  const [requirements, setRequirements] = useState<RequirementDraft[]>([]);
  const [changeSummary, setChangeSummary] = useState("");
  const [newTabKey, setNewTabKey] = useState<HumanCapitalWorkspaceTabKey | "">("");
  const [error, setError] = useState<string | null>(null);
  const [status, setStatus] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  const unusedTabs = useMemo(() => {
    const used = new Set(tabs.map((tab) => tab.key));
    return TAB_CATALOG.filter((tab) => !used.has(tab.key));
  }, [tabs]);

  useEffect(() => {
    if (unusedTabs.length > 0) {
      setNewTabKey(unusedTabs[0].key);
    } else {
      setNewTabKey("");
    }
  }, [unusedTabs]);

  useEffect(() => {
    let cancelled = false;

    async function load() {
      if (!canManage) {
        setLoading(false);
        return;
      }

      try {
        const [configResponse, historyResponse, requirementsResponse] = await Promise.all([
          fetch("/api/human-capital/workspace/config?mode=draft", { method: "GET", cache: "no-store" }),
          fetch("/api/human-capital/workspace/history", { method: "GET", cache: "no-store" }),
          fetch("/api/human-capital/files/requirements", { method: "GET", cache: "no-store" }),
        ]);

        const configPayload = (await configResponse.json()) as { config?: { tabs?: HumanCapitalWorkspaceTabConfig[] }; error?: string };
        const historyPayload = (await historyResponse.json()) as { history?: HumanCapitalWorkspaceVersion[]; error?: string };
        const requirementsPayload = (await requirementsResponse.json()) as { requirements?: HumanCapitalFileRequirementDTO[]; error?: string };

        if (!configResponse.ok) {
          throw new Error(configPayload.error ?? "No se pudo cargar configuracion.");
        }
        if (!historyResponse.ok) {
          throw new Error(historyPayload.error ?? "No se pudo cargar historial.");
        }
        if (!requirementsResponse.ok) {
          throw new Error(requirementsPayload.error ?? "No se pudieron cargar requisitos.");
        }

        if (!cancelled) {
          setTabs(sortByOrder(configPayload.config?.tabs ?? []));
          setHistory(historyPayload.history ?? []);
          setRequirements(requirementsPayload.requirements ?? []);
        }
      } catch (loadError) {
        if (!cancelled) {
          setError(loadError instanceof Error ? loadError.message : "No se pudo cargar configuracion.");
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [canManage]);

  const updateTab = (index: number, updates: Partial<HumanCapitalWorkspaceTabConfig>) => {
    setTabs((prev) => {
      const next = [...prev];
      next[index] = { ...next[index], ...updates };
      return next;
    });
  };

  const moveTab = (index: number, direction: "up" | "down") => {
    setTabs((prev) => {
      const next = [...prev];
      const target = direction === "up" ? index - 1 : index + 1;
      if (target < 0 || target >= next.length) {
        return prev;
      }
      const temp = next[index];
      next[index] = next[target];
      next[target] = temp;
      return normalizeOrder(next);
    });
  };

  const toggleWidget = (index: number, widget: HumanCapitalWorkspaceWidgetKey) => {
    setTabs((prev) => {
      const next = [...prev];
      const widgets = new Set(next[index].widgets);
      if (widgets.has(widget)) {
        widgets.delete(widget);
      } else {
        widgets.add(widget);
      }
      next[index] = { ...next[index], widgets: Array.from(widgets) };
      return next;
    });
  };

  const addTab = () => {
    if (!newTabKey) {
      return;
    }

    const template = TAB_CATALOG.find((tab) => tab.key === newTabKey);
    if (!template) {
      return;
    }

    setTabs((prev) =>
      normalizeOrder([
        ...prev,
        {
          key: template.key,
          label: template.label,
          description: template.description,
          order: prev.length,
          visible: true,
          widgets: template.widgets,
        },
      ])
    );
  };

  const saveDraft = async () => {
    setError(null);
    setStatus(null);
    setSaving(true);

    try {
      const response = await fetch("/api/human-capital/workspace/config", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ tabs: normalizeOrder(tabs), changeSummary }),
      });
      const payload = (await response.json()) as { error?: string; config?: { tabs?: HumanCapitalWorkspaceTabConfig[] } };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo guardar el borrador.");
      }
      setTabs(sortByOrder(payload.config?.tabs ?? []));
      setStatus("Borrador guardado.");
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "No se pudo guardar el borrador.");
    } finally {
      setSaving(false);
    }
  };

  const publishDraft = async () => {
    setError(null);
    setStatus(null);
    setSaving(true);

    try {
      const response = await fetch("/api/human-capital/workspace/publish", { method: "POST" });
      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo publicar.");
      }
      setStatus("Workspace publicado.");
      const historyResponse = await fetch("/api/human-capital/workspace/history", { method: "GET", cache: "no-store" });
      const historyPayload = (await historyResponse.json()) as { history?: HumanCapitalWorkspaceVersion[] };
      setHistory(historyPayload.history ?? []);
    } catch (publishError) {
      setError(publishError instanceof Error ? publishError.message : "No se pudo publicar.");
    } finally {
      setSaving(false);
    }
  };

  const loadPublished = async () => {
    setError(null);
    setStatus(null);
    setSaving(true);

    try {
      const response = await fetch("/api/human-capital/workspace/config?mode=published", { method: "GET", cache: "no-store" });
      const payload = (await response.json()) as { error?: string; config?: { tabs?: HumanCapitalWorkspaceTabConfig[] } };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo cargar configuracion publicada.");
      }
      setTabs(sortByOrder(payload.config?.tabs ?? []));
      setStatus("Configuracion publicada cargada en el editor.");
    } catch (loadError) {
      setError(loadError instanceof Error ? loadError.message : "No se pudo cargar configuracion publicada.");
    } finally {
      setSaving(false);
    }
  };

  const applyHistoryVersion = (version: HumanCapitalWorkspaceVersion) => {
    setTabs(sortByOrder(version.tabs));
    setChangeSummary(`Rollback a version ${version.version}`);
    setStatus(`Version ${version.version} cargada en el editor.`);
  };

  const updateRequirement = (index: number, updates: Partial<RequirementDraft>) => {
    setRequirements((prev) => {
      const next = [...prev];
      next[index] = { ...next[index], ...updates };
      return next;
    });
  };

  const addRequirement = () => {
    setRequirements((prev) => [
      ...prev,
      {
        id: "",
        key: "",
        label: "",
        description: "",
        fieldType: "document",
        isRequired: true,
        isActive: true,
        sortOrder: prev.length * 10,
        isNew: true,
      },
    ]);
  };

  const saveRequirements = async () => {
    setError(null);
    setStatus(null);
    setSaving(true);

    try {
      const response = await fetch("/api/human-capital/files/requirements", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ requirements }),
      });
      const payload = (await response.json()) as { error?: string; requirements?: HumanCapitalFileRequirementDTO[] };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudieron guardar requisitos.");
      }
      setRequirements(payload.requirements ?? []);
      setStatus("Requisitos guardados.");
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "No se pudieron guardar requisitos.");
    } finally {
      setSaving(false);
    }
  };

  if (!canManage) {
    return (
      <div className="rounded-benell border border-benell-stroke bg-benell-surface p-6 shadow-benell">
        <h1 className="text-h2 font-semibold">Configuracion de Capital Humano</h1>
        <p className="text-body text-benell-text-soft">Solo lideres pueden editar el workspace.</p>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <header className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <h1 className="text-display">Configuracion de Capital Humano</h1>
        <p className="text-body-lg text-benell-text-soft">Administra tabs, widgets y requisitos sin hardcode.</p>
      </header>

      {loading ? <p className="text-label text-benell-text-soft">Cargando configuracion...</p> : null}
      {error ? <p className="text-label text-benell-red">{error}</p> : null}
      {status ? <p className="text-label text-benell-text-soft">{status}</p> : null}

      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h2 className="text-h2 font-semibold">Tabs y widgets</h2>
            <p className="text-body text-benell-text-soft">Define visibilidad, orden y contenido de cada tab.</p>
          </div>
          <div className="flex flex-wrap gap-2">
            <button
              type="button"
              onClick={() => void saveDraft()}
              disabled={saving}
              className="rounded-pill bg-benell-brown px-3 py-2 text-label font-semibold text-white disabled:opacity-50"
            >
              Guardar borrador
            </button>
            <button
              type="button"
              onClick={() => void publishDraft()}
              disabled={saving}
              className="rounded-pill border border-benell-brown px-3 py-2 text-label font-semibold text-benell-brown disabled:opacity-50"
            >
              Publicar
            </button>
            <button
              type="button"
              onClick={() => void loadPublished()}
              disabled={saving}
              className="rounded-pill border border-benell-stroke px-3 py-2 text-label font-semibold text-benell-text-soft disabled:opacity-50"
            >
              Cargar publicado
            </button>
          </div>
        </div>

        <div className="mt-4 grid grid-cols-1 gap-4">
          {tabs.map((tab, index) => (
            <article key={tab.key} className="rounded-benell border border-benell-stroke bg-white p-4">
              <div className="flex flex-wrap items-center gap-3">
                <div className="flex-1 min-w-[220px]">
                  <label className="text-xs font-semibold text-benell-text-soft">Titulo</label>
                  <input
                    value={tab.label}
                    onChange={(event) => updateTab(index, { label: event.target.value })}
                    className="mt-1 w-full rounded-lg border border-benell-stroke px-3 py-2 text-sm"
                  />
                </div>
                <div className="flex-1 min-w-[220px]">
                  <label className="text-xs font-semibold text-benell-text-soft">Descripcion</label>
                  <input
                    value={tab.description ?? ""}
                    onChange={(event) => updateTab(index, { description: event.target.value })}
                    className="mt-1 w-full rounded-lg border border-benell-stroke px-3 py-2 text-sm"
                  />
                </div>
                <label className="flex items-center gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={tab.visible}
                    onChange={(event) => updateTab(index, { visible: event.target.checked })}
                  />
                  Visible
                </label>
                <div className="flex items-center gap-2">
                  <button
                    type="button"
                    onClick={() => moveTab(index, "up")}
                    disabled={index === 0}
                    className="rounded-lg border border-benell-stroke px-2 py-1 text-xs text-benell-text-soft disabled:opacity-50"
                  >
                    Subir
                  </button>
                  <button
                    type="button"
                    onClick={() => moveTab(index, "down")}
                    disabled={index === tabs.length - 1}
                    className="rounded-lg border border-benell-stroke px-2 py-1 text-xs text-benell-text-soft disabled:opacity-50"
                  >
                    Bajar
                  </button>
                </div>
              </div>

              <div className="mt-3 grid grid-cols-1 gap-2 md:grid-cols-2">
                {WIDGET_OPTIONS.map((widget) => (
                  <label key={widget.key} className="flex items-center gap-2 text-sm text-benell-text">
                    <input
                      type="checkbox"
                      checked={tab.widgets.includes(widget.key)}
                      onChange={() => toggleWidget(index, widget.key)}
                    />
                    {widget.label}
                  </label>
                ))}
              </div>
            </article>
          ))}
        </div>

        {unusedTabs.length > 0 ? (
          <div className="mt-4 flex flex-wrap items-center gap-3">
            <select
              value={newTabKey}
              onChange={(event) => setNewTabKey(event.target.value as HumanCapitalWorkspaceTabKey)}
              className="rounded-lg border border-benell-stroke px-3 py-2 text-sm"
            >
              {unusedTabs.map((option) => (
                <option key={option.key} value={option.key}>
                  {option.label}
                </option>
              ))}
            </select>
            <button
              type="button"
              onClick={addTab}
              className="rounded-pill border border-benell-stroke px-3 py-2 text-label font-semibold text-benell-text"
            >
              Agregar tab
            </button>
          </div>
        ) : null}

        <div className="mt-4">
          <label className="text-xs font-semibold text-benell-text-soft">Resumen del cambio</label>
          <input
            value={changeSummary}
            onChange={(event) => setChangeSummary(event.target.value)}
            placeholder="Ej: Ajuste de tabs por reclutamiento"
            className="mt-1 w-full rounded-lg border border-benell-stroke px-3 py-2 text-sm"
          />
        </div>
      </section>

      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h2 className="text-h2 font-semibold">Requisitos de expediente</h2>
            <p className="text-body text-benell-text-soft">Define documentos obligatorios y opcionales.</p>
          </div>
          <div className="flex flex-wrap gap-2">
            <button
              type="button"
              onClick={addRequirement}
              className="rounded-pill border border-benell-stroke px-3 py-2 text-label font-semibold text-benell-text"
            >
              Agregar requisito
            </button>
            <button
              type="button"
              onClick={() => void saveRequirements()}
              disabled={saving}
              className="rounded-pill bg-benell-brown px-3 py-2 text-label font-semibold text-white disabled:opacity-50"
            >
              Guardar requisitos
            </button>
          </div>
        </div>

        <div className="mt-4 overflow-x-auto">
          <table className="w-full min-w-[960px] text-sm">
            <thead>
              <tr className="border-b border-benell-stroke text-left text-label text-benell-text-soft">
                <th className="px-2 py-2">Key</th>
                <th className="px-2 py-2">Etiqueta</th>
                <th className="px-2 py-2">Descripcion</th>
                <th className="px-2 py-2">Tipo</th>
                <th className="px-2 py-2">Requerido</th>
                <th className="px-2 py-2">Activo</th>
                <th className="px-2 py-2">Orden</th>
              </tr>
            </thead>
            <tbody>
              {requirements.map((req, index) => (
                <tr key={`${req.id || "new"}-${index}`} className="border-b border-benell-stroke/70">
                  <td className="px-2 py-2">
                    <input
                      value={req.key}
                      onChange={(event) => updateRequirement(index, { key: event.target.value })}
                      className="w-full rounded border border-benell-stroke px-2 py-1 text-xs"
                      placeholder="curp"
                    />
                  </td>
                  <td className="px-2 py-2">
                    <input
                      value={req.label}
                      onChange={(event) => updateRequirement(index, { label: event.target.value })}
                      className="w-full rounded border border-benell-stroke px-2 py-1 text-xs"
                      placeholder="CURP"
                    />
                  </td>
                  <td className="px-2 py-2">
                    <input
                      value={req.description ?? ""}
                      onChange={(event) => updateRequirement(index, { description: event.target.value })}
                      className="w-full rounded border border-benell-stroke px-2 py-1 text-xs"
                      placeholder="Detalle opcional"
                    />
                  </td>
                  <td className="px-2 py-2">
                    <select
                      value={req.fieldType}
                      onChange={(event) => updateRequirement(index, { fieldType: event.target.value })}
                      className="w-full rounded border border-benell-stroke px-2 py-1 text-xs"
                    >
                      {FIELD_TYPE_OPTIONS.map((option) => (
                        <option key={option} value={option}>
                          {option}
                        </option>
                      ))}
                    </select>
                  </td>
                  <td className="px-2 py-2">
                    <input
                      type="checkbox"
                      checked={req.isRequired}
                      onChange={(event) => updateRequirement(index, { isRequired: event.target.checked })}
                    />
                  </td>
                  <td className="px-2 py-2">
                    <input
                      type="checkbox"
                      checked={req.isActive}
                      onChange={(event) => updateRequirement(index, { isActive: event.target.checked })}
                    />
                  </td>
                  <td className="px-2 py-2">
                    <input
                      type="number"
                      value={req.sortOrder}
                      onChange={(event) => updateRequirement(index, { sortOrder: Number(event.target.value) })}
                      className="w-full rounded border border-benell-stroke px-2 py-1 text-xs"
                    />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>

      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <h2 className="text-h2 font-semibold">Historial</h2>
        <p className="text-body text-benell-text-soft">Versiones publicadas y borradores recientes.</p>
        <div className="mt-4 grid grid-cols-1 gap-3">
          {history.map((version) => (
            <div key={version.id} className="rounded-benell border border-benell-stroke bg-white p-4">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-sm font-semibold text-benell-text">Version {version.version}</p>
                  <p className="text-caption text-benell-text-soft">
                    Estado: {version.status} · Publicado: {version.publishedAt ?? "-"}
                  </p>
                </div>
                <button
                  type="button"
                  onClick={() => applyHistoryVersion(version)}
                  className="rounded-pill border border-benell-stroke px-3 py-1 text-xs font-semibold text-benell-text"
                >
                  Cargar en borrador
                </button>
              </div>
              {version.changeSummary ? (
                <p className="mt-2 text-xs text-benell-text-soft">{version.changeSummary}</p>
              ) : null}
            </div>
          ))}
        </div>
      </section>
    </div>
  );
}
