"use client";

import { useEffect, useState } from "react";
import { AlertTriangle, Plus } from "lucide-react";
import { api, type Bodega, type Linea } from "@/lib/api";
import { useSesion } from "@/components/sesion-proveedor";
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 { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
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";

export default function PaginaLineas() {
  const estado = useSesion();
  const [lineas, setLineas] = useState<Linea[]>([]);
  const [bodegas, setBodegas] = useState<Bodega[]>([]);

  const administrador = estado.fase === "lista" && estado.sesion.administrador;

  async function cargar() {
    try {
      const [ls, bs] = await Promise.all([
        api<Linea[]>("/api/lineas"),
        api<Bodega[]>("/api/catalogo/bodegas"),
      ]);
      setLineas(ls);
      setBodegas(bs);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "No se pudo cargar.");
    }
  }

  useEffect(() => {
    void cargar();
  }, []);

  const marcadasMateriaPrima = bodegas.filter((b) => b.usaProduccion === "M");

  return (
    <div className="space-y-5">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Líneas de producción</h1>
          <p className="text-sm text-muted-foreground">
            Cada línea declara de qué bodega saca y a cuál entrega.
          </p>
        </div>
        {administrador ? (
          <DialogoLinea bodegas={bodegas} alGuardar={cargar} />
        ) : null}
      </div>

      {/*
        Qué es una línea, dicho en la pantalla y no en un manual.

        La pregunta «¿para qué son las líneas?» se la hizo Christian el 24-sep-2026
        viendo esta misma pantalla. Si la hace quien mandó a construirla, la va a hacer
        todo el mundo — y la respuesta no puede vivir en un documento que nadie abre.
      */}
      <Card className="border-dashed bg-muted/30">
        <CardContent className="space-y-3 pt-6 text-sm">
          <p>
            <strong>Una línea es un lugar donde se produce</strong>: panadería, cocina,
            repostería. Cada una declara sus tres bodegas, y eso es todo lo que es.
          </p>
          <div className="grid gap-3 sm:grid-cols-3">
            <div className="rounded-md border bg-background p-3">
              <div className="text-xs uppercase tracking-wide text-muted-foreground">
                Sale de
              </div>
              <p className="mt-1 text-muted-foreground">
                La bodega de donde se descuenta la materia prima al despachar.
              </p>
            </div>
            <div className="rounded-md border bg-background p-3">
              <div className="text-xs uppercase tracking-wide text-muted-foreground">
                Se produce en
              </div>
              <p className="mt-1 text-muted-foreground">
                Dónde queda lo que está en proceso, mientras se trabaja.
              </p>
            </div>
            <div className="rounded-md border bg-background p-3">
              <div className="text-xs uppercase tracking-wide text-muted-foreground">
                Entra a
              </div>
              <p className="mt-1 text-muted-foreground">
                La bodega donde aparece el producto terminado, listo para vender.
              </p>
            </div>
          </div>
          <p className="text-muted-foreground">
            Sirven para dos cosas: que cada orden sepa <strong>exactamente</strong> qué
            bodegas mover —sin adivinar— y que los permisos se den por línea, porque quien
            despacha en panadería no tiene por qué mover el inventario de la cocina. Con
            una sola línea el módulo funciona igual de bien.
          </p>
        </CardContent>
      </Card>

      {marcadasMateriaPrima.length > 1 ? (
        <Alert>
          <AlertTriangle className="size-4" />
          <AlertTitle>
            Hay {marcadasMateriaPrima.length} bodegas marcadas como materia prima en el Back
            Office
          </AlertTitle>
          <AlertDescription>
            <p>
              {marcadasMateriaPrima.map((b) => `#${b.tienda} ${b.descripcion}`).join(", ")}.
            </p>
            <p className="mt-1">
              El Back Office se queda con una cualquiera de ellas al despachar. Acá eso no
              pasa: la línea elige explícitamente, y la orden congela esa elección al
              crearse.
            </p>
          </AlertDescription>
        </Alert>
      ) : null}

      <Card>
        <CardHeader>
          <CardTitle className="text-base">{lineas.length} líneas</CardTitle>
          <CardDescription>
            {administrador
              ? "Cambiar una bodega afecta a las órdenes nuevas, no a las que ya existen."
              : "Sólo un administrador del módulo puede cambiarlas."}
          </CardDescription>
        </CardHeader>
        <CardContent>
          {lineas.length === 0 ? (
            <p className="py-10 text-center text-sm text-muted-foreground">
              Todavía no hay líneas configuradas.
            </p>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Línea</TableHead>
                  <TableHead>Materia prima</TableHead>
                  <TableHead>Producción</TableHead>
                  <TableHead>Producto terminado</TableHead>
                  <TableHead />
                </TableRow>
              </TableHeader>
              <TableBody>
                {lineas.map((l) => (
                  <TableRow key={l.id}>
                    <TableCell>
                      <div className="font-medium">{l.nombre}</div>
                      <div className="font-mono text-xs text-muted-foreground">{l.codigo}</div>
                    </TableCell>
                    <TableCell className="text-sm">
                      <Bodeguita numero={l.bodegaMateriaPrima} bodegas={bodegas} />
                    </TableCell>
                    <TableCell className="text-sm">
                      <Bodeguita numero={l.bodegaProduccion} bodegas={bodegas} />
                      {l.bodegaDespacho != null ? (
                        <div className="text-xs text-muted-foreground">
                          despacho: <Bodeguita numero={l.bodegaDespacho} bodegas={bodegas} />
                        </div>
                      ) : null}
                    </TableCell>
                    <TableCell className="text-sm">
                      <Bodeguita numero={l.bodegaProductoTerminado} bodegas={bodegas} />
                    </TableCell>
                    <TableCell>
                      {l.activa ? null : <Badge variant="outline">Inactiva</Badge>}
                    </TableCell>
                    {administrador ? (
                      <TableCell>
                        <DialogoLinea bodegas={bodegas} alGuardar={cargar} linea={l} />
                      </TableCell>
                    ) : null}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

function Bodeguita({ numero, bodegas }: { numero: number; bodegas: Bodega[] }) {
  const bodega = bodegas.find((b) => b.tienda === numero);
  return (
    <span>
      <span className="font-mono text-xs text-muted-foreground">#{numero}</span>{" "}
      {bodega?.descripcion ?? "—"}
    </span>
  );
}

function DialogoLinea({
  bodegas,
  alGuardar,
  linea,
}: {
  bodegas: Bodega[];
  alGuardar: () => Promise<void>;
  /** Si viene, el diálogo EDITA esa línea (PUT) con sus valores precargados; si no, crea una nueva (POST). */
  linea?: Linea;
}) {
  const [abierto, setAbierto] = useState(false);
  const [guardando, setGuardando] = useState(false);
  const inicial = {
    codigo: linea?.codigo ?? "",
    nombre: linea?.nombre ?? "",
    bodegaMateriaPrima: linea ? String(linea.bodegaMateriaPrima) : "",
    bodegaProduccion: linea ? String(linea.bodegaProduccion) : "",
    bodegaProductoTerminado: linea ? String(linea.bodegaProductoTerminado) : "",
    bodegaDespacho: linea?.bodegaDespacho != null ? String(linea.bodegaDespacho) : "",
    entradaTerminadoEn: (linea?.entradaTerminadoEn ?? "PROCESO") as string,
  };
  const [datos, setDatos] = useState(inicial);

  return (
    <Dialog
      open={abierto}
      onOpenChange={(v) => {
        if (v) setDatos(inicial);
        setAbierto(v);
      }}
    >
      <DialogTrigger asChild>
        {linea ? (
          <Button variant="outline" size="sm">
            Editar
          </Button>
        ) : (
          <Button>
            <Plus className="size-4" />
            Nueva línea
          </Button>
        )}
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{linea ? `Editar ${linea.nombre}` : "Nueva línea de producción"}</DialogTitle>
          <DialogDescription>
            Cuatro roles de bodega. Dos roles pueden ser la misma bodega: el traslado entre
            ellos no genera movimiento. Sin bodega de despacho se usa la de producción.
          </DialogDescription>
        </DialogHeader>
        <div className="space-y-3">
          <div className="grid grid-cols-2 gap-3">
            <div className="space-y-1.5">
              <Label htmlFor="codigo">Código</Label>
              <Input
                id="codigo"
                value={datos.codigo}
                onChange={(e) => setDatos((p) => ({ ...p, codigo: e.target.value }))}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="nombre">Nombre</Label>
              <Input
                id="nombre"
                value={datos.nombre}
                onChange={(e) => setDatos((p) => ({ ...p, nombre: e.target.value }))}
              />
            </div>
          </div>
          {(
            [
              ["bodegaMateriaPrima", "Bodega de materia prima"],
              ["bodegaProduccion", "Bodega de producción"],
              ["bodegaProductoTerminado", "Bodega de producto terminado"],
            ] as const
          ).map(([campo, etiqueta]) => (
            <div key={campo} className="space-y-1.5">
              <Label>{etiqueta}</Label>
              <Select
                value={datos[campo]}
                onValueChange={(v) => setDatos((p) => ({ ...p, [campo]: v }))}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Elegí una bodega" />
                </SelectTrigger>
                <SelectContent>
                  {bodegas
                    .filter((b) => !b.esTransito)
                    .map((b) => (
                      <SelectItem key={b.tienda} value={String(b.tienda)}>
                        #{b.tienda} · {b.descripcion}
                      </SelectItem>
                    ))}
                </SelectContent>
              </Select>
            </div>
          ))}
          <div className="space-y-1.5">
            <Label>Bodega de despacho (opcional)</Label>
            <Select
              value={datos.bodegaDespacho || "ninguna"}
              onValueChange={(v) => setDatos((p) => ({ ...p, bodegaDespacho: "ninguna" === v ? "" : v }))}
            >
              <SelectTrigger>
                <SelectValue placeholder="Sin bodega de despacho" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="ninguna">Sin bodega de despacho</SelectItem>
                {bodegas
                  .filter((b) => !b.esTransito)
                  .map((b) => (
                    <SelectItem key={b.tienda} value={String(b.tienda)}>
                      #{b.tienda} · {b.descripcion}
                    </SelectItem>
                  ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Dónde entra el producto terminado al registrar la producción</Label>
            <Select
              value={datos.entradaTerminadoEn}
              onValueChange={(v) => setDatos((p) => ({ ...p, entradaTerminadoEn: v }))}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="PROCESO">En la bodega de producción</SelectItem>
                <SelectItem value="DESPACHO">En la bodega de despacho</SelectItem>
                <SelectItem value="DESTINO">En la bodega de producto terminado</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => setAbierto(false)}>
            Cancelar
          </Button>
          <Button
            disabled={guardando}
            onClick={async () => {
              setGuardando(true);
              try {
                await api(linea ? `/api/lineas/${linea.id}` : "/api/lineas", {
                  metodo: linea ? "PUT" : "POST",
                  cuerpo: {
                    codigo: datos.codigo,
                    nombre: datos.nombre,
                    bodegaMateriaPrima: Number(datos.bodegaMateriaPrima),
                    bodegaProduccion: Number(datos.bodegaProduccion),
                    bodegaProductoTerminado: Number(datos.bodegaProductoTerminado),
                    bodegaDespacho: datos.bodegaDespacho ? Number(datos.bodegaDespacho) : null,
                    entradaTerminadoEn: datos.entradaTerminadoEn,
                  },
                });
                toast.success(linea ? "Línea actualizada: aplica a las órdenes nuevas." : "Línea creada.");
                setAbierto(false);
                await alGuardar();
              } catch (error) {
                toast.error(
                  error instanceof Error ? error.message : "No se pudo guardar la línea.",
                  { duration: 10000 },
                );
              } finally {
                setGuardando(false);
              }
            }}
          >
            {linea ? "Guardar" : "Crear"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
