"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  ListTodo, Plus, Pencil, Trash2, Loader2, Search, RefreshCw, X, Check, Clock, Link2,
} from "lucide-react";
import Button from "@/components/ui/Button";
import { cn } from "@/lib/cn";
import {
  listTareas, createTarea, updateTarea, toggleTareaEstado, deleteTarea, listAssignableUsers,
  type TareaFilters,
} from "@/lib/pb/tareas";
import { listPedidos } from "@/lib/pb/pedidos";
import {
  TIPO_TAREA_LABELS, PRIORIDAD_TAREA_LABELS, tareaAlerta,
  type Tarea, type TipoTarea, type EstadoTarea, type PrioridadTarea,
} from "@/lib/types/tarea";
import type { Pedido } from "@/lib/types/pedido";
import { useNavAlerts } from "@/lib/store/useNavAlerts";

const TIPOS = Object.keys(TIPO_TAREA_LABELS) as TipoTarea[];

const TIPO_COLOR: Record<TipoTarea, string> = {
  medir: "bg-violet-100 text-violet-800 border-violet-200",
  comprar: "bg-amber-100 text-amber-800 border-amber-200",
  cortar: "bg-orange-100 text-orange-800 border-orange-200",
  armar: "bg-sky-100 text-sky-800 border-sky-200",
  instalar: "bg-red-100 text-red-800 border-red-200",
  entregar: "bg-emerald-100 text-emerald-800 border-emerald-200",
  llamar: "bg-blue-100 text-blue-800 border-blue-200",
  otra: "bg-canvas text-ink-soft border-line",
};

interface Draft {
  id?: string;
  titulo: string;
  tipo: TipoTarea;
  fecha: string;
  hora: string;
  prioridad: PrioridadTarea;
  asignado_a: string;
  pedido: string;
  pedidoLabel: string;
  descripcion: string;
}

function emptyDraft(): Draft {
  return { titulo: "", tipo: "medir", fecha: "", hora: "", prioridad: "media", asignado_a: "", pedido: "", pedidoLabel: "", descripcion: "" };
}

function pedidoLabel(p: Pedido): string {
  const code = p.codigo || (p.numero ? `#${p.numero}` : "Pedido");
  return `${code} — ${p.expand?.cliente?.nombre || "Cliente"}`;
}

export default function TareasPage() {
  const refreshAlerts = useNavAlerts((s) => s.refresh);
  const [tareas, setTareas] = useState<Tarea[]>([]);
  const [users, setUsers] = useState<Array<{ id: string; name: string }>>([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState("");
  const [estado, setEstado] = useState<EstadoTarea | "todos">("pendiente");
  const [tipo, setTipo] = useState("");
  const [search, setSearch] = useState("");
  const [modal, setModal] = useState<Draft | null>(null);
  const [busyId, setBusyId] = useState("");
  const [confirmDel, setConfirmDel] = useState<Tarea | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setErr("");
    try {
      const filters: TareaFilters = { estado, tipo: tipo || undefined, search: search || undefined };
      setTareas(await listTareas(filters));
    } catch (e) {
      setErr((e as Error).message || "No se pudieron cargar las tareas");
    } finally {
      setLoading(false);
    }
  }, [estado, tipo, search]);

  useEffect(() => { load(); }, [load]);
  useEffect(() => { listAssignableUsers().then(setUsers).catch(() => {}); }, []);

  const { pendientes, hechas } = useMemo(() => {
    return {
      pendientes: tareas.filter((t) => t.estado !== "hecha"),
      hechas: tareas.filter((t) => t.estado === "hecha"),
    };
  }, [tareas]);

  async function refreshAll() {
    await load();
    refreshAlerts(true);
  }

  async function toggle(t: Tarea) {
    setBusyId(t.id);
    try {
      await toggleTareaEstado(t);
      await refreshAll();
    } finally {
      setBusyId("");
    }
  }

  async function save() {
    if (!modal || !modal.titulo.trim()) return;
    setBusyId("save");
    try {
      const payload = {
        titulo: modal.titulo.trim(),
        tipo: modal.tipo,
        fecha: modal.fecha || undefined,
        hora: modal.hora || undefined,
        prioridad: modal.prioridad,
        asignado_a: modal.asignado_a || undefined,
        pedido: modal.pedido || undefined,
        descripcion: modal.descripcion || undefined,
      };
      if (modal.id) await updateTarea(modal.id, payload);
      else await createTarea(payload);
      setModal(null);
      await refreshAll();
    } catch (e) {
      setErr((e as Error).message || "No se pudo guardar la tarea");
    } finally {
      setBusyId("");
    }
  }

  async function remove(t: Tarea) {
    setBusyId(t.id);
    try {
      await deleteTarea(t.id);
      setConfirmDel(null);
      await refreshAll();
    } finally {
      setBusyId("");
    }
  }

  function openEdit(t: Tarea) {
    setModal({
      id: t.id,
      titulo: t.titulo,
      tipo: t.tipo,
      fecha: (t.fecha || "").slice(0, 10),
      hora: t.hora || "",
      prioridad: t.prioridad || "media",
      asignado_a: t.asignado_a || "",
      pedido: t.pedido || "",
      pedidoLabel: t.expand?.pedido ? pedidoLabel(t.expand.pedido as Pedido) : "",
      descripcion: t.descripcion || "",
    });
  }

  return (
    <div className="max-w-5xl space-y-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="flex items-center gap-2 text-2xl font-extrabold text-ink">
            <ListTodo className="h-6 w-6 text-brand-dark" /> Tareas
          </h1>
          <p className="text-sm text-ink-soft">Medir, comprar, instalar y más. Con fecha, hora y vínculo a pedidos.</p>
        </div>
        <div className="flex items-center gap-2">
          <button onClick={load} title="Actualizar"
            className="inline-flex h-10 w-10 items-center justify-center rounded-lg border border-line bg-surface text-faint hover:text-ink">
            <RefreshCw size={16} className={loading ? "animate-spin" : ""} />
          </button>
          <Button type="button" onClick={() => setModal(emptyDraft())}>
            <Plus size={16} /> Nueva tarea
          </Button>
        </div>
      </div>

      {/* Filtros */}
      <div className="flex flex-wrap items-center gap-2">
        <div className="inline-flex rounded-lg border border-line bg-surface p-0.5">
          {(["pendiente", "hecha", "todos"] as const).map((v) => (
            <button key={v} onClick={() => setEstado(v)}
              className={cn("h-8 rounded-md px-3 text-xs font-semibold capitalize",
                estado === v ? "bg-brand-soft text-brand-dark" : "text-faint hover:text-ink")}>
              {v === "todos" ? "Todas" : v === "pendiente" ? "Pendientes" : "Hechas"}
            </button>
          ))}
        </div>
        <select value={tipo} onChange={(e) => setTipo(e.target.value)}
          className="h-9 rounded-lg border border-line bg-surface px-2 text-sm text-ink outline-none focus:border-brand">
          <option value="">Todos los tipos</option>
          {TIPOS.map((t) => <option key={t} value={t}>{TIPO_TAREA_LABELS[t]}</option>)}
        </select>
        <label className="relative">
          <Search size={14} className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-faint" />
          <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Buscar"
            className="h-9 w-44 rounded-lg border border-line bg-surface pl-8 pr-3 text-sm text-ink outline-none focus:border-brand" />
        </label>
      </div>

      {err && <div className="rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-bad">{err}</div>}

      {loading ? (
        <div className="grid place-items-center py-20 text-faint"><Loader2 className="h-6 w-6 animate-spin" /></div>
      ) : tareas.length === 0 ? (
        <div className="grid place-items-center rounded-lg border border-dashed border-line bg-surface px-4 py-12 text-center">
          <div>
            <ListTodo className="mx-auto mb-2 h-8 w-8 text-faint opacity-40" />
            <p className="text-sm text-faint">No hay tareas para este filtro.</p>
          </div>
        </div>
      ) : (
        <div className="space-y-5">
          {estado !== "hecha" && pendientes.length > 0 && (
            <div className="space-y-2">
              {estado === "todos" && (
                <h2 className="text-sm font-extrabold text-ink-soft">PENDIENTES ({pendientes.length})</h2>
              )}
              {pendientes.map((t) => (
                <TareaRow key={t.id} t={t} busy={busyId === t.id} onToggle={toggle} onEdit={openEdit} onDelete={setConfirmDel} />
              ))}
            </div>
          )}
          {estado !== "pendiente" && hechas.length > 0 && (
            <div className="space-y-2">
              <h2 className="text-sm font-extrabold text-faint">HECHAS ({hechas.length})</h2>
              {hechas.map((t) => (
                <TareaRow key={t.id} t={t} busy={busyId === t.id} onToggle={toggle} onEdit={openEdit} onDelete={setConfirmDel} />
              ))}
            </div>
          )}
        </div>
      )}

      {modal && (
        <TareaModal
          draft={modal}
          users={users}
          busy={busyId === "save"}
          onChange={setModal}
          onClose={() => setModal(null)}
          onSave={save}
        />
      )}

      {confirmDel && (
        <div className="fixed inset-0 z-50 grid place-items-center bg-black/40 p-4" onClick={() => setConfirmDel(null)}>
          <div className="w-full max-w-sm rounded-2xl border border-line bg-surface p-5" onClick={(e) => e.stopPropagation()}>
            <h3 className="font-extrabold text-ink">Borrar tarea</h3>
            <p className="mt-1 text-sm text-ink-soft">&ldquo;{confirmDel.titulo}&rdquo;</p>
            <div className="mt-4 flex justify-end gap-2">
              <Button type="button" variant="ghost" onClick={() => setConfirmDel(null)}>Cancelar</Button>
              <Button type="button" variant="danger" loading={busyId === confirmDel.id} onClick={() => remove(confirmDel)}>Borrar</Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function TareaRow({ t, busy, onToggle, onEdit, onDelete }: {
  t: Tarea;
  busy: boolean;
  onToggle: (t: Tarea) => void;
  onEdit: (t: Tarea) => void;
  onDelete: (t: Tarea) => void;
}) {
  const done = t.estado === "hecha";
  const alerta = tareaAlerta(t);
  const fechaTxt = t.fecha
    ? new Date(t.fecha.slice(0, 10) + "T12:00:00").toLocaleDateString("es-AR", { day: "numeric", month: "short" })
    : "Sin fecha";
  return (
    <div className={cn("flex items-center gap-3 rounded-xl border bg-surface px-3 py-2.5",
      done ? "border-line opacity-60" : alerta === "vencida" ? "border-red-200 bg-red-50/40" : "border-line")}>
      <button onClick={() => onToggle(t)} disabled={busy} title={done ? "Marcar pendiente" : "Marcar hecha"}
        className={cn("grid h-7 w-7 shrink-0 place-items-center rounded-md border text-xs font-bold",
          done ? "border-brand bg-brand text-white" : "border-line bg-canvas text-faint hover:text-ink")}>
        {busy ? <Loader2 size={14} className="animate-spin" /> : done ? <Check size={15} /> : ""}
      </button>
      <div className="min-w-0 flex-1">
        <div className="flex flex-wrap items-center gap-1.5">
          <span className={cn("font-semibold text-ink", done && "line-through")}>{t.titulo}</span>
          <span className={cn("rounded-full border px-1.5 py-0.5 text-[10px] font-bold", TIPO_COLOR[t.tipo])}>
            {TIPO_TAREA_LABELS[t.tipo]}
          </span>
          {t.prioridad === "alta" && !done && (
            <span className="rounded-full border border-red-200 bg-red-100 px-1.5 py-0.5 text-[10px] font-bold text-red-800">Alta</span>
          )}
        </div>
        <div className="mt-0.5 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-faint">
          <span className={cn(alerta === "vencida" && "font-bold text-bad", alerta === "hoy" && "font-bold text-orange-600")}>
            {fechaTxt}{t.hora ? ` · ${t.hora}` : ""}{alerta === "hoy" ? " · hoy" : alerta === "vencida" ? " · vencida" : ""}
          </span>
          {t.expand?.asignado_a?.name && <span>{t.expand.asignado_a.name}</span>}
          {t.pedido && (
            <Link href={`/pedidos/${t.pedido}`} className="inline-flex items-center gap-1 font-semibold text-brand-dark hover:underline">
              <Link2 size={12} /> {t.expand?.pedido?.codigo || t.expand?.pedido?.expand?.cliente?.nombre || "Pedido"}
            </Link>
          )}
        </div>
      </div>
      <button onClick={() => onEdit(t)} title="Editar"
        className="inline-flex h-8 w-8 items-center justify-center rounded-lg text-faint hover:text-ink">
        <Pencil size={14} />
      </button>
      <button onClick={() => onDelete(t)} title="Borrar"
        className="inline-flex h-8 w-8 items-center justify-center rounded-lg text-faint hover:bg-red-50 hover:text-bad">
        <Trash2 size={14} />
      </button>
    </div>
  );
}

function TareaModal({ draft, users, busy, onChange, onClose, onSave }: {
  draft: Draft;
  users: Array<{ id: string; name: string }>;
  busy: boolean;
  onChange: (d: Draft) => void;
  onClose: () => void;
  onSave: () => void;
}) {
  const [pedQuery, setPedQuery] = useState("");
  const [pedResults, setPedResults] = useState<Pedido[]>([]);
  const [pedSearching, setPedSearching] = useState(false);
  const set = (patch: Partial<Draft>) => onChange({ ...draft, ...patch });

  useEffect(() => {
    if (!pedQuery.trim()) { setPedResults([]); return; }
    const t = setTimeout(async () => {
      setPedSearching(true);
      try {
        const res = await listPedidos({ search: pedQuery, perPage: 8 });
        setPedResults(res.items);
      } finally {
        setPedSearching(false);
      }
    }, 350);
    return () => clearTimeout(t);
  }, [pedQuery]);

  const field = "h-10 w-full rounded-lg border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand";

  return (
    <div className="fixed inset-0 z-50 grid place-items-center bg-black/40 p-4 overflow-y-auto" onClick={onClose}>
      <div className="my-8 w-full max-w-lg rounded-2xl border border-line bg-surface p-5 shadow-[var(--shadow-lg)]" onClick={(e) => e.stopPropagation()}>
        <div className="mb-4 flex items-center justify-between">
          <h2 className="font-extrabold text-ink">{draft.id ? "Editar tarea" : "Nueva tarea"}</h2>
          <button onClick={onClose} className="rounded-lg p-1 text-faint hover:text-ink"><X size={18} /></button>
        </div>

        <div className="space-y-3">
          <div>
            <label className="text-sm font-medium text-ink-soft">Título</label>
            <input autoFocus value={draft.titulo} onChange={(e) => set({ titulo: e.target.value })}
              placeholder="Ej: Ir a medir la cocina" className={field} />
          </div>

          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="text-sm font-medium text-ink-soft">Tipo</label>
              <select value={draft.tipo} onChange={(e) => set({ tipo: e.target.value as TipoTarea })} className={field}>
                {TIPOS.map((t) => <option key={t} value={t}>{TIPO_TAREA_LABELS[t]}</option>)}
              </select>
            </div>
            <div>
              <label className="text-sm font-medium text-ink-soft">Prioridad</label>
              <select value={draft.prioridad} onChange={(e) => set({ prioridad: e.target.value as PrioridadTarea })} className={field}>
                {(Object.keys(PRIORIDAD_TAREA_LABELS) as PrioridadTarea[]).map((p) => (
                  <option key={p} value={p}>{PRIORIDAD_TAREA_LABELS[p]}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="text-sm font-medium text-ink-soft">Fecha</label>
              <input type="date" value={draft.fecha} onChange={(e) => set({ fecha: e.target.value })} className={field} />
            </div>
            <div>
              <label className="flex items-center gap-1 text-sm font-medium text-ink-soft"><Clock size={13} /> Hora</label>
              <input type="time" value={draft.hora} onChange={(e) => set({ hora: e.target.value })} className={field} />
            </div>
          </div>

          {users.length > 0 && (
            <div>
              <label className="text-sm font-medium text-ink-soft">Asignar a</label>
              <select value={draft.asignado_a} onChange={(e) => set({ asignado_a: e.target.value })} className={field}>
                <option value="">Sin asignar (taller)</option>
                {users.map((u) => <option key={u.id} value={u.id}>{u.name}</option>)}
              </select>
            </div>
          )}

          <div>
            <label className="text-sm font-medium text-ink-soft">Pedido vinculado (opcional)</label>
            {draft.pedido ? (
              <div className="flex items-center justify-between gap-2 rounded-lg border border-brand-soft bg-brand-soft/40 px-3 py-2 text-sm">
                <span className="truncate font-semibold text-brand-dark">{draft.pedidoLabel || "Pedido vinculado"}</span>
                <button onClick={() => set({ pedido: "", pedidoLabel: "" })} className="text-faint hover:text-bad"><X size={15} /></button>
              </div>
            ) : (
              <div className="relative">
                <input value={pedQuery} onChange={(e) => setPedQuery(e.target.value)}
                  placeholder="Buscar pedido por código o cliente" className={field} />
                {pedSearching && <Loader2 size={14} className="absolute right-3 top-1/2 -translate-y-1/2 animate-spin text-faint" />}
                {pedResults.length > 0 && (
                  <div className="absolute z-10 mt-1 max-h-52 w-full overflow-y-auto rounded-lg border border-line bg-surface shadow-lg">
                    {pedResults.map((p) => (
                      <button key={p.id} type="button"
                        onClick={() => { set({ pedido: p.id, pedidoLabel: pedidoLabel(p) }); setPedQuery(""); setPedResults([]); }}
                        className="block w-full px-3 py-2 text-left text-sm text-ink hover:bg-canvas">
                        {pedidoLabel(p)}
                      </button>
                    ))}
                  </div>
                )}
              </div>
            )}
          </div>

          <div>
            <label className="text-sm font-medium text-ink-soft">Notas</label>
            <textarea value={draft.descripcion} onChange={(e) => set({ descripcion: e.target.value })} rows={2}
              placeholder="Detalle opcional" className={cn(field, "h-auto py-2 resize-y")} />
          </div>
        </div>

        <div className="mt-5 flex justify-end gap-2">
          <Button type="button" variant="ghost" onClick={onClose}>Cancelar</Button>
          <Button type="button" loading={busy} disabled={!draft.titulo.trim()} onClick={onSave}>
            {draft.id ? "Guardar" : "Crear tarea"}
          </Button>
        </div>
      </div>
    </div>
  );
}
