"use client";

import { DashboardEmptyState, DashboardPageIntro, DashboardSection } from "@/components/dashboard-page";
import { FacturacionPosConfigForm } from "@/components/facturacion-pos-config-form";
import { useAuth } from "@/components/providers";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogBody,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { ErrorState } from "@/components/ui/error-state";
import { Input } from "@/components/ui/input";
import { SkeletonListRow } from "@/components/ui/skeleton";
import { useToast } from "@/hooks/use-toast";
import { authApi, configuracionApi, uploadFileWithProgress } from "@/lib/api";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Building2, ImageIcon, Loader2, MapPin, Phone, Plus, Save, Upload } from "lucide-react";
import { useRouter } from "next/navigation";
import { useMemo, useRef, useState } from "react";

type TiendaForm = {
  nombreImpresion: string;
  direccionImpresion: string;
  telefonoImpresion: string;
  logoUrl: string;
};

type NuevaTiendaForm = {
  nombre: string;
  codigo: string;
  direccion: string;
  telefonoImpresion: string;
};

const EMPTY_NUEVA_TIENDA: NuevaTiendaForm = { nombre: "", codigo: "", direccion: "", telefonoImpresion: "" };

function toForm(tienda: any): TiendaForm {
  return {
    nombreImpresion: tienda?.nombreImpresion || tienda?.nombre || "",
    direccionImpresion: tienda?.direccionImpresion || tienda?.direccion || "",
    telefonoImpresion: tienda?.telefonoImpresion || "",
    logoUrl: tienda?.logoUrl || "",
  };
}

export default function TiendasPage() {
  const router = useRouter();
  const { canRead, canWrite } = useAuth();
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const logoInputRef = useRef<HTMLInputElement | null>(null);
  // "Tiendas" comparte el permiso granular "usuarios" (ver
  // dashboard-shell.tsx y auth.controller.ts) -- no es un módulo aparte, y
  // ya no se decide por rol crudo: un admin sin escritura en "usuarios"
  // puede ver la lista pero no crear ni editar tiendas.
  const canView = canRead("usuarios");
  const canManage = canWrite("usuarios");
  const [selectedId, setSelectedId] = useState<number | null>(null);
  const [form, setForm] = useState<TiendaForm>({
    nombreImpresion: "",
    direccionImpresion: "",
    telefonoImpresion: "",
    logoUrl: "",
  });
  const [uploadingLogo, setUploadingLogo] = useState(false);
  const [showNuevaTienda, setShowNuevaTienda] = useState(false);
  const [nuevaTienda, setNuevaTienda] = useState<NuevaTiendaForm>(EMPTY_NUEVA_TIENDA);

  const { data: tiendas = [], isLoading, isError, refetch } = useQuery({
    queryKey: ["tiendas"],
    queryFn: authApi.tiendas,
    enabled: canView,
  });

  const { data: resumenConfiguracion } = useQuery({
    queryKey: ["configuracion"],
    queryFn: configuracionApi.resumen,
    enabled: canView,
  });

  // Sin @RequirePermission en el backend a propósito (ver taller-parametros.controller.ts)
  // -- cualquier usuario autenticado necesita saber si debe ocultar "Nueva tienda".
  const { data: flags } = useQuery({
    queryKey: ["configuracion", "flags"],
    queryFn: configuracionApi.flags,
  });
  const permiteCrearTiendas = flags?.permiteTiendas ?? true;

  const selectedTienda = useMemo(
    () => tiendas.find((tienda: any) => Number(tienda.id) === Number(selectedId)) || null,
    [selectedId, tiendas],
  );

  const parametrosTiendaSeleccionada = useMemo(() => {
    if (!selectedTienda) return {};
    const tienda = resumenConfiguracion?.tiendas.find(
      (t) => Number(t.tiendaId) === Number(selectedTienda.id),
    );
    return tienda?.parametros ?? {};
  }, [resumenConfiguracion, selectedTienda]);

  const configuredStores = tiendas.filter((tienda: any) => tienda.logoUrl || tienda.telefonoImpresion || tienda.direccionImpresion).length;

  const saveMutation = useMutation({
    mutationFn: async () => {
      if (!selectedTienda) {
        throw new Error("Selecciona una tienda.");
      }

      return authApi.updateTienda(Number(selectedTienda.id), form);
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ["tiendas"] });
      toast({
        variant: "success",
        title: "Tienda actualizada",
        description: "El encabezado de impresión ya usará estos datos.",
      });
    },
    onError: (error: any) =>
      toast({
        variant: "destructive",
        title: "Error",
        description: error.message || "No se pudo actualizar la tienda.",
      }),
  });

  const createTiendaMutation = useMutation({
    mutationFn: async () => {
      if (!nuevaTienda.nombre.trim()) {
        throw new Error("Escribe el nombre de la tienda.");
      }
      return authApi.createTienda({
        nombre: nuevaTienda.nombre.trim(),
        codigo: nuevaTienda.codigo.trim() || undefined,
        direccion: nuevaTienda.direccion.trim() || undefined,
        telefonoImpresion: nuevaTienda.telefonoImpresion.trim() || undefined,
      });
    },
    onSuccess: async (created) => {
      await queryClient.invalidateQueries({ queryKey: ["tiendas"] });
      setShowNuevaTienda(false);
      setNuevaTienda(EMPTY_NUEVA_TIENDA);
      toast({ variant: "success", title: "Tienda creada", description: `"${created.nombre}" ya está disponible.` });
    },
    onError: (error: any) =>
      toast({ variant: "destructive", title: "No se pudo crear", description: error.message }),
  });

  const selectTienda = (tienda: any) => {
    setSelectedId(Number(tienda.id));
    setForm(toForm(tienda));
  };

  const uploadLogo = async (file: File) => {
    setUploadingLogo(true);
    try {
      const uploaded = await uploadFileWithProgress(file, "foto");
      setForm((current) => ({ ...current, logoUrl: uploaded.url }));
      toast({
        variant: "success",
        title: "Logo cargado",
        description: "Guarda la tienda para dejarlo fijo en impresión.",
      });
    } catch (error: any) {
      toast({
        variant: "destructive",
        title: "No se pudo subir el logo",
        description: error.message || "Intenta con otra imagen.",
      });
    } finally {
      setUploadingLogo(false);
    }
  };

  if (!canView) {
    return (
      <main className="mx-auto max-w-4xl p-6">
        <DashboardEmptyState
          title="Sin acceso"
          description="No tenés permiso para ver la gestión de tiendas."
          icon={Building2}
        />
      </main>
    );
  }

  return (
    <div className="min-h-full pb-16 md:pb-10">
      <main className="mx-auto flex max-w-7xl flex-col gap-6 p-4 md:p-6">
        <DashboardPageIntro
          title="Tiendas"
          description="Configura los datos que aparecerán en encabezados de impresión por cada tienda."
          icon={Building2}
          tone="slate"
          badge="Mantenimiento"
          onBack={() => router.push("/dashboard")}
          actions={
            permiteCrearTiendas && canManage ? (
              <Button
                className="rounded-xl"
                onClick={() => setShowNuevaTienda(true)}
              >
                <Plus className="mr-2 h-4 w-4" />
                Nueva tienda
              </Button>
            ) : undefined
          }
          stats={[
            { label: "Tiendas activas", value: tiendas.length, hint: "Disponibles para usuarios y OT", icon: Building2 },
            { label: "Configuradas", value: configuredStores, hint: "Con datos de impresión", icon: ImageIcon },
            { label: "Logo", value: selectedTienda?.logoUrl ? "Activo" : "Pendiente", hint: "Para encabezado", icon: ImageIcon },
          ]}
        />

        <div className="grid gap-6 lg:grid-cols-[360px_1fr]">
          <DashboardSection title="Listado" description="Selecciona la tienda que quieres ajustar.">
            {isLoading ? (
              <div className="divide-y divide-border rounded-xl border border-border">
                {Array.from({ length: 4 }).map((_, index) => (
                  <SkeletonListRow key={index} />
                ))}
              </div>
            ) : isError ? (
              <ErrorState onRetry={() => refetch()} description="No se pudo cargar la lista de tiendas." />
            ) : tiendas.length === 0 ? (
              <DashboardEmptyState
                title="No hay tiendas registradas"
                description="Crea la primera tienda para configurar sus datos de impresión."
                icon={Building2}
                action={
                  canManage ? (
                    <Button onClick={() => setShowNuevaTienda(true)}>
                      <Plus className="mr-2 h-4 w-4" />
                      Crear la primera
                    </Button>
                  ) : undefined
                }
              />
            ) : (
              <div className="space-y-2">
                {tiendas.map((tienda: any) => {
                  const active = Number(tienda.id) === Number(selectedId);
                  return (
                    <button
                      key={tienda.id}
                      type="button"
                      onClick={() => selectTienda(tienda)}
                      className={`w-full rounded-xl border p-4 text-left transition-colors duration-150 ease-out active:scale-[0.98] ${
                        active
                          ? "border-border-strong bg-foreground text-background"
                          : "border-border bg-surface text-foreground hover:border-border-strong hover:bg-muted"
                      }`}
                    >
                      <div className="flex items-center gap-2">
                        <p className="font-bold">{tienda.nombre}</p>
                        {tienda.creadaEnTaller ? (
                          <Badge variant={active ? 'outline' : 'warning'} className={active ? 'border-background/40 text-background' : undefined}>
                            Creada en taller
                          </Badge>
                        ) : null}
                      </div>
                      <p className={`mt-1 text-xs ${active ? "text-subtle-foreground" : "text-muted-foreground"}`}>
                        {tienda.codigo || `ID ${tienda.id}`}
                      </p>
                    </button>
                  );
                })}
              </div>
            )}
          </DashboardSection>

          <DashboardSection title="Datos de impresión" description="Estos datos se muestran en la hoja de recepción impresa.">
            {!selectedTienda ? (
              <DashboardEmptyState
                title="Selecciona una tienda"
                description="Elige una tienda del listado para editar su encabezado."
                icon={Building2}
                className="border-none bg-muted shadow-none"
              />
            ) : (
              <div className="grid gap-5 xl:grid-cols-[1fr_320px]">
                <div className="space-y-4">
                  <div className="grid gap-4 md:grid-cols-2">
                    <label className="space-y-2">
                      <span className="text-sm font-bold text-foreground">Nombre de impresión</span>
                      <Input
                        value={form.nombreImpresion}
                        onChange={(event) => setForm({ ...form, nombreImpresion: event.target.value })}
                        className="h-11 rounded-xl"
                        placeholder="Nombre del taller como debe salir impreso"
                        disabled={!canManage}
                      />
                    </label>
                    <label className="space-y-2">
                      <span className="text-sm font-bold text-foreground">Teléfono</span>
                      <div className="relative">
                        <Phone className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-subtle-foreground" />
                        <Input
                          value={form.telefonoImpresion}
                          onChange={(event) => setForm({ ...form, telefonoImpresion: event.target.value })}
                          className="h-11 rounded-xl pl-9"
                          placeholder="Teléfono de contacto"
                          disabled={!canManage}
                        />
                      </div>
                    </label>
                  </div>

                  <label className="space-y-2">
                    <span className="text-sm font-bold text-foreground">Dirección</span>
                    <div className="relative">
                      <MapPin className="absolute left-3 top-3.5 h-4 w-4 text-subtle-foreground" />
                      <textarea
                        value={form.direccionImpresion}
                        onChange={(event) => setForm({ ...form, direccionImpresion: event.target.value })}
                        className="min-h-24 w-full resize-none rounded-xl border border-border bg-surface px-9 py-3 text-sm outline-none transition-colors focus:border-border-strong disabled:opacity-60"
                        placeholder="Dirección completa del taller"
                        disabled={!canManage}
                      />
                    </div>
                  </label>

                  <label className="space-y-2">
                    <span className="text-sm font-bold text-foreground">URL del logo</span>
                    <Input
                      value={form.logoUrl}
                      onChange={(event) => setForm({ ...form, logoUrl: event.target.value })}
                      className="h-11 rounded-xl"
                      placeholder="https://.../logo.webp"
                      disabled={!canManage}
                    />
                  </label>

                  {canManage ? (
                    <div className="flex flex-wrap gap-2">
                      <Button
                        className="rounded-xl"
                        disabled={saveMutation.isPending || uploadingLogo}
                        onClick={() => saveMutation.mutate()}
                      >
                        {saveMutation.isPending ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Save className="mr-2 h-4 w-4" />}
                        Guardar tienda
                      </Button>
                      <Button
                        variant="outline"
                        className="rounded-xl"
                        disabled={uploadingLogo}
                        onClick={() => logoInputRef.current?.click()}
                      >
                        {uploadingLogo ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Upload className="mr-2 h-4 w-4" />}
                        Subir logo
                      </Button>
                    </div>
                  ) : null}
                </div>

                <Card className="border-border bg-muted">
                  <CardContent className="p-4">
                    <p className="text-sm font-bold text-foreground">Vista previa</p>
                    <div className="mt-4 rounded-xl border border-border bg-surface p-4">
                      {form.logoUrl ? (
                        <img src={form.logoUrl} alt="Logo de tienda" className="max-h-24 w-full object-contain" />
                      ) : (
                        <div className="flex h-24 items-center justify-center rounded-xl border border-dashed border-border-strong text-sm text-subtle-foreground">
                          Sin logo
                        </div>
                      )}
                      <p className="mt-4 text-center text-base font-bold uppercase text-foreground">
                        {form.nombreImpresion || selectedTienda.nombre}
                      </p>
                      {form.direccionImpresion ? (
                        <p className="mt-2 whitespace-pre-wrap text-center text-sm font-medium text-muted-foreground">
                          {form.direccionImpresion}
                        </p>
                      ) : null}
                      {form.telefonoImpresion ? (
                        <p className="mt-1 text-center text-sm font-bold text-foreground">
                          Tel: {form.telefonoImpresion}
                        </p>
                      ) : null}
                    </div>
                  </CardContent>
                </Card>
              </div>
            )}
          </DashboardSection>
        </div>

        {selectedTienda ? (
          <DashboardSection
            title="Facturación POS (POSTouch)"
            description="Cuando esta tienda termina una OT, se envía automáticamente a POSTouch para facturarla. Cada tienda tiene su propia conexión — activarla acá no afecta a las demás."
          >
            <FacturacionPosConfigForm
              tiendaId={Number(selectedTienda.id)}
              tiendaNombre={selectedTienda.nombre}
              parametros={parametrosTiendaSeleccionada}
              readOnly={!canWrite("configuracion.facturacion")}
            />
          </DashboardSection>
        ) : null}
      </main>

      <input
        ref={logoInputRef}
        type="file"
        accept="image/png,image/jpeg,image/webp"
        className="hidden"
        onChange={(event) => {
          const file = event.target.files?.[0];
          if (file) void uploadLogo(file);
          event.currentTarget.value = "";
        }}
      />

      <Dialog
        open={showNuevaTienda}
        onOpenChange={(open) => {
          setShowNuevaTienda(open);
          if (!open) setNuevaTienda(EMPTY_NUEVA_TIENDA);
        }}
      >
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>Nueva tienda</DialogTitle>
            <DialogDescription>
              Usá esta opción solo si el taller no tiene un sistema de facturación conectado. Si las
              tiendas ya vienen de tu sistema de facturación, se cargan solas y no hace falta crearlas
              acá.
            </DialogDescription>
          </DialogHeader>
          
          <DialogBody>
          <div className="space-y-4">
            <label className="space-y-2 block">
              <span className="text-sm font-bold text-foreground">Nombre</span>
              <Input
                value={nuevaTienda.nombre}
                onChange={(event) => setNuevaTienda({ ...nuevaTienda, nombre: event.target.value })}
                className="h-11 rounded-xl"
                placeholder="Ej. Sucursal Central"
              />
            </label>
            <div className="grid gap-4 md:grid-cols-2">
              <label className="space-y-2">
                <span className="text-sm font-bold text-foreground">Código corto (opcional)</span>
                <Input
                  value={nuevaTienda.codigo}
                  onChange={(event) => setNuevaTienda({ ...nuevaTienda, codigo: event.target.value })}
                  className="h-11 rounded-xl"
                  maxLength={5}
                />
              </label>
              <label className="space-y-2">
                <span className="text-sm font-bold text-foreground">Teléfono (opcional)</span>
                <Input
                  value={nuevaTienda.telefonoImpresion}
                  onChange={(event) =>
                    setNuevaTienda({ ...nuevaTienda, telefonoImpresion: event.target.value })
                  }
                  className="h-11 rounded-xl"
                />
              </label>
            </div>
            <label className="space-y-2 block">
              <span className="text-sm font-bold text-foreground">Dirección (opcional)</span>
              <Input
                value={nuevaTienda.direccion}
                onChange={(event) => setNuevaTienda({ ...nuevaTienda, direccion: event.target.value })}
                className="h-11 rounded-xl"
              />
            </label>
          </div>
          </DialogBody>

          <DialogFooter>
            <Button
              variant="outline"
              className="rounded-xl"
              onClick={() => {
                setShowNuevaTienda(false);
                setNuevaTienda(EMPTY_NUEVA_TIENDA);
              }}
            >
              Cancelar
            </Button>
            <Button
              className="rounded-xl"
              disabled={createTiendaMutation.isPending}
              onClick={() => createTiendaMutation.mutate()}
            >
              {createTiendaMutation.isPending ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <Plus className="mr-2 h-4 w-4" />
              )}
              Crear tienda
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
