"use client";

import { useEffect, useState, useCallback } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import { Search, Users, Phone, MapPin, Pencil, Trash2, Save, X, Plus, Handshake, FileText, ClipboardList } from "lucide-react";
import { motion } from "framer-motion";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import { getPB } from "@/lib/pocketbase";
import { createCliente, listPedidos } from "@/lib/pb/pedidos";
import { listCrmOportunidades } from "@/lib/pb/crm";
import { listPresupuestos } from "@/lib/pb/presupuestos";
import type { Cliente, Pedido } from "@/lib/types/pedido";
import type { CrmOportunidad } from "@/lib/types/crm";
import type { Presupuesto } from "@/lib/types/presupuesto";

type ClienteDraft = {
  nombre: string;
  celular: string;
  direccion: string;
  notas: string;
  tipo_cliente: "persona" | "empresa";
  documento_tipo: "dni" | "cuil" | "cuit";
  documento_numero: string;
  razon_social: string;
  contacto_nombre: string;
  contacto_celular: string;
};

const EMPTY_DRAFT: ClienteDraft = {
  nombre: "",
  celular: "",
  direccion: "",
  notas: "",
  tipo_cliente: "persona",
  documento_tipo: "dni",
  documento_numero: "",
  razon_social: "",
  contacto_nombre: "",
  contacto_celular: "",
};

export default function ClientesPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [clientes, setClientes] = useState<Cliente[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [selected, setSelected] = useState<Cliente | null>(null);
  const [creating, setCreating] = useState(false);
  const [draft, setDraft] = useState<ClienteDraft>(EMPTY_DRAFT);
  const [related, setRelated] = useState<{ crm: CrmOportunidad[]; presupuestos: Presupuesto[]; pedidos: Pedido[] }>({
    crm: [],
    presupuestos: [],
    pedidos: [],
  });
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState("");

  const reload = useCallback(async () => {
    setLoading(true);
    try {
      setErr("");
      let filter = "";
      if (search.trim()) {
        const clean = search.trim().replace(/"/g, "");
        const digits = clean.replace(/\D/g, "");
        const conditions = [
          `nombre ~ "${clean}"`,
          `razon_social ~ "${clean}"`,
          `contacto_nombre ~ "${clean}"`
        ];
        if (digits) {
          conditions.push(`celular ~ "${digits}"`);
          conditions.push(`contacto_celular ~ "${digits}"`);
        }
        filter = conditions.join(" || ");
      }
      const res = await getPB().collection("clientes").getList<Cliente>(1, 500, {
        filter,
        sort: "nombre",
      });
      setClientes(res.items);
    } catch (e) {
      setErr((e as Error).message || "No se pudieron cargar clientes");
    } finally {
      setLoading(false);
    }
  }, [search]);

  useEffect(() => {
    const t = setTimeout(reload, search ? 250 : 0);
    return () => clearTimeout(t);
  }, [reload, search]);

  useEffect(() => {
    const clienteId = searchParams.get("cliente");
    const esNuevo = searchParams.get("nuevo") === "1";

    if (esNuevo) {
      if (!creating) {
        setCreating(true);
        setSelected(null);
        setDraft(EMPTY_DRAFT);
      }
      return;
    }

    if (!clienteId) {
      if (selected || creating) {
        setSelected(null);
        setCreating(false);
        setRelated({ crm: [], presupuestos: [], pedidos: [] });
      }
      return;
    }

    if (selected?.id === clienteId) return;

    const match = clientes.find((item) => item.id === clienteId);
    if (match) {
      hydrateCliente(match);
      return;
    }
    getPB().collection("clientes").getOne<Cliente>(clienteId)
      .then(hydrateCliente)
      .catch(() => setErr("No se pudo abrir la ficha del cliente."));
  }, [clientes, searchParams, selected?.id, creating]);

  function hydrateCliente(cliente: Cliente) {
    setSelected(cliente);
    setCreating(false);
    setDraft({
      nombre: cliente.nombre || "",
      celular: cliente.celular || "",
      direccion: cliente.direccion || "",
      notas: cliente.notas || "",
      tipo_cliente: cliente.tipo_cliente || "persona",
      documento_tipo: cliente.documento_tipo || "dni",
      documento_numero: cliente.documento_numero || "",
      razon_social: cliente.razon_social || "",
      contacto_nombre: cliente.contacto_nombre || "",
      contacto_celular: cliente.contacto_celular || "",
    });
  }

  function openCliente(cliente: Cliente) {
    router.replace(`/clientes?cliente=${cliente.id}`, { scroll: false });
  }

  function newCliente() {
    router.replace("/clientes?nuevo=1", { scroll: false });
  }

  function closeCliente() {
    router.replace("/clientes", { scroll: false });
  }

  async function saveCliente() {
    if (!draft.nombre.trim()) return;
    setSaving(true);
    setErr("");
    try {
      const payload = {
        nombre: draft.nombre.trim(),
        celular: draft.celular.trim(),
        direccion: draft.direccion.trim(),
        notas: draft.notas,
        tipo_cliente: draft.tipo_cliente,
        documento_tipo: draft.documento_tipo,
        documento_numero: draft.documento_numero.trim(),
        razon_social: draft.razon_social.trim(),
        contacto_nombre: draft.contacto_nombre.trim(),
        contacto_celular: draft.contacto_celular.trim(),
      };
      const updated = selected
        ? await getPB().collection("clientes").update<Cliente>(selected.id, payload)
        : await createCliente(payload);
      setClientes((prev) => selected ? prev.map((item) => (item.id === updated.id ? updated : item)) : [updated, ...prev]);
      setSelected(updated);
      setCreating(false);
      router.replace(`/clientes?cliente=${updated.id}`, { scroll: false });
    } catch (e) {
      setErr((e as Error).message || "No se pudo guardar cliente");
    } finally {
      setSaving(false);
    }
  }

  useEffect(() => {
    if (!selected) return;
    (async () => {
      const [crmRes, presupuestosRes, pedidosRes] = await Promise.all([
        listCrmOportunidades({ cliente: selected.id, estado: "todos", perPage: 20 }).catch(() => ({ items: [] })),
        listPresupuestos({ cliente: selected.id, perPage: 20 }).catch(() => ({ items: [] })),
        listPedidos({ cliente: selected.id, perPage: 20 }).catch(() => ({ items: [] })),
      ]);
      setRelated({ crm: crmRes.items, presupuestos: presupuestosRes.items, pedidos: pedidosRes.items });
    })();
  }, [selected]);

  async function deleteCliente() {
    if (!selected) return;
    if (!confirm(`¿Borrar cliente ${selected.nombre}?`)) return;
    setSaving(true);
    setErr("");
    try {
      await getPB().collection("clientes").delete(selected.id);
      setClientes((prev) => prev.filter((item) => item.id !== selected.id));
      closeCliente();
    } catch (e) {
      setErr((e as Error).message || "No se pudo borrar. Puede tener pedidos asociados.");
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="max-w-5xl">
      <div className="mb-6 flex items-center justify-between gap-4">
        <div>
          <h1 className="text-2xl font-extrabold text-ink">Clientes</h1>
          <p className="text-sm text-ink-soft mt-0.5">
            Se cargan automáticamente al crear pedidos.
          </p>
        </div>
        <Button type="button" onClick={newCliente}>
          <Plus size={16} /> Nuevo cliente
        </Button>
      </div>

      <div className="card p-4 mb-4">
        <Input
          placeholder="Buscar por nombre o celular"
          prefix={<Search size={16} />}
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
      </div>

      <div className="card overflow-hidden">
        {err && <div className="border-b border-line bg-red-50 px-4 py-2 text-sm text-bad">{err}</div>}
        {loading ? (
          <div className="p-10 text-center text-faint text-sm">Cargando…</div>
        ) : clientes.length === 0 ? (
          <div className="p-12 text-center">
            <Users size={32} className="mx-auto text-faint mb-2" />
            <p className="text-ink-soft">
              {search ? "Ningún cliente coincide." : "Sin clientes todavía."}
            </p>
          </div>
        ) : (
          <ul className="divide-y divide-line">
            {clientes.map((c, i) => (
              <motion.li
                key={c.id}
                initial={{ opacity: 0, y: 4 }}
                animate={{ opacity: 1, y: 0 }}
                transition={{ delay: i * 0.02 }}
                className="px-5 py-3 flex items-center gap-4 hover:bg-canvas/50"
              >
                <div className="w-10 h-10 rounded-full bg-brand-soft text-brand-dark grid place-items-center font-bold">
                  {c.nombre.slice(0, 1).toUpperCase()}
                </div>
                <div className="flex-1 min-w-0">
                  <p className="font-semibold text-ink truncate">{c.nombre}</p>
                  <div className="text-xs text-ink-soft flex items-center gap-3 mt-0.5">
                    {c.celular && (
                      <span className="flex items-center gap-1">
                        <Phone size={11} /> {c.celular}
                      </span>
                    )}
                    {c.direccion && (
                      <span className="flex items-center gap-1 truncate">
                        <MapPin size={11} /> {c.direccion}
                      </span>
                    )}
                  </div>
                </div>
                <button
                  type="button"
                  onClick={() => openCliente(c)}
                  className="inline-flex h-8 w-8 items-center justify-center rounded-lg border border-line text-faint hover:text-ink"
                  title="Abrir ficha"
                >
                  <Pencil size={14} />
                </button>
              </motion.li>
            ))}
          </ul>
        )}
      </div>

      {(selected || creating) && (
        <div className="fixed inset-0 z-40 grid place-items-center bg-black/35 p-4" onClick={closeCliente}>
          <div className="max-h-[92dvh] w-full max-w-2xl overflow-auto rounded-xl border border-line bg-surface p-5 shadow-[var(--shadow-lg)]" onClick={(e) => e.stopPropagation()}>
            <div className="mb-4 flex items-center justify-between gap-3">
              <h2 className="text-lg font-extrabold text-ink">{creating ? "Nuevo cliente" : "Ficha cliente"}</h2>
              <button type="button" onClick={closeCliente} className="rounded-lg p-1.5 text-faint hover:text-ink">
                <X size={18} />
              </button>
            </div>
            <div className="grid gap-3">
              <Input label="Nombre" value={draft.nombre} onChange={(e) => setDraft((d) => ({ ...d, nombre: e.target.value }))} />
              <Input label="Celular" value={draft.celular} onChange={(e) => setDraft((d) => ({ ...d, celular: e.target.value }))} />
              <Input label="Direccion" value={draft.direccion} onChange={(e) => setDraft((d) => ({ ...d, direccion: e.target.value }))} />
              <div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
                <label className="flex flex-col gap-1.5">
                  <span className="text-sm font-medium text-ink-soft">Tipo</span>
                  <select value={draft.tipo_cliente} onChange={(e) => setDraft((d) => ({ ...d, tipo_cliente: e.target.value as ClienteDraft["tipo_cliente"] }))} className="h-11 rounded-xl border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand">
                    <option value="persona">Persona</option>
                    <option value="empresa">Empresa</option>
                  </select>
                </label>
                <label className="flex flex-col gap-1.5">
                  <span className="text-sm font-medium text-ink-soft">Documento</span>
                  <select value={draft.documento_tipo} onChange={(e) => setDraft((d) => ({ ...d, documento_tipo: e.target.value as ClienteDraft["documento_tipo"] }))} className="h-11 rounded-xl border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand">
                    <option value="dni">DNI</option>
                    <option value="cuil">CUIL</option>
                    <option value="cuit">CUIT</option>
                  </select>
                </label>
                <Input label="Numero" value={draft.documento_numero} onChange={(e) => setDraft((d) => ({ ...d, documento_numero: e.target.value }))} />
              </div>
              {draft.tipo_cliente === "empresa" && (
                <div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
                  <Input label="Razon social" value={draft.razon_social} onChange={(e) => setDraft((d) => ({ ...d, razon_social: e.target.value }))} />
                  <Input label="Contacto" value={draft.contacto_nombre} onChange={(e) => setDraft((d) => ({ ...d, contacto_nombre: e.target.value }))} />
                  <Input label="Celular contacto" value={draft.contacto_celular} onChange={(e) => setDraft((d) => ({ ...d, contacto_celular: e.target.value }))} />
                </div>
              )}
              <label className="flex flex-col gap-1.5">
                <span className="text-sm font-medium text-ink-soft">Notas</span>
                <textarea
                  value={draft.notas}
                  onChange={(e) => setDraft((d) => ({ ...d, notas: e.target.value }))}
                  rows={4}
                  className="rounded-xl border border-line bg-surface px-3 py-2 text-sm text-ink outline-none focus:border-brand"
                />
              </label>
            </div>
            {selected && (
              <div className="mt-5 grid gap-3">
                <RelatedList title="Oportunidades" icon={Handshake} items={related.crm.map((item) => ({ href: `/crm/${item.id}`, label: item.titulo, meta: item.estado }))} />
                <RelatedList title="Presupuestos" icon={FileText} items={related.presupuestos.map((item) => ({ href: `/presupuestos/${item.id}`, label: item.codigo || "Presupuesto", meta: item.estado }))} />
                <RelatedList title="Pedidos" icon={ClipboardList} items={related.pedidos.map((item) => ({ href: `/pedidos/${item.id}`, label: item.codigo || (item.numero ? `#${item.numero}` : "Pedido"), meta: item.estado_pedido }))} />
              </div>
            )}
            {err && <p className="mt-3 text-sm text-bad">{err}</p>}
            <div className="mt-5 flex justify-between gap-2">
              {selected ? (
                <Button type="button" variant="danger" onClick={deleteCliente} loading={saving}>
                  <Trash2 size={16} /> Borrar
                </Button>
              ) : <span />}
              <div className="flex gap-2">
                <Button type="button" variant="secondary" onClick={closeCliente}>Cerrar</Button>
                <Button type="button" onClick={saveCliente} loading={saving}>
                  <Save size={16} /> Guardar
                </Button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function RelatedList({ title, icon: Icon, items }: {
  title: string;
  icon: typeof Handshake;
  items: Array<{ href: string; label: string; meta: string }>;
}) {
  return (
    <section className="rounded-xl border border-line bg-canvas p-3">
      <h3 className="mb-2 flex items-center gap-2 text-sm font-bold text-ink">
        <Icon size={15} /> {title}
      </h3>
      {items.length === 0 ? (
        <p className="text-xs text-faint">Sin registros vinculados.</p>
      ) : (
        <div className="space-y-1">
          {items.map((item) => (
            <Link key={item.href} href={item.href} className="flex items-center justify-between gap-3 rounded-lg bg-surface px-3 py-2 text-sm hover:bg-white/70">
              <span className="font-semibold text-ink">{item.label}</span>
              <span className="text-xs text-faint">{item.meta}</span>
            </Link>
          ))}
        </div>
      )}
    </section>
  );
}
