import { useEffect, useMemo, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Scale, ScanLine } from "lucide-react";
import { PickingAPI } from "@/apis/PickingAPI";
import { DispatchPrintAPI } from "@/apis/DispatchPrintAPI";
import { useBarcodeScannerInput } from "@/hooks/useBarcodeScannerInput";
import { toast } from "sonner";
import { formatKg, getBusinessErrorMessage, weightRangeKg } from "@/utils/apiErrorMessage";

export default function Weighing() {
  const queryClient = useQueryClient();
  const [company, setCompany] = useState(null);
  const [selectedId, setSelectedId] = useState(null);
  const [actualWeight, setActualWeight] = useState("");
  const [savingId, setSavingId] = useState(null);

  useEffect(() => {
    PickingAPI.getPrimaryCompanyForCurrentUser().then(setCompany);
  }, []);

  const { data: orders = [] } = useQuery({
    queryKey: ["picking-orders-weigh", company?.id],
    enabled: Boolean(company?.id),
    queryFn: () => PickingAPI.getPickingOrdersByCompanyId(company.id),
  });

  const ready = useMemo(
    () => orders.filter((order) => order.status === "packed" && !order.weight_validated),
    [orders],
  );

  const display = selectedId
    ? ready.filter((order) => String(order.id) === String(selectedId))
    : ready;

  const {
    value: scanCode,
    handleChange,
    handleKeyDown,
    inputRef,
    focusScanInput,
    clearValue,
  } = useBarcodeScannerInput({
    onScan: (code) => void lookup(code),
    autoFocus: true,
    enableDebounceScan: false,
  });

  const lookup = async (code) => {
    const trimmed = String(code || "").trim();
    if (!trimmed || !company?.id) return;
    try {
      const order = await PickingAPI.lookupForWeigh(trimmed, company.id, "weigh");
      setSelectedId(order.id);
      setActualWeight("");
      toast.success(`Pedido ${order.sale_number || order.id} listo para pesar.`);
      clearValue();
    } catch (error) {
      toast.error(getBusinessErrorMessage(error) || "La orden no está embalada o no existe.");
    }
  };

  const validate = async (order) => {
    const weight = Number.parseFloat(actualWeight);
    if (!Number.isFinite(weight) || weight <= 0) {
      toast.error("Ingresa el peso real de la caja en kg.");
      return;
    }
    setSavingId(order.id);
    try {
      await DispatchPrintAPI.validateWeight(order.id, weight, order.expected_weight_kg);
      toast.success("Peso validado. Continúa en Despacho para la etiqueta courier.");
      try {
        await DispatchPrintAPI.printPickingCourier(order.id);
      } catch {
        toast.info("El peso quedó validado. La etiqueta se imprime en Despacho.");
      }
      setSelectedId(null);
      setActualWeight("");
      await queryClient.invalidateQueries({ queryKey: ["picking-orders-weigh", company?.id] });
      focusScanInput();
    } catch (error) {
      toast.error(getBusinessErrorMessage(error) || "No se pudo validar el peso.");
    } finally {
      setSavingId(null);
    }
  };

  return (
    <div className="p-6 space-y-6">
      <div>
        <h1 className="text-3xl font-bold text-gradient flex items-center gap-2">
          <Scale className="w-8 h-8" />
          Pesaje
        </h1>
        <p className="text-gray-600 mt-1">
          Solo órdenes con caja embalada. Validación ±5% contra el peso esperado.
        </p>
      </div>

      <Card className="glass-card border-amber-200">
        <CardContent className="p-4">
          <form
            onSubmit={(event) => {
              event.preventDefault();
              void lookup(scanCode);
            }}
            className="space-y-2"
          >
            <Label className="flex items-center gap-2 font-semibold text-amber-900">
              <ScanLine className="w-5 h-5" />
              Abrir pedido embalado
            </Label>
            <div className="flex gap-2">
              <Input
                ref={inputRef}
                value={scanCode}
                onChange={(event) => handleChange(event.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="Código de barras o Venta # de la tarjeta"
              />
              <Button type="submit">Buscar</Button>
            </div>
          </form>
        </CardContent>
      </Card>

      <div className="grid lg:grid-cols-2 gap-6">
        {display.map((order) => {
          const range = weightRangeKg(order.expected_weight_kg);
          return (
            <Card key={order.id} className="glass-card">
              <CardHeader>
                <div className="flex justify-between">
                  <div>
                    <CardTitle>Venta #{order.sale_number}</CardTitle>
                    <p className="text-sm text-gray-600">{order.customer_name}</p>
                  </div>
                  <Badge className="bg-purple-100 text-purple-800">Embalado</Badge>
                </div>
              </CardHeader>
              <CardContent className="space-y-3">
                <p className="text-sm">
                  Esperado: <strong>{formatKg(range.expected)} kg</strong> ({formatKg(range.min)}–{formatKg(range.max)} kg)
                </p>
                <Input
                  type="number"
                  step="0.01"
                  min="0"
                  placeholder="Peso real de la caja (kg)"
                  value={String(selectedId) === String(order.id) ? actualWeight : ""}
                  onChange={(event) => {
                    setSelectedId(order.id);
                    setActualWeight(event.target.value);
                  }}
                  onKeyDown={(event) => {
                    if (event.key === "Enter") {
                      event.preventDefault();
                      void validate(order);
                    }
                  }}
                />
                <Button
                  className="w-full bg-yellow-600"
                  disabled={savingId === order.id}
                  onClick={() => void validate(order)}
                >
                  Validar peso
                </Button>
              </CardContent>
            </Card>
          );
        })}
      </div>

      {display.length === 0 && (
        <Card className="glass-card">
          <CardContent className="p-12 text-center text-gray-500">
            No hay cajas embaladas pendientes de pesaje.
          </CardContent>
        </Card>
      )}
    </div>
  );
}
