"use client";

import { use, useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { ArrowLeft, FileText, Handshake, Save, Send, UserCheck } from "lucide-react";
import { motion } from "framer-motion";
import Button from "@/components/ui/Button";
import CommercialItemsEditor from "@/components/presupuestos/CommercialItemsEditor";
import PaymentsPanel from "@/components/pagos/PaymentsPanel";
import {
  convertPresupuestoToPedido,
  getPresupuesto,
  listPresupuestoItems,
  presupuestoItemToDraft,
  replacePresupuestoItems,
  updatePresupuesto,
} from "@/lib/pb/presupuestos";
import { createCrmOportunidad, listCrmOportunidades, updateCrmOportunidad } from "@/lib/pb/crm";
import { listPagosForPresupuesto } from "@/lib/pb/pagos";
import { canConvertPresupuesto, summarizeCommercialItems } from "@/lib/presupuestos/domain";
import { hasPresupuestoDraftChanges, serializePresupuestoDraft } from "@/lib/presupuestos/dirty";
import { useUnsavedChangesGuard } from "@/lib/useUnsavedChangesGuard";
import {
  ESTADO_PRESUPUESTO_LABELS,
  PRESUPUESTO_CIERRE_LABELS,
  type EstadoPresupuesto,
  type Presupuesto,
  type PresupuestoCierreMotivo,
  type PresupuestoItemDraft,
} from "@/lib/types/presupuesto";
import type { Pago } from "@/lib/types/pago";
import type { CrmOportunidad } from "@/lib/types/crm";
import { money, dateLong } from "@/lib/format";

export default function PresupuestoDetailPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = use(params);
  const router = useRouter();
  const [presupuesto, setPresupuesto] = useState<Presupuesto | null>(null);
  const [items, setItems] = useState<PresupuestoItemDraft[]>([]);
  const [pagos, setPagos] = useState<Pago[]>([]);
  const [oportunidades, setOportunidades] = useState<CrmOportunidad[]>([]);
  const [estado, setEstado] = useState<EstadoPresupuesto>("borrador");
  const [cierreMotivo, setCierreMotivo] = useState<PresupuestoCierreMotivo | "">("");
  const [cierreNota, setCierreNota] = useState("");
  const [descripcion, setDescripcion] = useState("");
  const [notas, setNotas] = useState("");
  const [savedSnapshot, setSavedSnapshot] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState("");

  async function reload() {
    const [p, lineas, pagosList, crmList] = await Promise.all([
      getPresupuesto(id),
      listPresupuestoItems(id),
      listPagosForPresupuesto(id),
      listCrmOportunidades({ presupuesto: id }).then((res) => res.items).catch(() => []),
    ]);
    setPresupuesto(p);
    setEstado(p.estado);
    setCierreMotivo(p.cierre_motivo || "");
    setCierreNota(p.cierre_nota || "");
    setDescripcion(p.descripcion || "");
    setNotas(p.notas || "");
    const draftItems = lineas.map(presupuestoItemToDraft);
    setItems(draftItems);
    setPagos(pagosList);
    setOportunidades(crmList);
    setSavedSnapshot(serializePresupuestoDraft({
      estado: p.estado,
      descripcion: p.descripcion || "",
      notas: p.notas || "",
      cierre_motivo: p.cierre_motivo || "",
      cierre_nota: p.cierre_nota || "",
      items: draftItems,
    }));
  }

  useEffect(() => {
    (async () => {
      try {
        await reload();
      } catch (e) {
        setErr((e as Error).message || "No se pudo cargar el presupuesto");
      } finally {
        setLoading(false);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id]);

  const summary = summarizeCommercialItems(items);
  const pagado = pagos.reduce((sum, pago) => sum + (pago.monto || 0), 0);
  const saldo = Math.max(0, summary.total - pagado);
  const hasUnsavedChanges = hasPresupuestoDraftChanges(
    savedSnapshot ? JSON.parse(savedSnapshot) : null,
    { estado, descripcion, notas, cierre_motivo: cierreMotivo, cierre_nota: cierreNota, items },
  );

  useUnsavedChangesGuard(hasUnsavedChanges && !saving, save);

  async function persist() {
    await replacePresupuestoItems(id, items);
    await updatePresupuesto(id, {
      estado,
      descripcion: descripcion.trim(),
      notas: notas.trim(),
      total: summary.total,
      pagado,
      saldo,
      cierre_motivo: cierreMotivo,
      cierre_nota: cierreNota.trim(),
    });
    await reload();
  }

  async function save() {
    setSaving(true);
    setErr("");
    try {
      await persist();
    } catch (e) {
      setErr((e as Error).message || "No se pudo guardar");
    } finally {
      setSaving(false);
    }
  }

  async function convert() {
    if (!presupuesto) return;
    setSaving(true);
    setErr("");
    try {
      await persist();
      const pedido = await convertPresupuestoToPedido(id);
      router.replace(`/pedidos/${pedido.id}`);
    } catch (e) {
      setErr((e as Error).message || "No se pudo convertir a pedido");
      setSaving(false);
    }
  }


  async function createOpportunity() {
    if (!presupuesto) return;
    setSaving(true);
    setErr("");
    try {
      const created = await createCrmOportunidad({
        titulo: presupuesto.codigo ? `Seguimiento ${presupuesto.codigo}` : "Seguimiento presupuesto",
        cliente: {
          id: presupuesto.cliente,
          nombre: presupuesto.expand?.cliente?.nombre || "Cliente",
          celular: presupuesto.expand?.cliente?.celular,
          direccion: presupuesto.expand?.cliente?.direccion,
        },
        origen: "otro",
        estado: "presupuestado",
        prioridad: "media",
        valor_estimado: summary.total,
        nota: descripcion || notas,
      });
      await updateCrmOportunidad(created.id, { presupuesto: presupuesto.id });
      await reload();
    } catch (e) {
      setErr((e as Error).message || "No se pudo crear oportunidad CRM");
    } finally {
      setSaving(false);
    }
  }

  if (loading) return <div className="py-12 text-center text-sm text-faint">Cargando presupuesto...</div>;
  if (!presupuesto) return <div className="py-12 text-center text-bad">{err || "Presupuesto no encontrado"}</div>;

  const convertible = canConvertPresupuesto({ estado, pedido: presupuesto.pedido });
  const showCierre = estado === "rechazado" || estado === "sin_respuesta" || estado === "cancelado";

  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 className="flex-1">
          <h1 className="text-2xl font-extrabold text-ink">Presupuesto {presupuesto.codigo}</h1>
          <p className="text-sm text-ink-soft">
            Creado {dateLong(presupuesto.fecha || presupuesto.created)} para {presupuesto.expand?.cliente?.nombre || "cliente"}
          </p>
        </div>
        <span className="rounded-xl bg-canvas px-3 py-2 text-sm font-bold text-ink">
          Saldo {money(saldo)}
        </span>
      </div>

      <div className="grid grid-cols-1 gap-5 lg:grid-cols-3">
        <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="grid grid-cols-1 gap-3 md:grid-cols-[1fr_220px]">
            <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"
              />
            </label>
            <label className="flex flex-col gap-1.5">
              <span className="text-sm font-medium text-ink-soft">Estado</span>
              <select
                value={estado}
                onChange={(e) => setEstado(e.target.value as EstadoPresupuesto)}
                className="h-11 rounded-xl border border-line bg-surface px-3 text-sm outline-none focus:border-brand"
              >
                {Object.entries(ESTADO_PRESUPUESTO_LABELS).map(([value, label]) => (
                  <option key={value} value={value}>{label}</option>
                ))}
              </select>
              {presupuesto.pedido && <span className="text-xs text-good">Ya convertido a pedido.</span>}
            </label>
          </div>
          {showCierre && (
            <div className="grid grid-cols-1 gap-3 md:grid-cols-[260px_1fr]">
              <label className="flex flex-col gap-1.5">
                <span className="text-sm font-medium text-ink-soft">Motivo / etiqueta</span>
                <select
                  value={cierreMotivo}
                  onChange={(e) => setCierreMotivo(e.target.value as PresupuestoCierreMotivo | "")}
                  className="h-11 rounded-xl border border-line bg-surface px-3 text-sm outline-none focus:border-brand"
                >
                  <option value="">Sin etiqueta</option>
                  {Object.entries(PRESUPUESTO_CIERRE_LABELS).map(([value, label]) => (
                    <option key={value} value={value}>{label}</option>
                  ))}
                </select>
              </label>
              <label className="flex flex-col gap-1.5">
                <span className="text-sm font-medium text-ink-soft">Nota de cierre</span>
                <input
                  value={cierreNota}
                  onChange={(e) => setCierreNota(e.target.value)}
                  className="h-11 rounded-xl border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand"
                  placeholder="Ej: eligió otro proveedor, le pareció caro, no respondió..."
                />
              </label>
            </div>
          )}
          <CommercialItemsEditor items={items} onChange={setItems} />
        </motion.section>

        <motion.section initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.04 }} className="card space-y-3 p-5 lg:col-span-3">
          <h2 className="flex items-center gap-2 font-bold text-ink">
            <FileText size={16} /> Notas
          </h2>
          <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, código generado por calculadora, aclaraciones comerciales..."
          />
        </motion.section>

        <motion.section initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.05 }} className="card space-y-3 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">
              <Handshake size={16} /> CRM
            </h2>
            {oportunidades.length === 0 && (
              <Button type="button" variant="secondary" onClick={createOpportunity} loading={saving}>
                <Handshake size={16} /> Crear oportunidad
              </Button>
            )}
          </div>
          {oportunidades.length === 0 ? (
            <p className="text-sm text-faint">Este presupuesto no está vinculado a una oportunidad.</p>
          ) : (
            <div className="flex flex-wrap gap-2">
              {oportunidades.map((op) => (
                <Link key={op.id} href={`/crm/${op.id}`} className="rounded-xl border border-line bg-canvas px-3 py-2 text-sm font-semibold text-ink hover:border-line-strong">
                  {op.titulo}
                </Link>
              ))}
            </div>
          )}
        </motion.section>

        <motion.section initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.06 }} className="card p-5 lg:col-span-3">
          <PaymentsPanel
            clienteId={presupuesto.cliente}
            presupuestoId={presupuesto.id}
            pagos={pagos}
            onChanged={reload}
          />
        </motion.section>

        <div className="lg:col-span-3 flex flex-wrap items-center justify-between gap-3">
          <div className="flex items-center gap-3 text-sm">
            <span className="rounded-xl bg-canvas px-3 py-2 font-semibold text-ink">Total {money(summary.total)}</span>
            <span className="rounded-xl bg-canvas px-3 py-2 font-semibold text-ink">Pagado {money(pagado)}</span>
          </div>
          <div className="flex items-center gap-2">
            {err && <span className="text-sm font-medium text-bad">{err}</span>}
            <Button type="button" variant="secondary" onClick={save} loading={saving}>
              <Save size={16} /> Guardar
            </Button>
            <Button type="button" onClick={convert} loading={saving} disabled={!convertible}>
              {convertible ? <Send size={16} /> : <UserCheck size={16} />}
              Convertir a pedido
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
}
