import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../pedido/pedido_ticket.dart';
import '../../themes/themes.dart';
import '../../models/models.dart';
import '../../viewmodels/viewmodels.dart';
import 'package:collection/collection.dart';

import '../../widgets/widgets.dart';

class PedidoForm extends StatefulWidget {
  @override
  _PedidoFormState createState() => _PedidoFormState();
}

class _PedidoFormState extends State<PedidoForm> {
  final _busqueda = TextEditingController(text: '');
  final TextEditingController _descuentoController = TextEditingController();
  CategoriaProductoViewModel cvm = CategoriaProductoViewModel();
  ProductoViewModel pvm = ProductoViewModel();
  PedidoViewModel pedvm = PedidoViewModel();
  bool _isLoading = false;
  CategoriaProducto? categoriaSeleccionada;
  List<CategoriaProducto> categorias = [];
  List<Producto> productos = [];
  List<ItemCarrito> carrito = [];
  Producto? _productoActual;
  bool _estadoBusqueda = false;
  Pedido? pedidoActual;
  ScrollController _gridViewController = ScrollController();
  final _searchController = TextEditingController();
  final NumberFormat _numberFormat = NumberFormat.decimalPattern('es_MX');
  int? selectedDescuento = 0;
  double subtotal = 0;
  double precioDescuento = 0;
  double totalPedido = 0;

  bool efectivoSeleccionado = false;
  bool tarjetaSeleccionada = false;
  bool transferenciaSeleccionada = false;
  TextEditingController efectivoController = TextEditingController();
  TextEditingController tarjetaController = TextEditingController();
  TextEditingController transferenciaController = TextEditingController();
  double cambio = 0.0;

  double calcularTotalPedido() {
    double total = 0;

    for (var item in carrito) {
      total += double.parse(item.producto.precio!) * item.cantidad;
      item.selectedToppings.forEach((categoryId, selectedToppingIds) {
        for (int toppingId in selectedToppingIds) {
          Producto? topping = item.selectableToppings[categoryId]?.firstWhere(
              (topping) => topping.id == toppingId,
              orElse: () => Producto(precio: '0'));
          if (topping != null) {
            total += (double.tryParse(topping.precio!) ?? 0) * item.cantidad;
          }
        }
      });
    }

    return total;
  }

  double aplicarDescuento(double total, int? descuento) {
    if (descuento != null && descuento > 0) {
      double totalPedido = total * (1 - descuento / 100);
      // print(
      //     'Total con descuento: $totalPedido (Descuento aplicado: $descuento%)');
      return totalPedido;
    }
    // print('Sin descuento, total: $total');
    return total;
  }

  @override
  void initState() {
    super.initState();
    cargarCategoriasIniciales().then((_) {
      if (categorias.isNotEmpty) {
        categoriaSeleccionada = categorias.first;
        cargarProductosPorCategoria(categoriaSeleccionada!.id);
      }
    });

    Provider.of<DescuentoViewModel>(context, listen: false).cargarDescuentos();
  }

  _onSearchChanged(String value) {
    if (value.isEmpty) {
      cargarProductosIniciales();
    } else {
      Provider.of<ProductoViewModel>(context, listen: false)
          .fetchLocalByName(nombre: value);
    }
  }

  void _recalcularTotal() {
    subtotal = calcularTotalPedido();
    // print('Subtotal: $subtotal');
    // print('Descuento seleccionado: $selectedDescuento%');

    precioDescuento = subtotal * (selectedDescuento! / 100);
    totalPedido = subtotal - precioDescuento;

    setState(() {
      pedidoActual = pedidoActual ?? Pedido();
      pedidoActual!.totalPedido = totalPedido;
      pedidoActual!.descuento = selectedDescuento;
    });

    // print('Precio descuento: $precioDescuento');
    // print('Total con descuento aplicado: $totalPedido');
  }

  void _finalizeOrder() async {
    if (carrito.isEmpty) {
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('Pedido vacío',
                style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22)),
            content: const Text(
                'No puedes finalizar un pedido sin productos. Por favor, agrega al menos un producto.',
                style: TextStyle(fontWeight: FontWeight.w500, fontSize: 18)),
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
            actions: <Widget>[
              TextButton(
                style: TextButton.styleFrom(
                    padding: EdgeInsets.fromLTRB(30, 20, 30, 20),
                    foregroundColor: AppTheme.quaternary,
                    backgroundColor: AppTheme.tertiary),
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text('Aceptar', style: TextStyle(fontSize: 18)),
              ),
            ],
          );
        },
      );
      return;
    }

    await _promptForCustomerName();
  }

  Future<void> _promptForCustomerName() async {
    TextEditingController nombreController = TextEditingController();
    TextEditingController comentarioController = TextEditingController();
    String errorMessage = '';
    double faltante = totalPedido;
    bool totalCompletado = false;

    void _calcularCambio(StateSetter setState) {
      double totalPagado = (double.tryParse(efectivoController.text) ?? 0) +
          (double.tryParse(tarjetaController.text) ?? 0) +
          (double.tryParse(transferenciaController.text) ?? 0);

      setState(() {
        cambio = totalPagado - totalPedido;
        if (cambio < 0) {
          faltante = totalPedido - totalPagado;
          cambio = 0;
          totalCompletado = false;
        } else {
          faltante = 0;
          totalCompletado = true;
        }
      });
    }

    void _validarCantidad(
        StateSetter setState, TextEditingController controller) {
      double cantidad = double.tryParse(controller.text) ?? 0;
      if (cantidad > totalPedido) {
        setState(() {
          controller.text = totalPedido.toStringAsFixed(2);
        });
      }
      _calcularCambio(setState);
    }

    bool? shouldSave = await showDialog<bool>(
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
          builder: (context, setState) {
            return AlertDialog(
              actionsPadding: EdgeInsets.fromLTRB(50, 10, 50, 30),
              title: const Text(
                'Finalizar Pedido',
                style: TextStyle(fontSize: 22, fontWeight: FontWeight.w500),
              ),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  AppTextField(
                    controller: nombreController,
                    etiqueta: 'Nombre',
                    hintText: "Nombre del Cliente",
                    errorText: errorMessage.isEmpty ? null : errorMessage,
                    onChanged: (value) {
                      setState(() {
                        errorMessage = value.trim().isEmpty
                            ? "El nombre del cliente es obligatorio."
                            : '';
                      });
                    },
                  ),
                  const SizedBox(height: 10),
                  AppTextField(
                    controller: comentarioController,
                    etiqueta: 'Comentarios (opcional)',
                    hintText: 'Comentarios',
                    maxLines: 3,
                  ),
                  const SizedBox(height: 10),
                  Align(
                    alignment: Alignment.center,
                    child: Text(
                      'Métodos de pago',
                      style:
                          TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
                    ),
                  ),
                  const SizedBox(height: 10),
                  // Efectivo
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        children: [
                          Checkbox(
                            activeColor: AppTheme.primary,
                            value: efectivoSeleccionado,
                            onChanged:
                                (totalCompletado && !efectivoSeleccionado)
                                    ? null
                                    : (bool? value) {
                                        setState(() {
                                          efectivoSeleccionado = value ?? false;
                                          if (!efectivoSeleccionado) {
                                            efectivoController.clear();
                                            _calcularCambio(setState);
                                          }
                                        });
                                      },
                          ),
                          const Text(
                            "Efectivo",
                            style: TextStyle(
                                fontSize: 18, fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                      if (efectivoSeleccionado)
                        SizedBox(
                          width: 150,
                          child: AppTextField(
                            controller: efectivoController,
                            etiqueta: 'Cantidad',
                            hintText: '0.00',
                            keyboardType: TextInputType.number,
                            onChanged: (value) => _calcularCambio(setState),
                          ),
                        ),
                    ],
                  ),
                  const SizedBox(height: 10),
                  // Tarjeta
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        children: [
                          Checkbox(
                            activeColor: AppTheme.primary,
                            value: tarjetaSeleccionada,
                            onChanged: (totalCompletado && !tarjetaSeleccionada)
                                ? null
                                : (bool? value) {
                                    setState(() {
                                      tarjetaSeleccionada = value ?? false;
                                      if (!tarjetaSeleccionada) {
                                        tarjetaController.clear();
                                        _calcularCambio(setState);
                                      }
                                    });
                                  },
                          ),
                          const Text(
                            "Tarjeta",
                            style: TextStyle(
                                fontSize: 18, fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                      if (tarjetaSeleccionada)
                        SizedBox(
                          width: 150,
                          child: AppTextField(
                            controller: tarjetaController,
                            etiqueta: 'Cantidad',
                            hintText: '0.00',
                            keyboardType: TextInputType.number,
                            onChanged: (value) {
                              _validarCantidad(setState, tarjetaController);
                            },
                          ),
                        ),
                    ],
                  ),
                  const SizedBox(height: 10),
                  // Transferencia
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        children: [
                          Checkbox(
                            activeColor: AppTheme.primary,
                            value: transferenciaSeleccionada,
                            onChanged:
                                (totalCompletado && !transferenciaSeleccionada)
                                    ? null
                                    : (bool? value) {
                                        setState(() {
                                          transferenciaSeleccionada =
                                              value ?? false;
                                          if (!transferenciaSeleccionada) {
                                            transferenciaController.clear();
                                            _calcularCambio(setState);
                                          }
                                        });
                                      },
                          ),
                          const Text(
                            "Transferencia",
                            style: TextStyle(
                                fontSize: 18, fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                      if (transferenciaSeleccionada)
                        SizedBox(
                          width: 150,
                          child: AppTextField(
                            controller: transferenciaController,
                            etiqueta: 'Cantidad',
                            hintText: '0.00',
                            keyboardType: TextInputType.number,
                            onChanged: (value) {
                              _validarCantidad(
                                  setState, transferenciaController);
                            },
                          ),
                        ),
                    ],
                  ),
                  const SizedBox(height: 10),
                  // Mostrar el total del pedido y la cantidad faltante
                  Align(
                    alignment: Alignment.centerRight,
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.end,
                        children: [
                          Text(
                            'Total del pedido: \$${totalPedido.toStringAsFixed(2)}',
                            style: const TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 18),
                          ),
                          if (faltante > 0)
                            Text(
                              'Faltante: \$${faltante.toStringAsFixed(2)}',
                              style: const TextStyle(
                                  color: Colors.red,
                                  fontSize: 18,
                                  fontWeight: FontWeight.bold),
                            )
                          else if (cambio > 0)
                            Text('Cambio: \$${cambio.toStringAsFixed(2)}',
                                style: const TextStyle(
                                    color: Colors.green,
                                    fontSize: 18,
                                    fontWeight: FontWeight.bold)),
                        ]),
                  ),
                ],
              ),
              actions: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    TextButton(
                      child: const Text('Cancelar',
                          style: TextStyle(fontSize: 18)),
                      onPressed: () {
                        Navigator.of(context).pop(false);
                      },
                      style: ButtonStyle(
                          padding: MaterialStatePropertyAll(
                              EdgeInsets.fromLTRB(30, 20, 30, 20)),
                          backgroundColor: MaterialStatePropertyAll(Colors.red),
                          foregroundColor:
                              MaterialStatePropertyAll(AppTheme.secondary)),
                    ),
                    const SizedBox(width: 100),
                    TextButton(
                      child:
                          const Text('Guardar', style: TextStyle(fontSize: 18)),
                      onPressed: () {
                        if (nombreController.text.trim().isEmpty) {
                          setState(() => errorMessage =
                              "El nombre del cliente es obligatorio.");
                          return;
                        }
                        Navigator.of(context).pop(true);
                      },
                      style: ButtonStyle(
                          padding: MaterialStatePropertyAll(
                              EdgeInsets.fromLTRB(30, 20, 30, 20)),
                          backgroundColor:
                              MaterialStatePropertyAll(AppTheme.tertiary),
                          foregroundColor:
                              MaterialStatePropertyAll(AppTheme.quaternary)),
                    ),
                  ],
                )
              ],
            );
          },
        );
      },
    );

    if (shouldSave ?? false) {
      prepararPedidoActual(nombreController.text, comentarioController.text);
    }
  }

  void prepararPedidoActual(String nombreCliente, String comentarios) async {
    DateTime now = DateTime.now();
    String formattedDate = DateFormat('dd-MM-yyyy kk:mm:ss').format(now);

    Pedido nuevoPedido = Pedido(
      peticion: formattedDate,
      nombreCliente: nombreCliente,
      comentarios: comentarios,
      estatus: "NUEVO",
      totalPedido: totalPedido,
      descuento: pedidoActual?.descuento,
      tipoPago: _obtenerTipoPago(),
      cantEfectivo:
          efectivoSeleccionado ? double.tryParse(efectivoController.text) : 0,
      cantTarjeta:
          tarjetaSeleccionada ? double.tryParse(tarjetaController.text) : 0,
      cantTransferencia: transferenciaSeleccionada
          ? double.tryParse(transferenciaController.text)
          : 0,
    );

    List<PedidoProducto> listaPedidoProducto = carrito.map((item) {
      List<PedidoProductoTopping> selectedToppings = [];

      item.selectedToppings.forEach((categoryId, selectedToppingIds) {
        for (int toppingId in selectedToppingIds) {
          selectedToppings.add(PedidoProductoTopping(
            idTopping: toppingId,
          ));
        }
      });

      return PedidoProducto(
        idProducto: item.producto.id,
        producto: item.producto,
        costoUnitario: item.producto.precio,
        cantidad: item.cantidad,
        comentario: comentarios,
        toppings: selectedToppings,
      );
    }).toList();

    nuevoPedido.productos = listaPedidoProducto;

    bool result = await Provider.of<PedidoViewModel>(context, listen: false)
        .guardarPedidoLocal(pedido: nuevoPedido);

    if (!mounted) return;

    if (result) {
      Pedido? pedidoCompleto =
          await Provider.of<PedidoViewModel>(context, listen: false)
              .fetchPedidoConProductos(nuevoPedido.id!);

      if (pedidoCompleto != null) {
        imprimirTicketsJuntos(context, pedidoCompleto);
      }
      Navigator.of(context).pop();
    } else {
      print("Error al guardar el pedido");
    }
  }

  String _obtenerTipoPago() {
    List<String> tiposPago = [];
    if (efectivoSeleccionado) tiposPago.add('Efectivo');
    if (tarjetaSeleccionada) tiposPago.add('Tarjeta');
    if (transferenciaSeleccionada) tiposPago.add('Transferencia');
    return tiposPago.join(',');
  }

  void _limpiarBusqueda() async {
    setState(() {
      _busqueda.text = '';
      _estadoBusqueda = false;
    });
    await cargarCategoriasIniciales();
  }

  Future<void> cargarProductosIniciales() async {
    setState(() => _isLoading = true);
    await Provider.of<ProductoViewModel>(context, listen: false)
        .fetchLocalAll();
    productos =
        Provider.of<ProductoViewModel>(context, listen: false).productos;
    setState(() => _isLoading = false);
  }

  @override
  void dispose() {
    _gridViewController.dispose();
    _searchController.dispose();
    super.dispose();
  }

  Future<void> cargarCategoriasIniciales() async {
    setState(() => _isLoading = true);
    await Provider.of<CategoriaProductoViewModel>(context, listen: false)
        .fetchLocalAll();
    categorias = Provider.of<CategoriaProductoViewModel>(context, listen: false)
        .categoriaProductos;
    if (categorias.isNotEmpty) {
      categoriaSeleccionada = categorias.first;
      cargarProductosPorCategoria(categoriaSeleccionada!.id);
    }
    setState(() => _isLoading = false);
    if (categorias.isNotEmpty) {
      categoriaSeleccionada = categorias.first;
    }
  }

  void cargarProductosPorCategoria(int categoriaId) async {
    setState(() => _isLoading = true);
    await Provider.of<ProductoViewModel>(context, listen: false)
        .fetchAllByCategory(categoriaId);
    productos =
        Provider.of<ProductoViewModel>(context, listen: false).productos;
    setState(() => _isLoading = false);
  }

  void agregarAlCarrito(Producto producto) async {
    var existente = carrito.firstWhereOrNull((item) =>
        item.producto.id == producto.id &&
        mapEquals(item.selectedToppings, {}));

    if (existente != null) {
      setState(() {
        existente.cantidad++;
      });
    } else {
      Map<int, List<Producto>> toppingsSeleccionables =
          await obtenerToppingsSeleccionables(producto);

      setState(() {
        carrito.add(ItemCarrito(
          producto: producto,
          cantidad: 1,
          selectableToppings: toppingsSeleccionables,
        ));
      });
    }
    _recalcularTotal();
  }

  Future<Map<int, List<Producto>>> obtenerToppingsSeleccionables(
      Producto producto) async {
    Map<int, List<Producto>> toppingsSeleccionables = {};
    final toppingCategories =
        await pvm.obtenerToppingsPorProducto(producto.id!);

    for (int toppingId in toppingCategories) {
      Producto? topping = await pvm.obtenerProductoPorId(toppingId);
      if (topping != null && topping.idCategoria != null) {
        toppingsSeleccionables[topping.idCategoria!] ??= [];
        toppingsSeleccionables[topping.idCategoria]!.add(topping);
      }
    }
    return toppingsSeleccionables;
  }

  void quitarDelCarrito(Producto producto) {
    setState(() {
      var indice =
          carrito.indexWhere((item) => item.producto.id == producto.id);
      if (indice != -1) {
        if (carrito[indice].cantidad > 1) {
          carrito[indice].cantidad--;
        } else {
          carrito.removeAt(indice);
        }
      }
    });
  }

  void addToCart(Producto producto) {
    var existingIndex = carrito.indexWhere((item) =>
        item.producto.id == producto.id &&
        mapEquals(item.selectedToppings, {}));

    if (existingIndex != -1) {
      setState(() {
        carrito[existingIndex].cantidad++;
      });
    } else {
      setState(() {
        carrito.add(ItemCarrito(producto: producto, cantidad: 1));
      });
    }
  }

  void finalizeCustomization() {
    if (_productoActual != null) {
      addToCart(_productoActual!);
      setState(() {
        _productoActual = null;
      });
    }
  }

  Widget _buildDiscountSection() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          const Text(
            'Descuento',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
          ),
          const Spacer(),
          ConstrainedBox(
            constraints: const BoxConstraints(
              maxWidth: 150,
            ),
            child: Consumer<DescuentoViewModel>(
              builder: (context, viewModel, child) {
                return AppDropdownModel<int>(
                  hint: 'Seleccionar',
                  items: viewModel.descuentos
                      .map(
                        (descuento) => DropdownMenuItem<int>(
                          value: descuento.porcentaje,
                          child: Text(
                            '${descuento.porcentaje}%',
                            style: const TextStyle(color: Colors.black),
                          ),
                        ),
                      )
                      .toList(),
                  selectedValue: selectedDescuento,
                  onChanged: (value) {
                    setState(() {
                      selectedDescuento = value;
                      _recalcularTotal();
                    });
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildTotalSection() {
    String formattedsubtotal = _numberFormat.format(subtotal);
    String formattedPrecioDescuento = _numberFormat.format(precioDescuento);
    String formattedtotalPedido = _numberFormat.format(totalPedido);

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (precioDescuento > 0)
            Column(
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    const Text('Subtotal',
                        style: TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 18)),
                    Text("\$$formattedsubtotal",
                        style: const TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 18)),
                  ],
                ),
                const SizedBox(height: 10),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    const Text('Descuento',
                        style: TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 18)),
                    Text("-\$$formattedPrecioDescuento",
                        style: const TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 18)),
                  ],
                ),
              ],
            ),
          const SizedBox(height: 10),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text('Total',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
              Text("\$$formattedtotalPedido",
                  style: const TextStyle(
                      fontWeight: FontWeight.bold, fontSize: 18)),
            ],
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title:
              Text("Crear Pedido", style: TextStyle(color: AppTheme.secondary)),
          iconTheme: IconThemeData(color: AppTheme.secondary)),
      body: Row(
        children: [
          Flexible(
            flex: 3,
            child: _buildCartSection(),
          ),
          SizedBox(width: 35),
          Flexible(flex: 7, child: _buildProductsSection()),
        ],
      ),
    );
  }

  Widget _buildCartSection() {
    return Card(
      margin: const EdgeInsets.all(8.0),
      child: Column(
        children: [
          const Padding(
            padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 16.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text('Producto',
                    style:
                        TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
                Text('Cantidad',
                    style:
                        TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: carrito.length,
              itemBuilder: (context, index) {
                final item = carrito[index];

                return Column(
                  children: [
                    ListTile(
                      title: Text(item.producto.nombre!,
                          style: const TextStyle(fontWeight: FontWeight.w600)),
                      subtitle: Text('\$${item.producto.precio}',
                          style: const TextStyle(
                              fontWeight: FontWeight.bold,
                              color: Color(0xFF008000))),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          IconButton(
                              icon: const Icon(Icons.delete, color: Colors.red),
                              onPressed: () =>
                                  eliminarProductoDelCarrito(index)),
                          IconButton(
                              icon: const Icon(Icons.remove),
                              onPressed: () => quitarProductoDelCarrito(item)),
                          const SizedBox(width: 5),
                          Text('${item.cantidad}',
                              style: const TextStyle(
                                  fontWeight: FontWeight.bold, fontSize: 14)),
                          const SizedBox(width: 5),
                          IconButton(
                              icon: const Icon(Icons.add),
                              onPressed: () => incrementarProducto(item)),
                        ],
                      ),
                    ),
                    if (item.selectableToppings.isNotEmpty)
                      ExpansionTile(
                        title: Text('Toppings',
                            style: const TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 16)),
                        children: item.selectableToppings.entries.map((entry) {
                          final categoryId = entry.key;
                          final availableToppings = entry.value;
                          final categoria =
                              categorias.firstWhere((c) => c.id == categoryId);

                          return Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Padding(
                                padding: const EdgeInsets.only(left: 16.0),
                                child: Text(
                                  categoria.descripcion!,
                                  style: const TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 16),
                                ),
                              ),
                              ...availableToppings.map((topping) {
                                ValueNotifier<bool> isSelectedNotifier =
                                    ValueNotifier<bool>(
                                  item.selectedToppings[categoryId]
                                          ?.contains(topping.id) ??
                                      false,
                                );

                                return ValueListenableBuilder<bool>(
                                  valueListenable: isSelectedNotifier,
                                  builder: (context, isSelected, _) {
                                    return CheckboxListTile(
                                      activeColor: AppTheme.primary,
                                      title: Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.spaceBetween,
                                        children: [
                                          Text(topping.nombre!),
                                          if (double.tryParse(
                                                  topping.precio!) !=
                                              0.0)
                                            Text(
                                              '+\$${topping.precio}',
                                              style: TextStyle(
                                                color: Colors.black,
                                                fontSize: 13,
                                              ),
                                            ),
                                        ],
                                      ),
                                      value: isSelected,
                                      onChanged: (bool? value) {
                                        final maximoToppings =
                                            categoria.maximo ?? 0;

                                        if (value == true) {
                                          if ((item.selectedToppings[categoryId]
                                                      ?.length ??
                                                  0) >=
                                              maximoToppings) {
                                            item.selectedToppings[categoryId]!
                                                .remove(item
                                                    .selectedToppings[
                                                        categoryId]!
                                                    .first);
                                          }
                                          item.selectedToppings[categoryId] ??=
                                              <int>{};
                                          item.selectedToppings[categoryId]!
                                              .add(topping.id!);
                                        } else {
                                          item.selectedToppings[categoryId]
                                              ?.remove(topping.id!);
                                          if (item.selectedToppings[categoryId]
                                                  ?.isEmpty ??
                                              false) {
                                            item.selectedToppings
                                                .remove(categoryId);
                                          }
                                        }
                                        setState(() {});
                                        _recalcularTotal();
                                      },
                                    );
                                  },
                                );
                              }).toList(),
                            ],
                          );
                        }).toList(),
                      ),
                    Divider(),
                  ],
                );
              },
            ),
          ),
          _buildDiscountSection(),
          const Divider(thickness: 5),
          _buildTotalSection(),
          const SizedBox(height: 25),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: ElevatedButton(
              onPressed: _finalizeOrder,
              style: ElevatedButton.styleFrom(
                primary: AppTheme.tertiary,
                textStyle: const TextStyle(fontSize: 22),
                fixedSize: const Size(250, 50),
              ),
              child: Text('Finalizar Pedido',
                  style: TextStyle(color: AppTheme.quaternary)),
            ),
          ),
        ],
      ),
    );
  }

  void eliminarProductoDelCarrito(int index) {
    setState(() {
      carrito.removeAt(index);
    });
    _recalcularTotal();
  }

  void incrementarProducto(ItemCarrito item) {
    setState(() {
      item.cantidad++;
    });
    _recalcularTotal();
  }

  void quitarProductoDelCarrito(ItemCarrito item) {
    setState(() {
      if (item.cantidad > 1) {
        item.cantidad--;
      } else {
        carrito.remove(item);
      }
    });
    _recalcularTotal();
  }

  Widget _buildProductsSection() {
    return Column(
      children: [
        const SizedBox(height: 10),
        _buildCategoryButtons(),
        const SizedBox(height: 15),
        Expanded(
          child: Consumer<ProductoViewModel>(builder: (context, model, child) {
            productos = model.productos;
            return GridView.builder(
              controller: _gridViewController,
              key: ValueKey<int>(categoriaSeleccionada?.id ?? 0),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                childAspectRatio: 3 / 2,
              ),
              itemCount: productos.length,
              itemBuilder: (context, index) {
                final producto = productos[index];
                if (producto.idCategoria != categoriaSeleccionada?.id) {
                  return Container();
                }
                return Card(
                  child: InkWell(
                    onTap: () => agregarAlCarrito(producto),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        if (producto.imagen != null &&
                            File(producto.imagen!).existsSync())
                          Image.file(
                            File(producto.imagen!),
                            height: 120,
                            fit: BoxFit.cover,
                          )
                        else
                          const Icon(Icons.fastfood, size: 80),
                        const SizedBox(height: 8),
                        Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 8.0),
                          child: Text(
                            producto.nombre ?? '',
                            style: const TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.bold,
                            ),
                            textAlign: TextAlign.center,
                          ),
                        ),
                        const SizedBox(height: 8),
                        Text(
                          '\$${producto.precio}',
                          style: const TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.bold,
                            color: Color(0xFF008000),
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              },
            );
          }),
        )
      ],
    );
  }

  Widget _buildCategoryButtons() {
    List<CategoriaProducto> categoriasFiltradas =
        categorias.where((categoria) => categoria.esToping == 0).toList();

    return Container(
      height: 50,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: categoriasFiltradas.length,
        itemBuilder: (context, index) {
          final categoria = categoriasFiltradas[index];
          bool isSelected = categoriaSeleccionada?.id == categoria.id;
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 4.0),
            child: ElevatedButton(
              onPressed: () {
                cargarProductosPorCategoria(categoria.id);
                setState(() {
                  categoriaSeleccionada = categoria;
                });
              },
              style: ElevatedButton.styleFrom(
                primary: isSelected ? AppTheme.tertiary : Colors.grey,
                foregroundColor:
                    isSelected ? AppTheme.quaternary : AppTheme.secondary,
                onPrimary: AppTheme.secondary,
              ),
              child: Text(categoria.nombre!),
            ),
          );
        },
      ),
    );
  }

  Widget _buildSearchBar() {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: TextField(
        controller: _searchController,
        decoration: InputDecoration(
          hintText: 'Buscar producto...',
          prefixIcon: const Icon(Icons.search),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(12.0),
          ),
        ),
        onChanged: _onSearchChanged,
      ),
    );
  }
}
