"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useSession } from "next-auth/react";
import { AlertTriangle, CheckCircle2, Clock3, Link2, PlayCircle, RefreshCcw, Trash2, UploadCloud } from "lucide-react";
import { DEPARTMENT_OPTIONS, getDepartmentLabel } from "@/lib/departments";
import { cn } from "@/lib/utils";
import type { CaptureAssigneeDTO, CaptureBoardResponse, CaptureEvidenceDTO, CaptureRowDTO } from "@/lib/capture";
import type { DepartmentKey, UserRole } from "@/lib/types";

type CaptureWorkspaceTab = "queue" | "evidence" | "automation";

type CaptureWorkspaceProps = {
  requestedDepartment?: string | null;
  forcedDepartment?: DepartmentKey;
};

type RowEditFormState = {
  objectiveIndicator: string;
  quantityQuality: string;
  compliance: string;
  dueCommitment: string;
  captureNote: string;
  ownerUserId: string;
  captureMode: "manual" | "auto" | "hybrid";
  automationSource: string;
  freshnessSlaHours: string;
};

type ProjectsContextResponse = {
  initiatives?: Array<{ id: string; name: string }>;
  tasks?: Array<{ id: string; title: string; initiativeId: string }>;
};

const ACTIVE_CAPTURE_DEPARTMENTS: DepartmentKey[] = ["marketing", "capital_humano", "operaciones", "proyectos"];

function normalizeDepartment(department: string | null | undefined): DepartmentKey | null {
  if (!department) {
    return null;
  }

  if (department === "administracion") {
    return "capital_humano";
  }

  if (ACTIVE_CAPTURE_DEPARTMENTS.includes(department as DepartmentKey)) {
    return department as DepartmentKey;
  }

  return null;
}

function toEditForm(row: CaptureRowDTO): RowEditFormState {
  return {
    objectiveIndicator: row.objectiveIndicator ?? "",
    quantityQuality: row.quantityQuality ?? "",
    compliance: row.compliance ?? "",
    dueCommitment: row.dueCommitment ?? "",
    captureNote: row.captureNote ?? "",
    ownerUserId: row.ownerUserId ?? "",
    captureMode: row.captureMode,
    automationSource: row.automationSource ?? "",
    freshnessSlaHours: String(row.freshnessSlaHours),
  };
}

function formatDateTime(iso: string | null): string {
  if (!iso) {
    return "-";
  }

  const parsed = new Date(iso);
  if (Number.isNaN(parsed.getTime())) {
    return "-";
  }

  return new Intl.DateTimeFormat("es-MX", {
    dateStyle: "medium",
    timeStyle: "short",
    timeZone: "UTC",
  }).format(parsed);
}

function statusLabel(status: CaptureRowDTO["status"]) {
  if (status === "captured") {
    return "Captured";
  }
  if (status === "in_progress") {
    return "In Progress";
  }
  if (status === "stale") {
    return "Stale";
  }
  if (status === "error") {
    return "Error";
  }
  return "Pending";
}

function statusClassName(status: CaptureRowDTO["status"]) {
  if (status === "captured") {
    return "border-benell-green/30 bg-benell-green/15 text-benell-green";
  }
  if (status === "in_progress") {
    return "border-benell-amber/40 bg-benell-amber/15 text-benell-amber";
  }
  if (status === "stale" || status === "error") {
    return "border-benell-red/40 bg-benell-red/15 text-benell-red";
  }
  return "border-benell-stroke bg-benell-surface-muted text-benell-text-soft";
}

export default function CaptureWorkspace({ requestedDepartment, forcedDepartment }: CaptureWorkspaceProps) {
  const { data: session, status } = useSession();
  const role = (session?.user?.role ?? "employee") as UserRole;
  const viewerDepartment = normalizeDepartment(session?.user?.department ?? null);

  const [selectedDepartment, setSelectedDepartment] = useState<DepartmentKey | null>(forcedDepartment ?? null);
  const [weekStartInput, setWeekStartInput] = useState("");
  const [tab, setTab] = useState<CaptureWorkspaceTab>("queue");

  const [query, setQuery] = useState("");
  const [from, setFrom] = useState("");
  const [to, setTo] = useState("");
  const [mineOnly, setMineOnly] = useState(false);
  const [filterInitiativeId, setFilterInitiativeId] = useState("");
  const [filterTaskId, setFilterTaskId] = useState("");

  const [board, setBoard] = useState<CaptureBoardResponse | null>(null);
  const [assignees, setAssignees] = useState<CaptureAssigneeDTO[]>([]);
  const [initiatives, setInitiatives] = useState<Array<{ id: string; name: string }>>([]);
  const [tasks, setTasks] = useState<Array<{ id: string; title: string; initiativeId: string }>>([]);

  const [editingRowId, setEditingRowId] = useState<string | null>(null);
  const [editForm, setEditForm] = useState<RowEditFormState | null>(null);

  const [evidenceRowId, setEvidenceRowId] = useState("");
  const [evidenceKind, setEvidenceKind] = useState<"link" | "photo" | "document">("link");
  const [evidenceTitle, setEvidenceTitle] = useState("");
  const [evidenceNote, setEvidenceNote] = useState("");
  const [evidenceUrl, setEvidenceUrl] = useState("");
  const [evidenceFile, setEvidenceFile] = useState<File | null>(null);
  const [evidenceInitiativeId, setEvidenceInitiativeId] = useState("");
  const [evidenceTaskId, setEvidenceTaskId] = useState("");
  const [ownerGroupTitle, setOwnerGroupTitle] = useState("");
  const [ownerKpiName, setOwnerKpiName] = useState("");
  const [ownerKpiObjective, setOwnerKpiObjective] = useState("");

  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const canUseWorkspace =
    role === "owner" || ((role === "leader" || role === "employee") && Boolean(viewerDepartment));
  const canManageDepartment =
    role === "owner" ||
    (role === "leader" && Boolean(viewerDepartment && selectedDepartment && viewerDepartment === selectedDepartment));

  const projectFilterTasks = useMemo(
    () => tasks.filter((task) => (filterInitiativeId ? task.initiativeId === filterInitiativeId : true)),
    [filterInitiativeId, tasks]
  );
  const evidenceTasks = useMemo(
    () => tasks.filter((task) => (evidenceInitiativeId ? task.initiativeId === evidenceInitiativeId : true)),
    [evidenceInitiativeId, tasks]
  );

  useEffect(() => {
    if (status !== "authenticated") {
      return;
    }

    if (forcedDepartment) {
      setSelectedDepartment(forcedDepartment);
      return;
    }

    if (role === "owner") {
      setSelectedDepartment(normalizeDepartment(requestedDepartment ?? null) ?? "marketing");
      return;
    }

    setSelectedDepartment(viewerDepartment);
  }, [forcedDepartment, requestedDepartment, role, status, viewerDepartment]);

  const loadBoard = useCallback(async () => {
    if (!selectedDepartment) {
      setIsLoading(false);
      return;
    }

    setIsLoading(true);
    try {
      const params = new URLSearchParams({ department: selectedDepartment });
      if (weekStartInput) {
        params.set("weekStart", weekStartInput);
      }
      if (query.trim()) {
        params.set("q", query.trim());
      }
      if (mineOnly && session?.user.id) {
        params.set("uploadedById", session.user.id);
      }
      if (from) {
        params.set("from", `${from}T00:00:00.000Z`);
      }
      if (to) {
        params.set("to", `${to}T23:59:59.999Z`);
      }
      if (filterInitiativeId) {
        params.set("initiativeId", filterInitiativeId);
      }
      if (filterTaskId) {
        params.set("taskId", filterTaskId);
      }

      const response = await fetch(`/api/capture/board?${params.toString()}`, {
        method: "GET",
        cache: "no-store",
      });
      const payload = (await response.json()) as CaptureBoardResponse & { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo cargar capture board.");
      }

      setBoard(payload);
      setWeekStartInput(payload.weekStart);
      if (!evidenceRowId || !payload.rows.find((row) => row.id === evidenceRowId)) {
        setEvidenceRowId(payload.rows.find((row) => row.canEdit)?.id ?? payload.rows[0]?.id ?? "");
      }
      setError(null);
    } catch (loadError) {
      setError(loadError instanceof Error ? loadError.message : "No se pudo cargar capture board.");
    } finally {
      setIsLoading(false);
    }
  }, [
    evidenceRowId,
    filterInitiativeId,
    filterTaskId,
    from,
    mineOnly,
    query,
    selectedDepartment,
    session?.user.id,
    to,
    weekStartInput,
  ]);

  useEffect(() => {
    if (status !== "authenticated" || !canUseWorkspace || !selectedDepartment) {
      return;
    }

    void loadBoard();
  }, [canUseWorkspace, loadBoard, selectedDepartment, status]);

  useEffect(() => {
    if (!selectedDepartment || !canManageDepartment) {
      setAssignees([]);
      return;
    }
    const scopedDepartment = selectedDepartment;

    let cancelled = false;
    async function loadAssignees() {
      const response = await fetch(`/api/capture/assignees?department=${encodeURIComponent(scopedDepartment)}`, {
        method: "GET",
        cache: "no-store",
      });
      const payload = (await response.json()) as { assignees?: CaptureAssigneeDTO[] };
      if (!cancelled) {
        setAssignees(payload.assignees ?? []);
      }
    }

    void loadAssignees().catch(() => {
      if (!cancelled) {
        setAssignees([]);
      }
    });

    return () => {
      cancelled = true;
    };
  }, [canManageDepartment, selectedDepartment]);

  useEffect(() => {
    if (selectedDepartment !== "proyectos") {
      setInitiatives([]);
      setTasks([]);
      return;
    }

    let cancelled = false;
    async function loadProjectsContext() {
      const response = await fetch("/api/projects/dashboard", { method: "GET", cache: "no-store" });
      const payload = (await response.json()) as ProjectsContextResponse;
      if (!cancelled) {
        setInitiatives(payload.initiatives ?? []);
        setTasks(payload.tasks ?? []);
      }
    }

    void loadProjectsContext().catch(() => {
      if (!cancelled) {
        setInitiatives([]);
        setTasks([]);
      }
    });

    return () => {
      cancelled = true;
    };
  }, [selectedDepartment]);

  const submitRowPatch = async () => {
    if (!editingRowId || !editForm) {
      return;
    }

    setIsSaving(true);
    try {
      const editingRow = board?.rows.find((row) => row.id === editingRowId) ?? null;
      const payload: Record<string, string | number | null> = {
        quantityQuality: editForm.quantityQuality,
        compliance: editForm.compliance,
        dueCommitment: editForm.dueCommitment,
        captureNote: editForm.captureNote,
      };

      if (editingRow?.canEditCore) {
        payload.objectiveIndicator = editForm.objectiveIndicator;
      }

      if (canManageDepartment) {
        payload.ownerUserId = editForm.ownerUserId || null;
        payload.captureMode = editForm.captureMode;
        payload.automationSource = editForm.automationSource || null;
        payload.freshnessSlaHours = Number(editForm.freshnessSlaHours) || 168;
      }

      const response = await fetch(`/api/capture/rows/${editingRowId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      const result = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(result.error ?? "No se pudo actualizar la fila.");
      }

      setEditingRowId(null);
      setEditForm(null);
      await loadBoard();
      setError(null);
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "No se pudo actualizar la fila.");
    } finally {
      setIsSaving(false);
    }
  };

  const submitEvidence = async () => {
    if (!selectedDepartment || !board) {
      return;
    }

    if (!evidenceTitle.trim()) {
      setError("Título de evidencia es obligatorio.");
      return;
    }
    if (!evidenceRowId) {
      setError("Selecciona la fila KPI.");
      return;
    }

    setIsSaving(true);
    try {
      if (evidenceKind === "link") {
        const response = await fetch("/api/capture/evidence/link", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            weekStart: board.weekStart,
            department: selectedDepartment,
            rowId: evidenceRowId,
            initiativeId: evidenceInitiativeId || undefined,
            taskId: evidenceTaskId || undefined,
            title: evidenceTitle,
            note: evidenceNote || undefined,
            url: evidenceUrl,
          }),
        });
        const payload = (await response.json()) as { error?: string };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo guardar enlace.");
        }
      } else {
        if (!evidenceFile) {
          throw new Error("Selecciona archivo.");
        }

        const formData = new FormData();
        formData.set("weekStart", board.weekStart);
        formData.set("department", selectedDepartment);
        formData.set("rowId", evidenceRowId);
        formData.set("title", evidenceTitle);
        formData.set("note", evidenceNote);
        if (evidenceInitiativeId) {
          formData.set("initiativeId", evidenceInitiativeId);
        }
        if (evidenceTaskId) {
          formData.set("taskId", evidenceTaskId);
        }
        formData.set("file", evidenceFile);

        const response = await fetch("/api/capture/evidence/upload", { method: "POST", body: formData });
        const payload = (await response.json()) as { error?: string };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo subir evidencia.");
        }
      }

      setEvidenceTitle("");
      setEvidenceNote("");
      setEvidenceUrl("");
      setEvidenceFile(null);
      await loadBoard();
      setError(null);
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "No se pudo guardar evidencia.");
    } finally {
      setIsSaving(false);
    }
  };

  const deleteEvidence = async (id: string) => {
    setIsSaving(true);
    try {
      const response = await fetch(`/api/capture/evidence/${id}`, { method: "DELETE" });
      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo eliminar evidencia.");
      }
      await loadBoard();
      setError(null);
    } catch (removeError) {
      setError(removeError instanceof Error ? removeError.message : "No se pudo eliminar evidencia.");
    } finally {
      setIsSaving(false);
    }
  };

  const triggerSyncNow = async () => {
    if (!selectedDepartment || !board) {
      return;
    }

    setIsSaving(true);
    try {
      const response = await fetch(
        `/api/capture/automation/sync?department=${encodeURIComponent(selectedDepartment)}&weekStart=${encodeURIComponent(board.weekStart)}`,
        { method: "POST" }
      );
      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo ejecutar sync.");
      }
      await loadBoard();
      setError(null);
    } catch (syncError) {
      setError(syncError instanceof Error ? syncError.message : "No se pudo ejecutar sync.");
    } finally {
      setIsSaving(false);
    }
  };

  const addOwnerDepartmentKpi = async () => {
    if (role !== "owner" || !selectedDepartment || !ownerGroupTitle.trim() || !ownerKpiName.trim()) {
      setError("Owner: completa grupo y KPI para agregar.");
      return;
    }

    setIsSaving(true);
    try {
      const response = await fetch("/api/kpis/weekly", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          weekStart: board?.weekStart ?? weekStartInput,
          department: selectedDepartment,
          groupTitle: ownerGroupTitle.trim(),
          kpiName: ownerKpiName.trim(),
          objectiveIndicator: ownerKpiObjective.trim() || null,
        }),
      });
      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo agregar KPI.");
      }

      setOwnerGroupTitle("");
      setOwnerKpiName("");
      setOwnerKpiObjective("");
      setError(null);
      await loadBoard();
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "No se pudo agregar KPI.");
    } finally {
      setIsSaving(false);
    }
  };

  const clearOwnerDepartmentKpis = async () => {
    if (role !== "owner" || !selectedDepartment) {
      return;
    }

    const confirmed = window.confirm("¿Limpiar todos los KPIs de este departamento para la semana seleccionada?");
    if (!confirmed) {
      return;
    }

    setIsSaving(true);
    try {
      const params = new URLSearchParams({
        department: selectedDepartment,
      });
      if (board?.weekStart ?? weekStartInput) {
        params.set("weekStart", board?.weekStart ?? weekStartInput);
      }

      const response = await fetch(`/api/kpis/weekly?${params.toString()}`, { method: "DELETE" });
      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudieron limpiar KPIs.");
      }

      setError(null);
      await loadBoard();
    } catch (clearError) {
      setError(clearError instanceof Error ? clearError.message : "No se pudieron limpiar KPIs.");
    } finally {
      setIsSaving(false);
    }
  };

  if (status === "loading") {
    return <p className="text-body text-benell-text-soft">Cargando workspace...</p>;
  }
  if (status !== "authenticated") {
    return <p className="text-body text-benell-text-soft">Sesión requerida.</p>;
  }
  if (!canUseWorkspace || !selectedDepartment) {
    return <p className="text-body text-benell-text-soft">No tienes acceso a captura.</p>;
  }

  return (
    <div className="space-y-5">
      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
          <div>
            <p className="text-sm font-semibold uppercase tracking-wide text-benell-brown">Capture Workspace</p>
            <h1 className="mt-1 text-2xl font-semibold text-benell-text">Captura departamental</h1>
            <p className="mt-1 text-sm text-benell-text-soft">
              KPI queue, evidence feed y automation runs de {getDepartmentLabel(selectedDepartment)}.
            </p>
          </div>

          <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
            <label className="flex min-w-[180px] flex-col gap-1 text-sm text-benell-text-soft">
              Departamento
              <select
                value={selectedDepartment}
                onChange={(event) => setSelectedDepartment(normalizeDepartment(event.target.value) ?? selectedDepartment)}
                disabled={Boolean(forcedDepartment) || role !== "owner"}
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              >
                {DEPARTMENT_OPTIONS.filter((opt) => ACTIVE_CAPTURE_DEPARTMENTS.includes(opt.value)).map((opt) => (
                  <option key={opt.value} value={opt.value}>
                    {opt.label}
                  </option>
                ))}
              </select>
            </label>

            <label className="flex min-w-[180px] flex-col gap-1 text-sm text-benell-text-soft">
              Semana
              <input
                type="date"
                value={weekStartInput}
                onChange={(event) => setWeekStartInput(event.target.value)}
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              />
            </label>

            <button
              type="button"
              onClick={() => void loadBoard()}
              className="inline-flex items-center justify-center gap-2 rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm font-semibold text-benell-text"
            >
              <RefreshCcw className="size-4" aria-hidden /> Recargar
            </button>

            {canManageDepartment ? (
              <button
                type="button"
                onClick={() => void triggerSyncNow()}
                disabled={isSaving}
                className="inline-flex items-center justify-center gap-2 rounded-lg bg-benell-brown px-3 py-2 text-sm font-semibold text-white disabled:opacity-70"
              >
                <PlayCircle className="size-4" aria-hidden /> Sync now
              </button>
            ) : (
              <div className="rounded-lg border border-benell-stroke bg-benell-surface-muted px-3 py-2 text-sm text-benell-text-soft">
                Solo líder/owner puede sincronizar
              </div>
            )}
          </div>
        </div>
      </section>

      {role === "owner" ? (
        <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-2">
            <h2 className="text-base font-semibold text-benell-text">Owner tab · KPI/{selectedDepartment}/grupo/[kpi]</h2>
            <button
              type="button"
              onClick={() => void clearOwnerDepartmentKpis()}
              disabled={isSaving}
              className="rounded-lg border border-benell-red/40 bg-white px-3 py-2 text-sm font-semibold text-benell-red disabled:opacity-60"
            >
              Limpiar KPIs del departamento
            </button>
          </div>
          <div className="mt-3 grid gap-3 lg:grid-cols-3">
            <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
              Grupo / categoría
              <input
                value={ownerGroupTitle}
                onChange={(event) => setOwnerGroupTitle(event.target.value)}
                placeholder="Ej. Social media metrics"
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              />
            </label>
            <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
              KPI name
              <input
                value={ownerKpiName}
                onChange={(event) => setOwnerKpiName(event.target.value)}
                placeholder="Ej. Alcance orgánico semanal"
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              />
            </label>
            <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
              Cómo se mide (core)
              <input
                value={ownerKpiObjective}
                onChange={(event) => setOwnerKpiObjective(event.target.value)}
                placeholder="Ej. >= 1.2M impresiones"
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              />
            </label>
          </div>
          <div className="mt-3">
            <button
              type="button"
              onClick={() => void addOwnerDepartmentKpi()}
              disabled={isSaving}
              className="inline-flex items-center gap-2 rounded-lg bg-benell-brown px-4 py-2 text-sm font-semibold text-white disabled:opacity-70"
            >
              Agregar KPI al departamento
            </button>
          </div>
        </section>
      ) : null}

      <section className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
        <article className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
          <p className="text-xs uppercase tracking-wide text-benell-text-soft">Captured</p>
          <p className="mt-1 text-xl font-semibold text-benell-text">
            {board?.summary.capturedRows ?? 0}/{board?.summary.totalRows ?? 0}
          </p>
        </article>
        <article className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
          <p className="text-xs uppercase tracking-wide text-benell-text-soft">% Captured</p>
          <p className="mt-1 text-xl font-semibold text-benell-text">{board?.summary.capturePct.toFixed(1) ?? "0.0"}%</p>
        </article>
        <article className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
          <p className="text-xs uppercase tracking-wide text-benell-text-soft">Stale</p>
          <p className="mt-1 text-xl font-semibold text-benell-red">{board?.summary.staleRows ?? 0}</p>
        </article>
        <article className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
          <p className="text-xs uppercase tracking-wide text-benell-text-soft">At Risk</p>
          <p className="mt-1 text-xl font-semibold text-benell-amber">{board?.summary.atRiskRows ?? 0}</p>
        </article>
        <article className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
          <p className="text-xs uppercase tracking-wide text-benell-text-soft">Automation Errors</p>
          <p className="mt-1 text-xl font-semibold text-benell-red">{board?.summary.errorRows ?? 0}</p>
        </article>
      </section>

      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <div className="flex flex-wrap items-center gap-2">
          {([
            ["queue", "KPI Queue"],
            ["evidence", "Evidence Feed"],
            ["automation", "Automation Runs"],
          ] as Array<[CaptureWorkspaceTab, string]>).map(([value, label]) => (
            <button
              key={value}
              type="button"
              onClick={() => setTab(value)}
              className={cn(
                "rounded-full border px-3 py-1 text-xs font-semibold uppercase tracking-wide",
                tab === value ? "border-benell-brown bg-benell-brown text-white" : "border-benell-stroke bg-white text-benell-text"
              )}
            >
              {label}
            </button>
          ))}
        </div>

        <div className="mt-4 grid gap-3 lg:grid-cols-4">
          <label className="flex flex-col gap-1 text-sm text-benell-text-soft lg:col-span-2">
            Buscar
            <input
              value={query}
              onChange={(event) => setQuery(event.target.value)}
              className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
            />
          </label>
          <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
            Desde
            <input
              type="date"
              value={from}
              onChange={(event) => setFrom(event.target.value)}
              className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
            />
          </label>
          <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
            Hasta
            <input
              type="date"
              value={to}
              onChange={(event) => setTo(event.target.value)}
              className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
            />
          </label>
        </div>

        {selectedDepartment === "proyectos" ? (
          <div className="mt-3 grid gap-3 lg:grid-cols-2">
            <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
              Proyecto (filtro)
              <select
                value={filterInitiativeId}
                onChange={(event) => {
                  setFilterInitiativeId(event.target.value);
                  setFilterTaskId("");
                }}
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              >
                <option value="">Todos</option>
                {initiatives.map((initiative) => (
                  <option key={initiative.id} value={initiative.id}>
                    {initiative.name}
                  </option>
                ))}
              </select>
            </label>
            <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
              Tarea (filtro)
              <select
                value={filterTaskId}
                onChange={(event) => setFilterTaskId(event.target.value)}
                className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
              >
                <option value="">Todas</option>
                {projectFilterTasks.map((task) => (
                  <option key={task.id} value={task.id}>
                    {task.title}
                  </option>
                ))}
              </select>
            </label>
          </div>
        ) : null}

        <div className="mt-3 flex flex-wrap items-center gap-3">
          <label className="inline-flex items-center gap-2 text-sm text-benell-text-soft">
            <input type="checkbox" checked={mineOnly} onChange={(event) => setMineOnly(event.target.checked)} className="size-4 rounded border-benell-stroke" />
            Solo mis evidencias
          </label>
          <button
            type="button"
            onClick={() => void loadBoard()}
            className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm font-semibold text-benell-text"
          >
            Aplicar filtros
          </button>
        </div>
      </section>

      {error ? (
        <section className="rounded-benell border border-benell-red/40 bg-benell-red/10 p-4 text-sm text-benell-red">
          <div className="inline-flex items-center gap-2">
            <AlertTriangle className="size-4" aria-hidden />
            {error}
          </div>
        </section>
      ) : null}

      {isLoading ? <p className="text-sm text-benell-text-soft">Cargando capture data...</p> : null}

      {!isLoading && tab === "queue" ? (
        <section className="space-y-3">
          {(board?.rows ?? []).map((row) => (
            <article key={row.id} className="rounded-benell border border-benell-stroke bg-benell-surface p-4 shadow-benell">
              <div className="flex flex-wrap items-start justify-between gap-3">
                <div>
                  <div className="inline-flex flex-wrap items-center gap-2">
                    <p className="text-base font-semibold text-benell-text">{row.responsibility}</p>
                    <span className={cn("rounded-full border px-2 py-0.5 text-xs font-semibold uppercase", statusClassName(row.status))}>
                      {statusLabel(row.status)}
                    </span>
                    <span className="rounded-full border border-benell-stroke bg-benell-surface-muted px-2 py-0.5 text-xs text-benell-text-soft">
                      {row.captureMode}
                    </span>
                  </div>
                  <p className="mt-1 text-xs text-benell-text-soft">{row.sectionLabel}</p>
                </div>

                <div className="text-xs text-benell-text-soft">
                  <p>Owner: {row.ownerUserName ?? "Sin asignar"}</p>
                  <p>Last captured: {formatDateTime(row.lastCapturedAt)}</p>
                  <p>Last automation: {formatDateTime(row.lastAutomationAt)}</p>
                </div>
              </div>

              <div className="mt-3 grid gap-2 text-xs text-benell-text-soft sm:grid-cols-2 lg:grid-cols-4">
                <p>Objective: {row.objectiveIndicator ?? "-"}</p>
                <p>Quantity/Quality: {row.quantityQuality ?? "-"}</p>
                <p>Compliance: {row.compliance ?? "-"}</p>
                <p>Due: {row.dueCommitment ?? "-"}</p>
              </div>

              <div className="mt-3 flex flex-wrap gap-2">
                <button
                  type="button"
                  onClick={() => {
                    setEditingRowId(row.id);
                    setEditForm(toEditForm(row));
                  }}
                  disabled={!row.canEdit || isSaving}
                  className="rounded-lg border border-benell-stroke bg-white px-3 py-1.5 text-xs font-semibold text-benell-text disabled:opacity-60"
                >
                  {row.canEdit ? "Editar" : "Sin permiso"}
                </button>
              </div>

              {editingRowId === row.id && editForm ? (
                <div className="mt-4 grid gap-3 lg:grid-cols-2">
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                    Objective
                    {row.canEditCore ? (
                      <input
                        value={editForm.objectiveIndicator}
                        onChange={(event) => setEditForm((prev) => (prev ? { ...prev, objectiveIndicator: event.target.value } : prev))}
                        className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                      />
                    ) : (
                      <div className="rounded-lg border border-benell-stroke bg-benell-surface-muted px-3 py-2 text-sm text-benell-text-soft">
                        {editForm.objectiveIndicator || "-"} (solo owner)
                      </div>
                    )}
                  </label>
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                    Quantity / Quality
                    <input
                      value={editForm.quantityQuality}
                      onChange={(event) => setEditForm((prev) => (prev ? { ...prev, quantityQuality: event.target.value } : prev))}
                      className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                    />
                  </label>
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                    Compliance
                    <input
                      value={editForm.compliance}
                      onChange={(event) => setEditForm((prev) => (prev ? { ...prev, compliance: event.target.value } : prev))}
                      className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                    />
                  </label>
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                    Due Commitment
                    <input
                      value={editForm.dueCommitment}
                      onChange={(event) => setEditForm((prev) => (prev ? { ...prev, dueCommitment: event.target.value } : prev))}
                      className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                    />
                  </label>
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft lg:col-span-2">
                    Capture note
                    <textarea
                      value={editForm.captureNote}
                      onChange={(event) => setEditForm((prev) => (prev ? { ...prev, captureNote: event.target.value } : prev))}
                      className="min-h-[84px] rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                    />
                  </label>

                  {canManageDepartment ? (
                    <>
                      <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                        Row owner
                        <select
                          value={editForm.ownerUserId}
                          onChange={(event) => setEditForm((prev) => (prev ? { ...prev, ownerUserId: event.target.value } : prev))}
                          className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                        >
                          <option value="">Sin asignar</option>
                          {assignees.map((assignee) => (
                            <option key={assignee.id} value={assignee.id}>
                              {assignee.name}
                            </option>
                          ))}
                        </select>
                      </label>
                      <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                        Capture mode
                        <select
                          value={editForm.captureMode}
                          onChange={(event) =>
                            setEditForm((prev) =>
                              prev
                                ? { ...prev, captureMode: event.target.value as "manual" | "auto" | "hybrid" }
                                : prev
                            )
                          }
                          className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                        >
                          <option value="manual">manual</option>
                          <option value="auto">auto</option>
                          <option value="hybrid">hybrid</option>
                        </select>
                      </label>
                      <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                        Automation source
                        <input
                          value={editForm.automationSource}
                          onChange={(event) => setEditForm((prev) => (prev ? { ...prev, automationSource: event.target.value } : prev))}
                          className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                        />
                      </label>
                      <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                        Freshness SLA (h)
                        <input
                          type="number"
                          min={1}
                          max={720}
                          value={editForm.freshnessSlaHours}
                          onChange={(event) => setEditForm((prev) => (prev ? { ...prev, freshnessSlaHours: event.target.value } : prev))}
                          className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                        />
                      </label>
                    </>
                  ) : null}

                  <div className="flex flex-wrap items-center gap-2 lg:col-span-2">
                    <button
                      type="button"
                      onClick={() => void submitRowPatch()}
                      disabled={isSaving}
                      className="inline-flex items-center gap-2 rounded-lg bg-benell-brown px-3 py-2 text-sm font-semibold text-white disabled:opacity-70"
                    >
                      <CheckCircle2 className="size-4" aria-hidden /> Guardar fila
                    </button>
                    <button
                      type="button"
                      onClick={() => {
                        setEditingRowId(null);
                        setEditForm(null);
                      }}
                      className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm font-semibold text-benell-text"
                    >
                      Cancelar
                    </button>
                  </div>
                </div>
              ) : null}
            </article>
          ))}

          {board && board.rows.length === 0 ? <p className="text-sm text-benell-text-soft">No hay filas KPI para esta semana.</p> : null}
        </section>
      ) : null}

      {!isLoading && tab === "evidence" ? (
        <section className="grid gap-5 xl:grid-cols-2">
          <article className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
            <h2 className="text-base font-semibold text-benell-text">Nueva evidencia</h2>
            <div className="mt-3 space-y-3">
              <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                KPI row
                <select
                  value={evidenceRowId}
                  onChange={(event) => setEvidenceRowId(event.target.value)}
                  className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                >
                  <option value="">Seleccionar</option>
                  {(board?.rows ?? []).map((row) => (
                    <option key={row.id} value={row.id}>
                      {row.responsibility}
                    </option>
                  ))}
                </select>
              </label>

              {selectedDepartment === "proyectos" ? (
                <div className="grid gap-3 sm:grid-cols-2">
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                    Proyecto
                    <select
                      value={evidenceInitiativeId}
                      onChange={(event) => {
                        setEvidenceInitiativeId(event.target.value);
                        setEvidenceTaskId("");
                      }}
                      className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                    >
                      <option value="">Sin proyecto</option>
                      {initiatives.map((initiative) => (
                        <option key={initiative.id} value={initiative.id}>
                          {initiative.name}
                        </option>
                      ))}
                    </select>
                  </label>
                  <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                    Tarea
                    <select
                      value={evidenceTaskId}
                      onChange={(event) => setEvidenceTaskId(event.target.value)}
                      className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                    >
                      <option value="">Sin tarea</option>
                      {evidenceTasks.map((task) => (
                        <option key={task.id} value={task.id}>
                          {task.title}
                        </option>
                      ))}
                    </select>
                  </label>
                </div>
              ) : null}

              <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                Tipo
                <select
                  value={evidenceKind}
                  onChange={(event) => setEvidenceKind(event.target.value as "link" | "photo" | "document")}
                  className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                >
                  <option value="link">link</option>
                  <option value="photo">photo</option>
                  <option value="document">document</option>
                </select>
              </label>

              <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                Título
                <input
                  value={evidenceTitle}
                  onChange={(event) => setEvidenceTitle(event.target.value)}
                  className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                />
              </label>

              <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                Nota
                <textarea
                  value={evidenceNote}
                  onChange={(event) => setEvidenceNote(event.target.value)}
                  className="min-h-[84px] rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                />
              </label>

              {evidenceKind === "link" ? (
                <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                  URL
                  <input
                    value={evidenceUrl}
                    onChange={(event) => setEvidenceUrl(event.target.value)}
                    className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                  />
                </label>
              ) : (
                <label className="flex flex-col gap-1 text-sm text-benell-text-soft">
                  Archivo (jpg/png/webp/pdf, max 10MB)
                  <input
                    type="file"
                    accept="image/jpeg,image/png,image/webp,application/pdf"
                    onChange={(event) => setEvidenceFile(event.target.files?.[0] ?? null)}
                    className="rounded-lg border border-benell-stroke bg-white px-3 py-2 text-sm text-benell-text"
                  />
                </label>
              )}

              <button
                type="button"
                onClick={() => void submitEvidence()}
                disabled={isSaving}
                className="inline-flex items-center gap-2 rounded-lg bg-benell-brown px-4 py-2 text-sm font-semibold text-white disabled:opacity-70"
              >
                {evidenceKind === "link" ? <Link2 className="size-4" aria-hidden /> : <UploadCloud className="size-4" aria-hidden />}
                Guardar evidencia
              </button>
            </div>
          </article>

          <article className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
            <h2 className="text-base font-semibold text-benell-text">Evidence feed</h2>
            <p className="mt-1 text-sm text-benell-text-soft">{board?.evidence.length ?? 0} elementos</p>

            <div className="mt-3 space-y-2">
              {(board?.evidence ?? []).map((item: CaptureEvidenceDTO) => {
                const canDelete = canManageDepartment || item.uploadedById === session?.user.id;

                return (
                  <article key={item.id} className="rounded-lg border border-benell-stroke bg-white px-3 py-2">
                    <div className="flex flex-wrap items-start justify-between gap-2">
                      <div>
                        <p className="text-sm font-semibold text-benell-text">{item.title}</p>
                        <p className="text-xs text-benell-text-soft">{item.note || "Sin nota"}</p>
                      </div>
                      {canDelete ? (
                        <button
                          type="button"
                          onClick={() => void deleteEvidence(item.id)}
                          disabled={isSaving}
                          className="inline-flex items-center gap-1 rounded-md border border-benell-red/30 bg-benell-red/10 px-2 py-1 text-xs font-semibold text-benell-red disabled:opacity-60"
                        >
                          <Trash2 className="size-3" aria-hidden /> Eliminar
                        </button>
                      ) : null}
                    </div>

                    <div className="mt-2 flex flex-wrap items-center gap-3 text-xs text-benell-text-soft">
                      <span>Uploader: {item.uploaderName}</span>
                      <span>Fecha: {formatDateTime(item.createdAt)}</span>
                      <span>KPI: {item.rowKey}</span>
                      {item.initiativeName ? <span>Proyecto: {item.initiativeName}</span> : null}
                      {item.taskTitle ? <span>Tarea: {item.taskTitle}</span> : null}
                    </div>

                    <div className="mt-2 flex flex-wrap items-center gap-2">
                      <span className="inline-flex rounded-full border border-benell-stroke bg-benell-surface-muted px-2 py-0.5 text-xs text-benell-text">
                        {item.kind}
                      </span>
                      {item.url ? (
                        <a
                          href={item.url}
                          target="_blank"
                          rel="noreferrer"
                          className="inline-flex items-center gap-1 rounded-full border border-benell-stroke bg-white px-2 py-0.5 text-xs font-semibold text-benell-brown hover:underline"
                        >
                          <Link2 className="size-3" aria-hidden /> Link
                        </a>
                      ) : null}
                      {item.hasFile ? (
                        <a
                          href={`/api/capture/evidence/assets/${item.id}`}
                          target="_blank"
                          rel="noreferrer"
                          className="inline-flex items-center gap-1 rounded-full border border-benell-stroke bg-white px-2 py-0.5 text-xs font-semibold text-benell-brown hover:underline"
                        >
                          <UploadCloud className="size-3" aria-hidden /> Abrir archivo
                        </a>
                      ) : null}
                    </div>
                  </article>
                );
              })}

              {board && board.evidence.length === 0 ? <p className="text-sm text-benell-text-soft">No hay evidencia para el filtro actual.</p> : null}
            </div>
          </article>
        </section>
      ) : null}

      {!isLoading && tab === "automation" ? (
        <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
          <h2 className="text-base font-semibold text-benell-text">Automation run history</h2>
          <div className="mt-3 space-y-2">
            {(board?.automationRuns ?? []).map((run) => (
              <article key={run.id} className="rounded-lg border border-benell-stroke bg-white px-3 py-2">
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <div>
                    <p className="text-sm font-semibold text-benell-text">{run.source}</p>
                    <p className="text-xs text-benell-text-soft">Inició: {formatDateTime(run.startedAt)}</p>
                  </div>
                  <span
                    className={cn(
                      "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-semibold uppercase",
                      run.status === "success" && "border-benell-green/30 bg-benell-green/15 text-benell-green",
                      run.status === "failed" && "border-benell-red/40 bg-benell-red/15 text-benell-red",
                      run.status === "running" && "border-benell-amber/40 bg-benell-amber/15 text-benell-amber",
                      run.status === "queued" && "border-benell-stroke bg-benell-surface-muted text-benell-text-soft"
                    )}
                  >
                    {run.status === "success" ? <CheckCircle2 className="size-3" aria-hidden /> : null}
                    {run.status === "failed" ? <AlertTriangle className="size-3" aria-hidden /> : null}
                    {run.status === "running" ? <Clock3 className="size-3" aria-hidden /> : null}
                    {run.status}
                  </span>
                </div>
                <div className="mt-2 flex flex-wrap items-center gap-3 text-xs text-benell-text-soft">
                  <span>Rows touched: {run.rowsTouched}</span>
                  <span>Triggered by: {run.triggeredByName ?? "system"}</span>
                  <span>Completed: {formatDateTime(run.completedAt)}</span>
                  {run.errorMessage ? <span className="text-benell-red">Error: {run.errorMessage}</span> : null}
                </div>
              </article>
            ))}

            {board && board.automationRuns.length === 0 ? (
              <p className="text-sm text-benell-text-soft">Sin ejecuciones registradas para la semana actual.</p>
            ) : null}
          </div>
        </section>
      ) : null}
    </div>
  );
}
