"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { CalendarRange, Save, Wand2 } from "lucide-react";
import { api, type Linea, type VentaHistorica } from "@/lib/api";
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 {
  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: 2 });

function haceDias(dias: number): string {
  const d = new Date();
  d.setDate(d.getDate() - dias);
  return d.toISOString().slice(0, 10);
}

/**
 * «Ventas al ojo»: la fase 1 del pizarrón.
 *
 * Parte de lo que de verdad se vendió (hdettra) y el usuario lo ajusta. Los otros dos
 * orígenes —aritmético y machine learning— son sistemas aparte que entrarán por webhook;
 * esta pantalla es el camino manual.
 */
export default function PaginaPronostico() {
  const router = useRouter();

  const [lineas, setLineas] = useState<Linea[]>([]);
  const [linea, setLinea] = useState("");
  const [baseDesde, setBaseDesde] = useState(() => haceDias(30));
  const [baseHasta, setBaseHasta] = useState(() => haceDias(1));
  const [desde, setDesde] = useState(() => new Date().toISOString().slice(0, 10));
  const [hasta, setHasta] = useState(() => {
    const d = new Date();
    d.setDate(d.getDate() + 29);
    return d.toISOString().slice(0, 10);
  });

  const [historico, setHistorico] = useState<VentaHistorica[] | null>(null);
  const [estimadas, setEstimadas] = useState<Record<string, string>>({});
  const [cargando, setCargando] = useState(false);
  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(() => undefined);
  }, []);

  async function traerBase() {
    setCargando(true);
    try {
      const respuesta = await api<{ renglones: VentaHistorica[] }>(
        `/api/pronosticos/base?desde=${baseDesde}&hasta=${baseHasta}`,
      );
      setHistorico(respuesta.renglones);
      setEstimadas(
        Object.fromEntries(respuesta.renglones.map((r) => [r.plu, String(r.cantidad)])),
      );
      if (respuesta.renglones.length === 0) {
        toast.info("No hubo ventas de productos con fórmula en ese período.");
      }
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "No se pudo traer el histórico.");
    } finally {
      setCargando(false);
    }
  }

  function ajustarTodo(factor: number) {
    if (!historico) return;
    setEstimadas(
      Object.fromEntries(
        historico.map((r) => [r.plu, String(Math.round(r.cantidad * factor * 100) / 100)]),
      ),
    );
  }

  const totales = useMemo(() => {
    if (!historico) return { base: 0, estimado: 0 };
    return {
      base: historico.reduce((s, r) => s + r.cantidad, 0),
      estimado: historico.reduce((s, r) => s + (Number(estimadas[r.plu]) || 0), 0),
    };
  }, [historico, estimadas]);

  async function guardar() {
    if (!historico) return;
    setGuardando(true);
    try {
      const creado = await api<{ id: number }>("/api/pronosticos", {
        metodo: "POST",
        cuerpo: {
          linea: Number(linea),
          nombre: `Pronóstico ${desde} a ${hasta}`,
          desde,
          hasta,
          baseDesde,
          baseHasta,
          renglones: historico.map((r) => ({
            plu: r.plu,
            descripcion: r.descripcion,
            cantidadHistorica: r.cantidad,
            cantidadEstimada: Number(estimadas[r.plu]) || 0,
          })),
        },
      });
      toast.success(`Pronóstico #${creado.id} guardado.`);

      // Se pasan los renglones a la pantalla de orden nueva sin meterlos en la URL.
      const llave = `pronostico-${creado.id}`;
      window.sessionStorage.setItem(
        llave,
        JSON.stringify(
          historico
            .filter((r) => (Number(estimadas[r.plu]) || 0) > 0)
            .map((r) => ({
              plu: r.plu,
              descripcion: r.descripcion,
              cantidad: String(Number(estimadas[r.plu]) || 0),
            })),
        ),
      );
      router.push(`/ordenes/nueva?desde=${llave}`);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "No se pudo guardar.", {
        duration: 10000,
      });
    } finally {
      setGuardando(false);
    }
  }

  return (
    <div className="space-y-5">
      <div>
        <h1 className="text-2xl font-semibold tracking-tight">Pronóstico de ventas</h1>
        <p className="text-sm text-muted-foreground">
          Al ojo: se parte de lo que se vendió y se ajusta a mano.
        </p>
      </div>

      <Card>
        <CardHeader>
          <CardTitle className="text-base">Períodos</CardTitle>
          <CardDescription>
            Uno es de dónde se sacan las ventas reales; el otro es el que se está
            pronosticando.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
            <div className="space-y-1.5">
              <Label>Línea</Label>
              <Select value={linea} onValueChange={setLinea}>
                <SelectTrigger>
                  <SelectValue placeholder="Elegí" />
                </SelectTrigger>
                <SelectContent>
                  {lineas.map((l) => (
                    <SelectItem key={l.id} value={String(l.id)}>
                      {l.nombre}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <Fecha etiqueta="Base desde" valor={baseDesde} alCambiar={setBaseDesde} />
            <Fecha etiqueta="Base hasta" valor={baseHasta} alCambiar={setBaseHasta} />
            <Fecha etiqueta="Pronostica desde" valor={desde} alCambiar={setDesde} />
            <Fecha etiqueta="Pronostica hasta" valor={hasta} alCambiar={setHasta} />
          </div>
          <Button onClick={() => void traerBase()} disabled={cargando}>
            <CalendarRange className="size-4" />
            {cargando ? "Trayendo ventas…" : "Traer las ventas del período base"}
          </Button>
        </CardContent>
      </Card>

      {historico ? (
        <Card>
          <CardHeader className="flex-row items-center justify-between space-y-0">
            <div>
              <CardTitle className="text-base">
                {historico.length} productos · {numero.format(totales.base)} unidades vendidas
              </CardTitle>
              <CardDescription>
                Estimado actual: {numero.format(totales.estimado)} unidades
                {totales.base > 0
                  ? ` (${totales.estimado >= totales.base ? "+" : ""}${numero.format(
                      ((totales.estimado - totales.base) / totales.base) * 100,
                    )}%)`
                  : null}
              </CardDescription>
            </div>
            <div className="flex gap-2">
              <Button variant="outline" size="sm" onClick={() => ajustarTodo(0.9)}>
                −10%
              </Button>
              <Button variant="outline" size="sm" onClick={() => ajustarTodo(1)}>
                <Wand2 className="size-4" />
                Igual
              </Button>
              <Button variant="outline" size="sm" onClick={() => ajustarTodo(1.1)}>
                +10%
              </Button>
            </div>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="max-h-[32rem] overflow-auto rounded-md border">
              <Table>
                <TableHeader className="sticky top-0 bg-background">
                  <TableRow>
                    <TableHead>Producto</TableHead>
                    <TableHead className="text-right">Se vendió</TableHead>
                    <TableHead className="w-36 text-right">Se espera vender</TableHead>
                    <TableHead className="w-24 text-right">Variación</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {historico.map((r) => {
                    const estimado = Number(estimadas[r.plu]) || 0;
                    const variacion =
                      r.cantidad > 0 ? ((estimado - r.cantidad) / r.cantidad) * 100 : null;
                    return (
                      <TableRow key={r.plu}>
                        <TableCell>
                          <div className="text-sm">{r.descripcion}</div>
                          <div className="font-mono text-xs text-muted-foreground">{r.plu}</div>
                        </TableCell>
                        <TableCell className="text-right tabular-nums text-muted-foreground">
                          {numero.format(r.cantidad)}
                        </TableCell>
                        <TableCell>
                          <Input
                            type="number"
                            min={0}
                            step="any"
                            className="text-right"
                            value={estimadas[r.plu] ?? ""}
                            onChange={(e) =>
                              setEstimadas((prev) => ({ ...prev, [r.plu]: e.target.value }))
                            }
                          />
                        </TableCell>
                        <TableCell className="text-right text-sm tabular-nums">
                          {variacion === null ? (
                            <span className="text-muted-foreground">—</span>
                          ) : (
                            <span
                              className={
                                variacion > 0
                                  ? "text-emerald-600"
                                  : variacion < 0
                                    ? "text-amber-600"
                                    : "text-muted-foreground"
                              }
                            >
                              {variacion > 0 ? "+" : ""}
                              {numero.format(variacion)}%
                            </span>
                          )}
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </div>

            <Button
              className="w-full"
              disabled={guardando || !linea || historico.length === 0}
              onClick={() => void guardar()}
            >
              <Save className="size-4" />
              Guardar y crear la orden
            </Button>
          </CardContent>
        </Card>
      ) : null}
    </div>
  );
}

function Fecha({
  etiqueta,
  valor,
  alCambiar,
}: {
  etiqueta: string;
  valor: string;
  alCambiar: (v: string) => void;
}) {
  return (
    <div className="space-y-1.5">
      <Label>{etiqueta}</Label>
      <Input type="date" value={valor} onChange={(e) => alCambiar(e.target.value)} />
    </div>
  );
}
