"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import { ArrowLeft, Plus, Search, Trash2 } from "lucide-react";
import { api, type Linea, type Producto } from "@/lib/api";
import { NombreProducto } from "@/components/nombre-producto";
import { leerNombre } from "@/lib/producto";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { toast } from "sonner";

const numero = new Intl.NumberFormat("es-GT", { maximumFractionDigits: 4 });

type Renglon = { plu: string; descripcion: string; cantidad: string };

type RespuestaExplosion = {
  productos: {
    plu: string;
    unidades: number;
    tieneFormula: boolean;
    unidadesPorLote: number | null;
    lotesEquivalentes: number | null;
  }[];
  insumos: { plu: string; descripcion: string | null; cantidad: number }[];
  omitidos?: { plu: string; descripcion: string | null }[];
};

export default function PaginaNuevaOrden() {
  const router = useRouter();
  const parametros = useSearchParams();

  const [lineas, setLineas] = useState<Linea[]>([]);
  const [linea, setLinea] = useState<string>("");
  const [fecha, setFecha] = useState(() => new Date().toISOString().slice(0, 10));
  const [observaciones, setObservaciones] = useState("");
  const [renglones, setRenglones] = useState<Renglon[]>([]);
  const [busqueda, setBusqueda] = useState("");
  const [resultados, setResultados] = useState<Producto[]>([]);
  const [explosion, setExplosion] = useState<RespuestaExplosion | null>(null);
  const [guardando, setGuardando] = useState(false);

  useEffect(() => {
    api<Linea[]>("/api/lineas")
      .then((ls) => {
        const activas = ls.filter((l) => l.activa);
        setLineas(activas);
        if (activas.length === 1) setLinea(String(activas[0].id));
      })
      .catch((e: unknown) =>
        toast.error(e instanceof Error ? e.message : "No se pudieron cargar las líneas."),
      );
  }, []);

  // Si se llega desde un pronóstico, los renglones vienen precargados.
  useEffect(() => {
    const desde = parametros.get("desde");
    if (!desde) return;
    try {
      const guardado = window.sessionStorage.getItem(desde);
      if (guardado) setRenglones(JSON.parse(guardado) as Renglon[]);
    } catch {
      /* si no se puede leer, simplemente se empieza vacío */
    }
  }, [parametros]);

  // Búsqueda de productos, con una pausa para no consultar en cada tecla.
  useEffect(() => {
    if (busqueda.trim().length < 2) {
      setResultados([]);
      return;
    }
    const temporizador = setTimeout(() => {
      api<Producto[]>(`/api/catalogo/productos?q=${encodeURIComponent(busqueda)}`)
        .then(setResultados)
        .catch(() => setResultados([]));
    }, 250);
    return () => clearTimeout(temporizador);
  }, [busqueda]);

  const listos = useMemo(
    () => renglones.filter((r) => r.plu && Number(r.cantidad) > 0),
    [renglones],
  );

  // Vista previa de la materia prima, antes de comprometerse con nada.
  useEffect(() => {
    if (listos.length === 0) {
      setExplosion(null);
      return;
    }
    const temporizador = setTimeout(() => {
      api<RespuestaExplosion>("/api/catalogo/explosion", {
        metodo: "POST",
        cuerpo: {
          productos: listos.map((r) => ({ plu: r.plu, unidades: Number(r.cantidad) })),
        },
      })
        .then(setExplosion)
        .catch(() => setExplosion(null));
    }, 350);
    return () => clearTimeout(temporizador);
  }, [listos]);

  function agregar(producto: Producto) {
    if (renglones.some((r) => r.plu === producto.plu)) {
      toast.info("Ese producto ya está en la orden.");
      return;
    }
    setRenglones((prev) => [
      ...prev,
      { plu: producto.plu, descripcion: producto.descripcion, cantidad: "" },
    ]);
    setBusqueda("");
    setResultados([]);
  }

  async function guardar() {
    setGuardando(true);
    try {
      const creada = await api<{ id: number }>("/api/ordenes", {
        metodo: "POST",
        cuerpo: {
          linea: Number(linea),
          fecha,
          observaciones: observaciones || null,
          productos: listos.map((r) => ({ plu: r.plu, cantidad: Number(r.cantidad) })),
        },
      });
      toast.success(`Orden #${creada.id} creada.`);
      router.push(`/ordenes/${creada.id}`);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "No se pudo crear la orden.", {
        duration: 10000,
      });
    } finally {
      setGuardando(false);
    }
  }

  return (
    <div className="space-y-5">
      <div className="flex items-center gap-3">
        <Button variant="ghost" size="sm" asChild>
          <Link href="/">
            <ArrowLeft className="size-4" />
            Órdenes
          </Link>
        </Button>
        <h1 className="text-2xl font-semibold tracking-tight">Nueva orden</h1>
      </div>

      <div className="grid gap-5 lg:grid-cols-3">
        <Card className="min-w-0 lg:col-span-2">
          <CardHeader>
            <CardTitle className="text-base">Qué se va a producir</CardTitle>
            <CardDescription>
              Las cantidades van en unidades de producto terminado.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid gap-3 sm:grid-cols-2">
              <div className="space-y-1.5">
                <Label>Línea de producción</Label>
                <Select value={linea} onValueChange={setLinea}>
                  <SelectTrigger>
                    <SelectValue placeholder="Elegí una línea" />
                  </SelectTrigger>
                  <SelectContent>
                    {lineas.map((l) => (
                      <SelectItem key={l.id} value={String(l.id)}>
                        {l.nombre}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="fecha">Fecha</Label>
                <Input
                  id="fecha"
                  type="date"
                  value={fecha}
                  onChange={(e) => setFecha(e.target.value)}
                />
              </div>
            </div>

            <div className="space-y-1.5">
              <Label htmlFor="buscar">Agregar producto</Label>
              <div className="relative">
                <Search className="absolute left-2.5 top-2.5 size-4 text-muted-foreground" />
                <Input
                  id="buscar"
                  className="pl-8"
                  placeholder="Código o descripción — sólo aparecen los que tienen fórmula"
                  value={busqueda}
                  onChange={(e) => setBusqueda(e.target.value)}
                />
              </div>
              {resultados.length > 0 ? (
                <div className="max-h-64 overflow-auto rounded-md border">
                  {resultados.map((p) => (
                    <button
                      key={p.plu}
                      type="button"
                      onClick={() => agregar(p)}
                      disabled={!p.tieneFormula}
                      className="flex w-full items-center justify-between gap-2 border-b px-3 py-2 text-left text-sm last:border-b-0 hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40"
                    >
                      <NombreProducto plu={p.plu} descripcion={p.descripcion} />
                      {p.tieneFormula ? (
                        <Plus className="size-4 shrink-0" />
                      ) : (
                        <span className="shrink-0 text-xs text-muted-foreground">sin fórmula</span>
                      )}
                    </button>
                  ))}
                </div>
              ) : null}
            </div>

            {renglones.length > 0 ? (
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Producto</TableHead>
                    <TableHead className="w-36 text-right">Unidades</TableHead>
                    <TableHead className="w-28 text-right">Lotes</TableHead>
                    <TableHead className="w-10" />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {renglones.map((r, i) => {
                    const info = explosion?.productos.find((p) => p.plu === r.plu);
                    return (
                      <TableRow key={r.plu}>
                        <TableCell>
                          <NombreProducto plu={r.plu} descripcion={r.descripcion} />
                        </TableCell>
                        <TableCell>
                          <Input
                            type="number"
                            min={0}
                            step="any"
                            className="text-right"
                            value={r.cantidad}
                            onChange={(e) =>
                              setRenglones((prev) =>
                                prev.map((x, j) =>
                                  j === i ? { ...x, cantidad: e.target.value } : x,
                                ),
                              )
                            }
                          />
                        </TableCell>
                        <TableCell className="text-right text-sm tabular-nums text-muted-foreground">
                          {info?.lotesEquivalentes == null
                            ? "—"
                            : `${numero.format(info.lotesEquivalentes)}`}
                        </TableCell>
                        <TableCell>
                          <Button
                            variant="ghost"
                            size="icon"
                            onClick={() =>
                              setRenglones((prev) => prev.filter((_, j) => j !== i))
                            }
                          >
                            <Trash2 className="size-4" />
                          </Button>
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            ) : (
              <p className="py-8 text-center text-sm text-muted-foreground">
                Buscá un producto arriba para empezar.
              </p>
            )}

            <div className="space-y-1.5">
              <Label htmlFor="obs">Observaciones</Label>
              <Textarea
                id="obs"
                value={observaciones}
                onChange={(e) => setObservaciones(e.target.value)}
              />
            </div>

            <Button
              className="w-full"
              disabled={guardando || !linea || listos.length === 0}
              onClick={() => void guardar()}
            >
              Crear orden
            </Button>
          </CardContent>
        </Card>

        <Card className="h-fit min-w-0">
          <CardHeader>
            <CardTitle className="text-base">Materia prima que hace falta</CardTitle>
            <CardDescription>
              Vista previa, explotada hasta la hoja. Se congela al planificar.
            </CardDescription>
          </CardHeader>
          <CardContent>
            {!explosion || explosion.insumos.length === 0 ? (
              <p className="py-8 text-center text-sm text-muted-foreground">
                Poné cantidades y acá aparece el cálculo.
              </p>
            ) : (
              <ul className="space-y-2 text-sm">
                {explosion.insumos.map((i) => (
                  <li key={i.plu} className="flex items-start justify-between gap-3">
                    <span className="text-muted-foreground">
                      {leerNombre(i.descripcion ?? i.plu).nombre}
                    </span>
                    <span className="shrink-0 tabular-nums">{numero.format(i.cantidad)}</span>
                  </li>
                ))}
              </ul>
            )}
            {explosion?.omitidos && explosion.omitidos.length > 0 && (
              <p className="mt-4 border-t pt-3 text-xs text-muted-foreground">
                No se despachan ni se consumen (son costo, no existencia):{" "}
                {explosion.omitidos.map((o) => leerNombre(o.descripcion ?? o.plu).nombre).join(", ")}.
                Su costo entra por tarifas.
              </p>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
