"use client";

import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { ArrowLeft, Save, User, Phone, MapPin, Calendar, Banknote, FileText, Bell, Camera } from "lucide-react";
import { motion } from "framer-motion";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import CortesEditor from "@/components/cortes/CortesEditor";
import CommercialItemsEditor from "@/components/presupuestos/CommercialItemsEditor";
import PhotoCapture, { uploadPedidoFotos } from "@/components/pedidos/PhotoCapture";
import { createPedidoWithCliente, findClienteByCelular } from "@/lib/pb/pedidos";
import { replacePedidoCortes } from "@/lib/pb/cortes";
import { replacePedidoItems } from "@/lib/pb/pedido-items";
import { summarizeCommercialItems } from "@/lib/presupuestos/domain";
import { useUnsavedChangesGuard } from "@/lib/useUnsavedChangesGuard";
import type { CorteItemDraft } from "@/lib/cortes/types";
import type { PedidoItemDraft } from "@/lib/types/pedido";
import { ESTADO_PEDIDO_LABELS, ESTADO_CORTES_LABELS, type EstadoPedido, type EstadoCortes } from "@/lib/types/pedido";
import { PIPELINE_LABELS, mapEtapaToEstadoPedido, type EtapaProduccion } from "@/lib/pedidos/pipeline";
import { money } from "@/lib/format";

export default function NuevoPedidoPage() {
  const router = useRouter();

  const [nombre, setNombre] = useState("");
  const [celular, setCelular] = useState("");
  const [direccion, setDireccion] = useState("");
  const [matchedClienteId, setMatchedClienteId] = useState<string | null>(null);
  const [fechaPedidoInicial] = useState(() => todayInputValue());
  const [fechaPedido, setFechaPedido] = useState(fechaPedidoInicial);
  const [fechaEntrega, setFechaEntrega] = useState("");
  const [fechaEntregaHasta, setFechaEntregaHasta] = useState("");
  const [entregaDesde, setEntregaDesde] = useState("");
  const [entregaHasta, setEntregaHasta] = useState("");
  const [total, setTotal] = useState<string>("");
  const [descripcion, setDescripcion] = useState("");
  const [pedidoItems, setPedidoItems] = useState<PedidoItemDraft[]>([]);
  const [estadoPedido, setEstadoPedido] = useState<EstadoPedido>("cargado");
  const [estadoCortes, setEstadoCortes] = useState<EstadoCortes>("no_necesita");
  const [etapaProduccion, setEtapaProduccion] = useState<EtapaProduccion>("pedido_nuevo");
  const [avisado, setAvisado] = useState(false);
  const [hayQueMedir, setHayQueMedir] = useState(false);
  const [hayQueEnviar, setHayQueEnviar] = useState(false);
  const [hayQueInstalar, setHayQueInstalar] = useState(false);
  const [requierePintura, setRequierePintura] = useState(false);
  const [cortes, setCortes] = useState<CorteItemDraft[]>([]);
  const [fotos, setFotos] = useState<File[]>([]);
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState("");

  const totalN = parseFloat(total) || 0;
  const itemsTotal = summarizeCommercialItems(pedidoItems).total;
  const effectiveTotal = totalN || itemsTotal;
  // La seña se carga como pago real desde el detalle (después de crear). Nace en 0.
  const saldo = effectiveTotal;
  const hasUnsavedChanges =
    !!nombre.trim() ||
    !!celular.trim() ||
    !!direccion.trim() ||
    fechaPedido !== fechaPedidoInicial ||
    !!fechaEntrega ||
    !!fechaEntregaHasta ||
    !!total ||
    !!descripcion.trim() ||
    pedidoItems.length > 0 ||
    cortes.length > 0 ||
    fotos.length > 0 ||
    estadoPedido !== "cargado" ||
    estadoCortes !== "pendiente" ||
    etapaProduccion !== "pedido_nuevo" ||
    avisado ||
    hayQueMedir ||
    hayQueEnviar ||
    hayQueInstalar ||
    requierePintura;

  function applyDeliveryRange(fromDays: string, toDays: string) {
    setEntregaDesde(fromDays);
    setEntregaHasta(toDays);
    const from = parseInt(fromDays, 10);
    const to = parseInt(toDays || fromDays, 10);
    if (Number.isFinite(from) && from >= 0) setFechaEntrega(addDaysInputValue(from));
    if (!Number.isFinite(to) || to < 0) return;
    setFechaEntregaHasta(addDaysInputValue(to));
  }

  // Auto-lookup cliente when celular changes
  useEffect(() => {
    const digits = celular.replace(/\D/g, "");
    if (digits.length < 8) {
      setMatchedClienteId(null);
      return;
    }
    const t = setTimeout(async () => {
      const match = await findClienteByCelular(celular);
      if (match) {
        setMatchedClienteId(match.id);
        if (!nombre) setNombre(match.nombre);
        if (!direccion && match.direccion) setDireccion(match.direccion);
      } else {
        setMatchedClienteId(null);
      }
    }, 400);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [celular]);

  async function handleSaveOnly() {
    if (!nombre.trim()) {
      throw new Error("Falta el nombre del cliente");
    }
    const pedido = await createPedidoWithCliente({
      cliente: {
        id: matchedClienteId || undefined,
        nombre: nombre.trim(),
        celular: celular.trim() || undefined,
        direccion: direccion.trim() || undefined,
      },
      fecha_creacion: fechaPedido ? new Date(fechaPedido + "T00:00:00").toISOString() : undefined,
      fecha_entrega_estimada: fechaEntrega || undefined,
      fecha_entrega_hasta: fechaEntregaHasta || undefined,
      total: effectiveTotal,
      senia: 0,
      estado_pedido: estadoPedido,
      estado_cortes: estadoCortes,
      etapa_produccion: etapaProduccion,
      avisado_retiro: avisado,
      hay_que_medir: hayQueMedir,
      hay_que_enviar: hayQueEnviar,
      hay_que_instalar: hayQueInstalar,
      requiere_pintura: requierePintura,
      descripcion: descripcion.trim(),
    });
    await replacePedidoItems(pedido.id, pedidoItems);
    await replacePedidoCortes(pedido, cortes);
    await uploadPedidoFotos(pedido.id, fotos);
    return pedido;
  }

  const triggerGuard = useUnsavedChangesGuard(hasUnsavedChanges && !loading, async () => {
    const pedido = await handleSaveOnly();
    return !!pedido;
  });

  function leaveTo(path: string) {
    triggerGuard(path);
  }

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    setErr("");

    if (!nombre.trim()) {
      setErr("Falta el nombre del cliente");
      return;
    }

    setLoading(true);
    try {
      const pedido = await handleSaveOnly();
      router.replace(`/pedidos/${pedido.id}`);
    } catch (e) {
      setErr((e as Error).message || "No se pudo crear el pedido");
      setLoading(false);
    }
  }

  return (
    <div className="max-w-5xl">
      <div className="flex items-center gap-3 mb-6">
        <button type="button" onClick={() => leaveTo("/pedidos")} className="text-ink-soft hover:text-ink">
          <ArrowLeft size={20} />
        </button>
        <h1 className="flex-1 text-2xl font-extrabold text-ink">Nuevo pedido</h1>
        <Button type="submit" form="nuevo-pedido-form" loading={loading}>
          <Save size={16} /> Guardar pedido
        </Button>
      </div>

      <form id="nuevo-pedido-form" onSubmit={onSubmit} className="grid grid-cols-1 lg:grid-cols-3 gap-5">
        {/* Cliente */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          className="card p-5 lg:col-span-3 space-y-4"
        >
          <header>
            <h2 className="font-bold text-ink flex items-center gap-2">
              <User size={16} /> Cliente
            </h2>
            {matchedClienteId && (
              <p className="text-xs text-good mt-1">
                Cliente existente encontrado por celular — los datos se actualizan si están vacíos.
              </p>
            )}
          </header>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <Input
              label="Nombre *"
              value={nombre}
              onChange={(e) => setNombre(e.target.value)}
              prefix={<User size={16} />}
              required
              autoFocus
            />
            <Input
              label="Celular"
              type="tel"
              inputMode="tel"
              value={celular}
              onChange={(e) => setCelular(e.target.value)}
              prefix={<Phone size={16} />}
              hint="Si ya existe, se autocompleta"
            />
            <div className="sm:col-span-2">
              <Input
                label="Dirección"
                value={direccion}
                onChange={(e) => setDireccion(e.target.value)}
                prefix={<MapPin size={16} />}
              />
            </div>
          </div>
        </motion.section>

        {/* Estado */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.04 }}
          className="card p-5 lg:col-span-3 space-y-4"
        >
          <h2 className="font-bold text-ink">Estado inicial</h2>
          <SelectField
            label="Estado del pedido"
            value={estadoPedido}
            onChange={(v) => setEstadoPedido(v as EstadoPedido)}
            disabled
            options={Object.entries(ESTADO_PEDIDO_LABELS).map(([v, l]) => ({ v, l }))}
          />
          <SelectField
            label="Estado de cortes"
            value={estadoCortes}
            onChange={(v) => setEstadoCortes(v as EstadoCortes)}
            options={Object.entries(ESTADO_CORTES_LABELS).map(([v, l]) => ({ v, l }))}
          />
          <SelectField
            label="Pipeline de producción"
            value={etapaProduccion}
            onChange={(v) => {
              const nextEtapa = v as EtapaProduccion;
              setEtapaProduccion(nextEtapa);
              setEstadoPedido(mapEtapaToEstadoPedido(nextEtapa));
            }}
            options={Object.entries(PIPELINE_LABELS).map(([v, l]) => ({ v, l }))}
          />
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={avisado}
              onChange={(e) => setAvisado(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <Bell size={16} className="text-ink-soft" />
            <span className="text-sm text-ink">Avisado para retirar/enviar</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={hayQueMedir}
              onChange={(e) => setHayQueMedir(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Hay que medir en el lugar</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={hayQueEnviar}
              onChange={(e) => setHayQueEnviar(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Hay que enviar el pedido</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={hayQueInstalar}
              onChange={(e) => setHayQueInstalar(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Requiere instalación</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer p-2 rounded-lg hover:bg-canvas">
            <input
              type="checkbox"
              checked={requierePintura}
              onChange={(e) => setRequierePintura(e.target.checked)}
              className="w-4 h-4 accent-brand"
            />
            <span className="text-sm text-ink">Requiere pintura</span>
          </label>
        </motion.section>

        {/* Datos del pedido */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.08 }}
          className="card p-5 lg:col-span-3 space-y-4"
        >
          <h2 className="font-bold text-ink flex items-center gap-2">
            <FileText size={16} /> Detalle del trabajo
          </h2>
          <div>
            <label className="text-sm font-medium text-ink-soft mb-1.5 block">
              Descripción (qué se hace, medidas, materiales, etc)
            </label>
            <textarea
              value={descripcion}
              onChange={(e) => setDescripcion(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter" && e.shiftKey) e.stopPropagation();
              }}
              rows={5}
              className="w-full px-3 py-2.5 rounded-xl bg-surface border border-line focus:border-brand outline-none text-ink resize-y"
              placeholder="Ej: Mueble de cocina 1.80 x 0.60, MDF 18mm blanco, 2 puertas corredizas..."
            />
          </div>

          <CommercialItemsEditor items={pedidoItems} onChange={setPedidoItems} title="Productos del pedido" />

          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
            <Input
              label="Fecha del pedido"
              type="date"
              value={fechaPedido}
              onChange={(e) => setFechaPedido(e.target.value)}
              prefix={<Calendar size={16} />}
            />
          </div>

          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
            <Input
              label="Total (calculado)"
              type="number"
              inputMode="decimal"
              value={effectiveTotal.toString()}
              readOnly
              disabled
              prefix={<Banknote size={16} />}
              placeholder="0"
            />
            <div>
              <span className="text-sm font-medium text-ink-soft block mb-1.5">Seña</span>
              <div className="h-11 px-3 rounded-xl bg-canvas border border-line flex items-center gap-2 text-xs text-faint" title="La seña es la suma de los pagos. Después de crear el pedido, cargá el pago desde el detalle.">
                <Banknote size={14} className="shrink-0" />
                Se carga como pago al crear
              </div>
            </div>
            <div>
              <span className="text-sm font-medium text-ink-soft block mb-1.5">Saldo</span>
              <div
                className={`h-11 px-3 rounded-xl bg-canvas border border-line flex items-center font-bold ${
                  saldo > 0 ? "text-bad" : "text-good"
                }`}
              >
                {money(saldo)}
              </div>
            </div>
          </div>

          <div className="grid grid-cols-1 sm:grid-cols-[1fr_auto_auto] gap-3">
            <Input
              label="Entrega desde"
              type="date"
              value={fechaEntrega}
              onChange={(e) => setFechaEntrega(e.target.value)}
              prefix={<Calendar size={16} />}
            />
            <Input
              label="Entrega hasta"
              type="date"
              value={fechaEntregaHasta}
              onChange={(e) => setFechaEntregaHasta(e.target.value)}
              prefix={<Calendar size={16} />}
            />
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <Input
              label="Desde días"
              type="number"
              min="0"
              inputMode="numeric"
              value={entregaDesde}
              onChange={(e) => applyDeliveryRange(e.target.value, entregaHasta)}
              placeholder="Ej: 15"
            />
            <Input
              label="Hasta días"
              type="number"
              min="0"
              inputMode="numeric"
              value={entregaHasta}
              onChange={(e) => applyDeliveryRange(entregaDesde, e.target.value)}
              placeholder="Ej: 25"
            />
          </div>
        </motion.section>

        {/* Cortes */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.1 }}
          className="card p-4 lg:col-span-3"
        >
          <CortesEditor items={cortes} onChange={setCortes} />
        </motion.section>

        {/* Dibujo */}
        <motion.section
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.12 }}
          className="card p-5 lg:col-span-3"
        >
          <h2 className="font-bold text-ink flex items-center gap-2 mb-3">
            <Camera size={16} /> Fotos del croquis
          </h2>
          <p className="text-xs text-faint mb-3">
            Sacá una foto del dibujo en papel (o subila desde la galería). Se guardan al crear el pedido.
          </p>
          <PhotoCapture files={fotos} onFilesChange={setFotos} />
        </motion.section>

        {/* Actions */}
        <div className="lg:col-span-3 flex items-center justify-between gap-3 pt-2">
          {err && <span className="text-sm font-medium text-bad">{err}</span>}
          <div className="flex gap-2 ml-auto">
            <Button variant="secondary" type="button" onClick={() => leaveTo("/pedidos")}>Cancelar</Button>
            <Button type="submit" size="lg" loading={loading}>
              <Save size={18} /> Guardar pedido
            </Button>
          </div>
        </div>
      </form>
    </div>
  );
}

function addDaysInputValue(days: number): string {
  const d = new Date();
  d.setDate(d.getDate() + days);
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

function todayInputValue(): string {
  const d = new Date();
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

function SelectField({
  label,
  value,
  onChange,
  options,
  disabled,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  options: { v: string; l: string }[];
  disabled?: boolean;
}) {
  return (
    <label className="flex flex-col gap-1.5">
      <span className="text-sm font-medium text-ink-soft">{label}</span>
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        className="h-11 px-3 rounded-xl bg-surface border border-line focus:border-brand outline-none text-ink disabled:bg-canvas disabled:text-ink-soft disabled:cursor-not-allowed"
      >
        {options.map((o) => (
          <option key={o.v} value={o.v}>
            {o.l}
          </option>
        ))}
      </select>
    </label>
  );
}
