"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { ArrowLeft, FileText, Handshake, MapPin, Phone, Save, Search, User, Users } from "lucide-react";
import { motion } from "framer-motion";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import CommercialItemsEditor from "@/components/presupuestos/CommercialItemsEditor";
import { listClientes } from "@/lib/pb/clientes";
import { createPresupuestoWithCliente } from "@/lib/pb/presupuestos";
import { listCrmOportunidades, updateCrmOportunidad } from "@/lib/pb/crm";
import { serializePresupuestoDraft } from "@/lib/presupuestos/dirty";
import { useUnsavedChangesGuard } from "@/lib/useUnsavedChangesGuard";
import type { Cliente } from "@/lib/types/pedido";
import type { PresupuestoItemDraft } from "@/lib/types/presupuesto";
import type { CrmOportunidad } from "@/lib/types/crm";

export default function NuevoPresupuestoPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [nombre, setNombre] = useState("");
  const [celular, setCelular] = useState("");
  const [direccion, setDireccion] = useState("");
  const [clienteMode, setClienteMode] = useState<"existente" | "nuevo">("existente");
  const [clienteSearch, setClienteSearch] = useState("");
  const [clientes, setClientes] = useState<Cliente[]>([]);
  const [selectedCliente, setSelectedCliente] = useState<Cliente | null>(null);
  const [descripcion, setDescripcion] = useState("");
  const [notas, setNotas] = useState("");
  const [items, setItems] = useState<PresupuestoItemDraft[]>([]);
  const [crmOportunidades, setCrmOportunidades] = useState<CrmOportunidad[]>([]);
  const [selectedOportunidadId, setSelectedOportunidadId] = useState("");
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState("");
  
  const hasUnsavedChanges = Boolean(
    selectedOportunidadId ||
      selectedCliente ||
      nombre.trim() ||
      celular.trim() ||
      direccion.trim() ||
      clienteSearch.trim() ||
      serializePresupuestoDraft({ descripcion, notas, items }) !== serializePresupuestoDraft({ descripcion: "", notas: "", items: [] }),
  );

  useEffect(() => {
    async function loadOportunidades() {
      try {
        const res = await listCrmOportunidades({ presupuesto: "", estado: "activos" });
        setCrmOportunidades(res.items);
      } catch (e) {
        console.error("No se pudieron cargar propuestas de CRM", e);
      }
    }
    void loadOportunidades();
  }, []);

  function handleSelectOportunidad(id: string) {
    setSelectedOportunidadId(id);
    if (!id) {
      setSelectedCliente(null);
      setDescripcion("");
      return;
    }
    const op = crmOportunidades.find((o) => o.id === id);
    if (op) {
      if (op.expand?.cliente) {
        setSelectedCliente(op.expand.cliente);
        setClienteMode("existente");
      }
      const descPart = op.nota ? `\n\nNotas CRM: ${op.nota}` : "";
      setDescripcion(`Propuesta CRM: ${op.titulo}${descPart}`);
    }
  }

  async function handleSaveOnly() {
    if (clienteMode === "existente" && !selectedCliente) {
      throw new Error("Elegí un cliente o cambiá a cargar cliente nuevo");
    }
    if (clienteMode === "nuevo" && !nombre.trim()) {
      throw new Error("Falta el nombre del cliente");
    }
    const created = await createPresupuestoWithCliente({
      cliente: {
        id: selectedCliente?.id,
        nombre: selectedCliente?.nombre || nombre.trim(),
        celular: selectedCliente?.celular || celular.trim() || undefined,
        direccion: selectedCliente?.direccion || direccion.trim() || undefined,
      },
      descripcion: descripcion.trim(),
      notas: notas.trim(),
      items,
      skipCrmOpportunity: !!selectedOportunidadId,
    });
    return created;
  }

  useUnsavedChangesGuard(hasUnsavedChanges && !saving, async () => {
    const created = await handleSaveOnly();
    if (selectedOportunidadId && created) {
      await updateCrmOportunidad(selectedOportunidadId, {
        presupuesto: created.id,
        estado: "presupuestado",
      });
    }
    return !!created;
  });

  useEffect(() => {
    if (searchParams.get("from") !== "calculadora" || typeof window === "undefined") return;
    const nota = sessionStorage.getItem("fibro_calc_presupuesto_nota") || "";
    const total = Number(sessionStorage.getItem("fibro_calc_presupuesto_total") || "0");
    if (nota) {
      setNotas((current) => current || nota);
      setDescripcion((current) => current || "Presupuesto generado desde calculadora");
    }
    if (total > 0) {
      setItems((current) => current.length ? current : [{
        descripcion: "Cálculo de calculadora",
        cantidad: 1,
        precio_unitario: total,
      }]);
    }
  }, [searchParams]);

  useEffect(() => {
    if (clienteMode !== "existente") return;
    const t = setTimeout(async () => {
      try {
        const res = await listClientes(clienteSearch, 60);
        setClientes(res.items);
      } catch {
        setClientes([]);
      }
    }, clienteSearch ? 250 : 0);
    return () => clearTimeout(t);
  }, [clienteMode, clienteSearch]);

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    setErr("");
    setSaving(true);
    try {
      const created = await handleSaveOnly();
      if (selectedOportunidadId) {
        await updateCrmOportunidad(selectedOportunidadId, {
          presupuesto: created.id,
          estado: "presupuestado",
        });
      }
      router.replace(`/presupuestos/${created.id}`);
    } catch (e) {
      setErr((e as Error).message || "No se pudo crear el presupuesto");
      setSaving(false);
    }
  }

  return (
    <div className="max-w-5xl">
      <div className="mb-6 flex items-center gap-3">
        <Link href="/presupuestos" className="text-ink-soft hover:text-ink">
          <ArrowLeft size={20} />
        </Link>
        <div>
          <h1 className="text-2xl font-extrabold text-ink">Nuevo presupuesto</h1>
          <p className="text-sm text-ink-soft">El codigo se reserva al guardar.</p>
        </div>
      </div>

      <form onSubmit={submit} className="grid grid-cols-1 gap-5 lg:grid-cols-3">
        {crmOportunidades.length > 0 && (
          <motion.section initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className="card space-y-4 p-5 lg:col-span-3">
            <h2 className="flex items-center gap-2 font-bold text-ink">
              <Handshake size={16} className="text-brand-dark" /> Propuesta de CRM (Opcional)
            </h2>
            <label className="flex flex-col gap-1.5">
              <span className="text-sm font-medium text-ink-soft">Vincular a propuesta de CRM activa sin presupuesto</span>
              <select
                value={selectedOportunidadId}
                onChange={(e) => handleSelectOportunidad(e.target.value)}
                className="h-11 rounded-xl border border-line bg-surface px-3 text-sm outline-none focus:border-brand"
              >
                <option value="">-- No vincular a ninguna propuesta --</option>
                {crmOportunidades.map((op) => (
                  <option key={op.id} value={op.id}>
                    {op.titulo} ({op.expand?.cliente?.nombre || "Sin cliente"})
                  </option>
                ))}
              </select>
            </label>
          </motion.section>
        )}

        <motion.section initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className="card space-y-4 p-5 lg:col-span-3">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <h2 className="flex items-center gap-2 font-bold text-ink">
              <User size={16} /> Cliente
            </h2>
            <div className="flex rounded-xl border border-line bg-canvas p-1 text-sm font-semibold">
              <button
                type="button"
                onClick={() => setClienteMode("existente")}
                className={`rounded-lg px-3 py-1.5 ${clienteMode === "existente" ? "bg-surface text-ink shadow-sm" : "text-ink-soft"}`}
              >
                Buscar contacto
              </button>
              <button
                type="button"
                onClick={() => {
                  setClienteMode("nuevo");
                  setSelectedCliente(null);
                }}
                className={`rounded-lg px-3 py-1.5 ${clienteMode === "nuevo" ? "bg-surface text-ink shadow-sm" : "text-ink-soft"}`}
              >
                Nuevo cliente
              </button>
            </div>
          </div>
          {clienteMode === "existente" ? (
            <div className="space-y-3">
              <Input
                label="Buscar en contactos"
                value={clienteSearch}
                onChange={(e) => setClienteSearch(e.target.value)}
                prefix={<Search size={16} />}
                placeholder="Nombre o celular"
                autoFocus
              />
              <div className="max-h-64 overflow-auto rounded-xl border border-line">
                {clientes.length === 0 ? (
                  <div className="p-5 text-center text-sm text-faint">
                    <Users size={24} className="mx-auto mb-2" />
                    No hay contactos para mostrar.
                  </div>
                ) : (
                  <div className="divide-y divide-line">
                    {clientes.map((cliente) => (
                      <button
                        type="button"
                        key={cliente.id}
                        onClick={() => setSelectedCliente(cliente)}
                        className={`flex w-full items-center justify-between gap-3 px-4 py-3 text-left hover:bg-canvas ${
                          selectedCliente?.id === cliente.id ? "bg-brand-soft/60" : ""
                        }`}
                      >
                        <div>
                          <p className="font-semibold text-ink">{cliente.nombre}</p>
                          <p className="text-xs text-faint">
                            {[cliente.celular, cliente.direccion].filter(Boolean).join(" · ") || "Sin datos extra"}
                          </p>
                        </div>
                        {selectedCliente?.id === cliente.id && (
                          <span className="rounded-lg bg-brand px-2 py-1 text-xs font-bold text-white">Elegido</span>
                        )}
                      </button>
                    ))}
                  </div>
                )}
              </div>
            </div>
          ) : (
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
              <Input label="Nombre *" value={nombre} onChange={(e) => setNombre(e.target.value)} prefix={<User size={16} />} required autoFocus />
              <Input label="Celular" type="tel" value={celular} onChange={(e) => setCelular(e.target.value)} prefix={<Phone size={16} />} />
              <div className="sm:col-span-2">
                <Input label="Direccion" value={direccion} onChange={(e) => setDireccion(e.target.value)} prefix={<MapPin size={16} />} />
              </div>
            </div>
          )}
        </motion.section>

        <motion.section initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.05 }} className="card space-y-4 p-5 lg:col-span-3">
          <h2 className="flex items-center gap-2 font-bold text-ink">
            <FileText size={16} /> Detalle
          </h2>
          <label className="flex flex-col gap-1.5">
            <span className="text-sm font-medium text-ink-soft">Descripcion general</span>
            <textarea
              value={descripcion}
              onChange={(e) => setDescripcion(e.target.value)}
              rows={5}
              className="rounded-xl border border-line bg-surface px-3 py-2 text-sm text-ink outline-none resize-y focus:border-brand"
              placeholder="Ej: Placard melamina blanca, medidas aproximadas, observaciones..."
            />
          </label>
          <CommercialItemsEditor items={items} onChange={setItems} />
          <label className="flex flex-col gap-1.5">
            <span className="text-sm font-medium text-ink-soft">Notas</span>
            <textarea
              value={notas}
              onChange={(e) => setNotas(e.target.value)}
              rows={5}
              className="w-full rounded-xl border border-line bg-surface px-3 py-2 text-sm text-ink outline-none resize-y focus:border-brand"
              placeholder="Notas internas o código generado por calculadora..."
            />
          </label>
        </motion.section>

        <div className="lg:col-span-3 flex items-center justify-end gap-3">
          {err && <span className="text-sm font-medium text-bad">{err}</span>}
          <Button type="submit" size="lg" loading={saving}>
            <Save size={18} /> Guardar presupuesto
          </Button>
        </div>
      </form>
    </div>
  );
}
