import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:otp/otp.dart';
import 'package:provider/provider.dart';
import '/data/session/session_storage.dart';
import '/views/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';
import 'package:uuid/uuid.dart';
import '../../services/services.dart';
import 'package:timezone/data/latest.dart' as timezone;
import 'package:timezone/timezone.dart' as timezone;

class PedidoForm extends StatefulWidget {
  final Pedido? pedidoExistente;

  const PedidoForm({Key? key, this.pedidoExistente}) : super(key: key);

  @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();
  ScrollController _categoryScrollController = 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();
  TextEditingController _propinaCantidadController = TextEditingController();
  TextEditingController _propinaComentarioController = TextEditingController();
  double cambio = 0.0;
  double faltante = 0.0;
  bool totalCompletado = false;
  bool _isMesasActive = false;

  double calcularTotalPedido() {
    double total = 0;

    for (var item in carrito) {
      total += 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 += (topping.precio ?? 0.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();

    pedidoActual = widget.pedidoExistente ?? Pedido(id: 0);
    Future.microtask(() async {
      bool isMesasActive =
          await Provider.of<VariableViewModel>(context, listen: false)
              .isVariableActive('MESAS');
      setState(() {
        _isMesasActive = isMesasActive;
      });

      if (pedidoActual != null && pedidoActual!.id! > 0) {
        await _cargarPedidoExistente(pedidoActual!.id!);
      }
    });

    cargarCategoriasIniciales().then((_) {
      if (categorias.isNotEmpty) {
        categoriaSeleccionada = categorias.first;
        cargarProductosPorCategoria(categoriaSeleccionada!.id);
      }
    });

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

  Future<void> _cargarPedidoExistente(int pedidoId) async {
    Pedido? pedidoCompleto =
        await Provider.of<PedidoViewModel>(context, listen: false)
            .fetchPedidoConProductos(pedidoId);

    if (pedidoCompleto != null) {
      setState(() {
        pedidoActual = pedidoCompleto;
        carrito = pedidoCompleto.productos.map((producto) {
          return ItemCarrito(
            producto: producto.producto!,
            cantidad: producto.cantidad!,
            comentario: producto.comentario,
            selectedToppings: producto.toppings.fold<Map<int, Set<int>>>(
              {},
              (acc, topping) {
                acc[topping.idCategoria!] ??= {};
                acc[topping.idCategoria]!.add(topping.idTopping!);
                return acc;
              },
            ),
          );
        }).toList();
      });

      selectedDescuento = pedidoCompleto.descuento ?? 0;

      _recalcularTotal();
    }
  }

  void _onSearchChanged(String value) async {
    if (value.isEmpty) {
      cargarProductosPorCategoria(
          categoriaSeleccionada?.id ?? categorias.first.id);
    } else {
      setState(() {
        _estadoBusqueda = true;
      });

      await Provider.of<ProductoViewModel>(context, listen: false)
          .fetchLocalByName(nombre: value);

      setState(() {
        productos =
            Provider.of<ProductoViewModel>(context, listen: false).productos;
      });
    }
  }

  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');
  }

  bool validarMinimosSeleccionados() {
    for (var item in carrito) {
      for (var categoriaId in item.selectableToppings.keys) {
        final categoria = categorias.firstWhere((c) => c.id == categoriaId);
        final minimoRequerido = categoria.minimo ?? 0;
        final seleccionados = item.selectedToppings[categoriaId]?.length ?? 0;

        if (minimoRequerido > 0 && seleccionados < minimoRequerido) {
          showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Faltan Toppings',
                    style:
                        TextStyle(fontWeight: FontWeight.w500, fontSize: 22)),
                content: Text(
                    'El producto ${item.producto.nombre} requiere que seleccione al menos $minimoRequerido topping en la categoría ${categoria.nombre}.',
                    style: TextStyle(fontSize: 18)),
                actions: <Widget>[
                  TextButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: const Text('Aceptar'),
                      style: ButtonStyle(
                          padding: MaterialStatePropertyAll(
                              EdgeInsets.fromLTRB(20, 10, 20, 10)),
                          backgroundColor:
                              MaterialStatePropertyAll(AppTheme.tertiary),
                          foregroundColor:
                              MaterialStatePropertyAll(AppTheme.quaternary))),
                ],
              );
            },
          );
          return false;
        }
      }
    }
    return true;
  }

  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;
    }
    if (!validarMinimosSeleccionados()) {
      return;
    }

    await _promptForCustomerName();
  }

  void _mostrarDialogoPedidoVacio() {
    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 crear un pedido sin productos. Por favor, agrega al menos un producto.',
              style: TextStyle(fontSize: 18)),
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
          actions: <Widget>[
            TextButton(
              style: TextButton.styleFrom(
                  padding: const 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)),
            ),
          ],
        );
      },
    );
  }

  Future<void> _crearPedidoConModal() async {
    if (carrito.isEmpty) {
      _mostrarDialogoPedidoVacio();
      return;
    }

    TextEditingController nombreController = TextEditingController();
    TextEditingController descripcionController = TextEditingController();
    TextEditingController mesaSearchController = TextEditingController();

    Mesa? mesaSeleccionada;

    // Inicializa las mesas disponibles
    await Provider.of<MesaViewModel>(context, listen: false).fetchLocalAll();
    List<Mesa> mesasDisponibles =
        Provider.of<MesaViewModel>(context, listen: false).mesas;

    bool? shouldSave = await showDialog<bool>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text(
            'Crear Pedido',
            style: TextStyle(fontSize: 22, fontWeight: FontWeight.w500),
          ),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              AppTextField(
                controller: nombreController,
                etiqueta: 'Nombre del Cliente',
                hintText: 'Nombre del Cliente',
              ),
              const SizedBox(height: 10),
              AppTextField(
                controller: descripcionController,
                etiqueta: 'Descripción',
                hintText: 'Descripción del Pedido',
              ),
              const SizedBox(height: 10),
              AppDropdownSearch(
                controller: mesaSearchController,
                etiqueta: 'Seleccionar Mesa',
                asyncItems: (String query) async {
                  await Provider.of<MesaViewModel>(context, listen: false)
                      .fetchLocalByName(nombre: query);
                  return Provider.of<MesaViewModel>(context, listen: false)
                      .mesas;
                },
                itemAsString: (dynamic mesa) =>
                    (mesa as Mesa).nombre ?? 'Sin Nombre',
                selectedItem: mesaSeleccionada,
                onChanged: (dynamic nuevaMesa) {
                  mesaSeleccionada = nuevaMesa as Mesa;
                },
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(false),
              child: const Text('Cancelar'),
              style: ButtonStyle(
                padding: MaterialStatePropertyAll(
                  EdgeInsets.fromLTRB(20, 10, 20, 10),
                ),
                backgroundColor: MaterialStatePropertyAll(Colors.red),
                foregroundColor: MaterialStatePropertyAll(AppTheme.secondary),
              ),
            ),
            const SizedBox(width: 10),
            TextButton(
              onPressed: () {
                if (mesaSeleccionada != null) {
                  Navigator.of(context).pop(true);
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(
                      content: Text('Seleccione una mesa por favor'),
                    ),
                  );
                }
              },
              child: const Text('Guardar'),
              style: ButtonStyle(
                padding: MaterialStatePropertyAll(
                  EdgeInsets.fromLTRB(20, 10, 20, 10),
                ),
                backgroundColor: MaterialStatePropertyAll(Colors.black),
                foregroundColor: MaterialStatePropertyAll(AppTheme.quaternary),
              ),
            ),
          ],
        );
      },
    );

    if (shouldSave ?? false) {
      Pedido nuevoPedido = Pedido(
        peticion: DateTime.now().toUtc().toIso8601String(),
        nombreCliente: nombreController.text,
        comentarios: descripcionController.text,
        estatus: 'NUEVO',
        idMesa: mesaSeleccionada?.id,
        totalPedido: totalPedido,
        descuento: selectedDescuento,
        uuid: Uuid().v4(),
        idUsuario: await SessionStorage().getId(),
        productos: carrito.map((item) {
          return PedidoProducto(
            idProducto: item.producto.id,
            producto: item.producto,
            costoUnitario: item.producto.precio.toString(),
            cantidad: item.cantidad,
            comentario: item.comentario,
            toppings: item.selectedToppings.entries.expand((entry) {
              return entry.value.map((toppingId) {
                return PedidoProductoTopping(
                  idCategoria: entry.key,
                  idTopping: toppingId,
                );
              });
            }).toList(),
          );
        }).toList(),
      );

      final corteViewModel =
          Provider.of<CorteCajaViewModel>(context, listen: false);
      CorteCaja? corteActivo = corteViewModel.cortes.firstWhereOrNull(
        (corte) => corte.fechaCorte == null,
      );
      if (corteActivo != null) {
        nuevoPedido.idCorteCaja = corteActivo.id;
      }

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

      if (result) {
        Navigator.of(context).pop();
      } else {
        print('Error al guardar el pedido');
      }
    }
  }

  Future<void> _guardarPedidoExistente({
    double? cantEfectivo,
    double? cantTarjeta,
    double? cantTransferencia,
    String? tipoPago,
    String? estatus,
  }) async {
    if (pedidoActual == null) return;
    DateTime now = DateTime.now().toUtc();

    pedidoActual!.totalPedido = totalPedido;
    pedidoActual!.descuento = selectedDescuento;
    pedidoActual!.modificado = now;
    pedidoActual!.sincronizado = null;

    if (cantEfectivo != null) pedidoActual!.cantEfectivo = cantEfectivo;
    if (cantTarjeta != null) pedidoActual!.cantTarjeta = cantTarjeta;
    if (cantTransferencia != null)
      pedidoActual!.cantTransferencia = cantTransferencia;
    if (tipoPago != null) pedidoActual!.tipoPago = tipoPago;
    if (estatus != null) pedidoActual!.estatus = estatus;

    bool result = await Provider.of<PedidoViewModel>(context, listen: false)
        .guardarPedidoConProductos(
      pedido: pedidoActual!,
      carrito: carrito,
    );

    if (result) {
      Pedido? pedidoCompleto =
          await Provider.of<PedidoViewModel>(context, listen: false)
              .fetchPedidoConProductos(pedidoActual!.id);
      if (estatus == "TERMINADO") {
        imprimirTicketsJuntos(context, pedidoCompleto!);
      }
      print("Pedido actualizado correctamente");
      Navigator.of(context).pop();
    } else {
      print("Error al actualizar el pedido");
    }
  }

  Future<void> _promptForCustomerName() async {
    TextEditingController efectivoController = TextEditingController();
    TextEditingController tarjetaController = TextEditingController();
    TextEditingController transferenciaController = TextEditingController();
    TextEditingController? nombreController;
    TextEditingController? comentarioController;

    if (pedidoActual == null || pedidoActual!.id == 0) {
      nombreController = TextEditingController();
      comentarioController = TextEditingController();
    }

    faltante = totalPedido;
    bool totalCompletado = false;
    bool efectivoCompleto = false;
    bool tarjetaCompleto = false;
    bool transferenciaCompleto = false;
    bool propinaExpandida = 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;
        faltante = cambio < 0 ? totalPedido - totalPagado : 0;
        totalCompletado = cambio >= 0;
      });
    }

    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: SingleChildScrollView(
                child: AnimatedSize(
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.easeInOut,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      if (nombreController != null)
                        AppTextField(
                          controller: nombreController,
                          etiqueta: 'Nombre',
                          hintText: "Nombre del Cliente",
                        ),
                      if (comentarioController != null) ...[
                        const SizedBox(height: 10),
                        AppTextField(
                          controller: comentarioController,
                          etiqueta: 'Comentarios (opcional)',
                          hintText: 'Comentarios',
                          maxLines: 2,
                        ),
                      ],
                      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
                      _buildPaymentMethodRow(
                        setState,
                        label: 'Efectivo',
                        selected: efectivoSeleccionado,
                        exactSelected: efectivoCompleto,
                        controller: efectivoController,
                        onSelected: (value) {
                          setState(() {
                            efectivoSeleccionado = value;
                            if (!efectivoSeleccionado) {
                              efectivoCompleto = false;
                              efectivoController.clear();
                            }
                            _calcularCambio(setState);
                          });
                        },
                        onExactSelected: (value) {
                          setState(() {
                            efectivoCompleto = value;
                            if (efectivoCompleto) {
                              efectivoController.text =
                                  totalPedido.toStringAsFixed(2);
                              efectivoSeleccionado = true;
                              tarjetaSeleccionada = false;
                              transferenciaSeleccionada = false;
                              tarjetaController.clear();
                              transferenciaController.clear();
                            } else {
                              efectivoController.clear();
                            }
                            _calcularCambio(setState);
                          });
                        },
                        disableOtherMethods:
                            tarjetaCompleto || transferenciaCompleto,
                        onChangedMonto: () => _calcularCambio(setState),
                      ),
                      // Tarjeta
                      _buildPaymentMethodRow(
                        setState,
                        label: 'Tarjeta',
                        selected: tarjetaSeleccionada,
                        exactSelected: tarjetaCompleto,
                        controller: tarjetaController,
                        sinCambio: true,
                        onSelected: (value) {
                          setState(() {
                            tarjetaSeleccionada = value;
                            if (!tarjetaSeleccionada) {
                              tarjetaCompleto = false;
                              tarjetaController.clear();
                            }
                            _calcularCambio(setState);
                          });
                        },
                        onExactSelected: (value) {
                          setState(() {
                            tarjetaCompleto = value;
                            if (tarjetaCompleto) {
                              tarjetaController.text =
                                  totalPedido.toStringAsFixed(2);
                              tarjetaSeleccionada = true;
                              efectivoSeleccionado = false;
                              transferenciaSeleccionada = false;
                              efectivoController.clear();
                              transferenciaController.clear();
                            } else {
                              tarjetaController.clear();
                            }
                            _calcularCambio(setState);
                          });
                        },
                        disableOtherMethods:
                            efectivoCompleto || transferenciaCompleto,
                        onChangedMonto: () => _calcularCambio(setState),
                      ),
                      // Transferencia
                      _buildPaymentMethodRow(
                        setState,
                        label: 'Transferencia',
                        selected: transferenciaSeleccionada,
                        exactSelected: transferenciaCompleto,
                        controller: transferenciaController,
                        sinCambio: true,
                        onSelected: (value) {
                          setState(() {
                            transferenciaSeleccionada = value;
                            if (!transferenciaSeleccionada) {
                              transferenciaCompleto = false;
                              transferenciaController.clear();
                            }
                            _calcularCambio(setState);
                          });
                        },
                        onExactSelected: (value) {
                          setState(() {
                            transferenciaCompleto = value;
                            if (transferenciaCompleto) {
                              transferenciaController.text =
                                  totalPedido.toStringAsFixed(2);
                              transferenciaSeleccionada = true;
                              efectivoSeleccionado = false;
                              tarjetaSeleccionada = false;
                              efectivoController.clear();
                              tarjetaController.clear();
                            } else {
                              transferenciaController.clear();
                            }
                            _calcularCambio(setState);
                          });
                        },
                        disableOtherMethods:
                            efectivoCompleto || tarjetaCompleto,
                        onChangedMonto: () => _calcularCambio(setState),
                      ),
                      // Propina Expandable
                      ExpansionTile(
                        title: const Text(
                          'Agregar Propina',
                          style: TextStyle(
                              fontSize: 18, fontWeight: FontWeight.bold),
                        ),
                        initiallyExpanded: propinaExpandida,
                        onExpansionChanged: (isExpanded) {
                          setState(() {
                            propinaExpandida = isExpanded;
                          });
                        },
                        children: [
                          AppTextField(
                            separarMiles: true,
                            controller: _propinaCantidadController,
                            etiqueta: 'Propina',
                            hintText: '0.00',
                            keyboardType: TextInputType.number,
                          ),
                          const SizedBox(height: 10),
                          AppTextField(
                            controller: _propinaComentarioController,
                            etiqueta: 'Comentario',
                            hintText: 'Comentario',
                            maxLines: 2,
                          ),
                        ],
                      ),
                      const SizedBox(height: 10),
                      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: [
                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: totalCompletado
                      ? () => Navigator.of(context).pop(true)
                      : null,
                  style: ButtonStyle(
                    padding: MaterialStatePropertyAll(
                        EdgeInsets.fromLTRB(30, 20, 30, 20)),
                    backgroundColor: MaterialStatePropertyAll(
                        totalCompletado ? AppTheme.tertiary : Colors.grey),
                    foregroundColor:
                        MaterialStatePropertyAll(AppTheme.quaternary),
                  ),
                ),
              ],
            );
          },
        );
      },
    );

    if (shouldSave ?? false) {
      if (pedidoActual != null && pedidoActual!.id != 0) {
        await _guardarPedidoExistente(
          cantEfectivo: double.tryParse(efectivoController.text),
          cantTarjeta: double.tryParse(tarjetaController.text),
          cantTransferencia: double.tryParse(transferenciaController.text),
          tipoPago: _obtenerTipoPago(),
          estatus: "TERMINADO",
        );

        await _guardarPropina(pedidoActual!.id!);
      } else {
        prepararPedidoActual(
          nombreController?.text ?? '',
          comentarioController?.text ?? '',
          efectivoController,
          tarjetaController,
          transferenciaController,
        );
      }
    }
  }

  Future<void> _guardarPropina(int idPedido) async {
    double? cantidad =
        double.tryParse(_propinaCantidadController.text.replaceAll(',', '')) ??
            0.0;
    String comentario = _propinaComentarioController.text.trim();

    if (cantidad != null && cantidad > 0) {
      Propinas nuevaPropina = Propinas(
        idPedido: idPedido,
        cantidad: cantidad,
        comentario: comentario,
        sincronizado: null,
        creado: DateTime.now().toUtc(),
      );

      await Provider.of<PropinaViewModel>(context, listen: false)
          .guardarPropina(nuevaPropina);
      print('Propina guardada correctamente');
    } else {
      print('Propina no guardada (cantidad inválida)');
    }
  }

  Widget _buildPaymentMethodRow(
    StateSetter setState, {
    required String label,
    required bool selected,
    required bool exactSelected,
    required TextEditingController controller,
    required Function(bool) onSelected,
    required Function(bool) onExactSelected,
    required bool disableOtherMethods,
    required Function() onChangedMonto,
    bool sinCambio = false,
  }) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Row(
          children: [
            Checkbox(
              activeColor: AppTheme.primary,
              value: selected,
              onChanged: disableOtherMethods
                  ? null
                  : (value) {
                      onSelected(value ?? false);
                    },
            ),
            GestureDetector(
              onTap: disableOtherMethods
                  ? null
                  : () {
                      onSelected(!selected);
                    },
              child: Text(
                label,
                style:
                    const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
            ),
          ],
        ),
        SizedBox(
          width: 180,
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Column(
                children: [
                  const Text(
                    'Exacto',
                    style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        color: Colors.black),
                  ),
                  const SizedBox(height: 17),
                  Checkbox(
                    activeColor: AppTheme.primary,
                    value: exactSelected,
                    onChanged: !disableOtherMethods
                        ? (value) {
                            onExactSelected(value ?? false);
                            if (value == true) {
                              setState(() {
                                disableOtherMethods = true;
                              });
                            }
                          }
                        : null,
                  ),
                ],
              ),
              const SizedBox(width: 5),
              Expanded(
                child: AppTextField(
                  controller: controller,
                  enabled: selected,
                  etiqueta: 'Cantidad',
                  hintText: '0.00',
                  keyboardType: TextInputType.number,
                  onChanged: (value) {
                    if (sinCambio) {
                      double? input = double.tryParse(value) ?? 0;
                      if (input > totalPedido) {
                        controller.text = totalPedido.toStringAsFixed(2);
                        controller.selection = TextSelection.fromPosition(
                          TextPosition(offset: controller.text.length),
                        );
                      }
                    }
                    onChangedMonto();
                  },
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  void prepararPedidoActual(
    String nombreCliente,
    String comentarios,
    TextEditingController efectivoController,
    TextEditingController tarjetaController,
    TextEditingController transferenciaController,
  ) async {
    String now = DateTime.now().toUtc().toIso8601String();
    int? idUsuario = await SessionStorage().getId();

    double cantEfectivo = efectivoSeleccionado
        ? double.tryParse(efectivoController.text) ?? 0
        : 0;
    double cantTarjeta =
        tarjetaSeleccionada ? double.tryParse(tarjetaController.text) ?? 0 : 0;
    double cantTransferencia = transferenciaSeleccionada
        ? double.tryParse(transferenciaController.text) ?? 0
        : 0;

    Pedido nuevoPedido = Pedido(
      peticion: now,
      nombreCliente: nombreCliente,
      comentarios: comentarios,
      estatus: "TERMINADO",
      totalPedido: totalPedido,
      descuento: pedidoActual?.descuento,
      idUsuario: idUsuario,
      tipoPago: _obtenerTipoPago(),
      cantEfectivo: cantEfectivo,
      cantTarjeta: cantTarjeta,
      cantTransferencia: cantTransferencia,
      uuid: Uuid().v4(),
    );

    final corteViewModel =
        Provider.of<CorteCajaViewModel>(context, listen: false);
    CorteCaja? corteActivo = corteViewModel.cortes.firstWhereOrNull(
      (corte) => corte.fechaCorte == null,
    );
    if (corteActivo != null) {
      nuevoPedido.idCorteCaja = corteActivo.id;
    }

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

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

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

    nuevoPedido.productos = listaPedidoProducto;

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

    await _guardarPropina(nuevoPedido.id!);

    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.isNotEmpty ? tiposPago.join(',') : 'No Definido';
  }

  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();
    _categoryScrollController.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) async {
                    if (value != null && value != selectedDescuento) {
                      // Guardar el valor anterior
                      final previousValue = selectedDescuento;

                      // Actualizar el descuento temporalmente
                      print('Descuento temporal seleccionado: $value');
                      setState(() {
                        selectedDescuento = value;
                      });

                      // Mostrar cuadro de confirmación
                      final authenticated = await showDialog<bool>(
                        context: context,
                        builder: (context) {
                          return TotpCuadroConfirmacion(
                            title: "Aplicar Descuento",
                            content:
                                "Por favor, ingresa el código de autenticación para continuar.",
                            onSuccess: () {
                              // Confirmación exitosa: recalcular total y actualizar UI
                              print(
                                  'Autenticación exitosa. Aplicando descuento...');
                              setState(() {
                                _recalcularTotal();
                                print('Descuento aplicado: $selectedDescuento');
                                print('Total recalculado: $totalPedido');
                              });
                            },
                          );
                        },
                      );

                      // Si la autenticación falla, revertir el descuento
                      if (authenticated != true) {
                        print(
                            'Autenticación fallida. Revirtiendo descuento...');
                        setState(() {
                          selectedDescuento = previousValue;
                          _recalcularTotal(); // Recalcular con el valor anterior
                          print('Descuento revertido: $selectedDescuento');
                          print(
                              'Total recalculado tras revertir: $totalPedido');
                        });
                      }
                    }
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  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: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(item.producto.nombre!,
                                  style: const TextStyle(
                                      fontWeight: FontWeight.w600,
                                      fontSize: 16)),
                              Text('\$${item.producto.precio}',
                                  style: const TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 14,
                                      color: Color(0xFF008000))),
                            ],
                          ),
                        ),
                        Row(
                          children: [
                            IconButton(
                              icon: const Icon(Icons.delete, color: Colors.red),
                              onPressed: () =>
                                  eliminarProductoDelCarrito(index),
                            ),
                            IconButton(
                              icon: const Icon(Icons.remove),
                              onPressed: () => quitarProductoDelCarrito(item),
                            ),
                            Text('${item.cantidad}',
                                style: const TextStyle(
                                    fontWeight: FontWeight.bold, fontSize: 14)),
                            IconButton(
                              icon: const Icon(Icons.add),
                              onPressed: () => incrementarProducto(item),
                            ),
                            IconButton(
                              icon:
                                  Icon(Icons.message, color: AppTheme.tertiary),
                              onPressed: () {
                                setState(() {
                                  item.expandido = !item.expandido;
                                });
                              },
                            ),
                          ],
                        ),
                      ],
                    ),
                    if (item.expandido) ...[
                      const SizedBox(height: 5),
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 16.0),
                        child: TextField(
                          controller: item.comentarioController,
                          decoration: const InputDecoration(
                            hintText: 'Agregar un comentario...',
                            border: OutlineInputBorder(),
                          ),
                          maxLines: 2,
                          onChanged: (value) {
                            item.comentario = value.trim();
                          },
                        ),
                      ),
                    ],
                    // ExpansionTile para todos los toppings
                    if (item.selectableToppings.isNotEmpty)
                      ExpansionTile(
                        initiallyExpanded: true,
                        title: const Text(
                          'Toppings',
                          style: 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 ExpansionTile(
                            initiallyExpanded: true,
                            title: Text(
                              '${categoria.nombre}'
                              ' (Hasta ${categoria.maximo ?? 0})'
                              ' ${(categoria.minimo ?? 0) > 0 ? " (Mínimo ${categoria.minimo})" : ""}',
                              style: const TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 16,
                              ),
                            ),
                            children: availableToppings.map((topping) {
                              bool isSelected = item
                                      .selectedToppings[categoryId]
                                      ?.contains(topping.id) ??
                                  false;
                              return CheckboxListTile(
                                activeColor: AppTheme.primary,
                                title: Row(
                                  mainAxisAlignment:
                                      MainAxisAlignment.spaceBetween,
                                  children: [
                                    Text(topping.nombre!),
                                    if (topping.precio != 0.0)
                                      Text(
                                        '+\$${topping.precio}',
                                        style: const TextStyle(
                                          color: Colors.black,
                                          fontSize: 13,
                                        ),
                                      ),
                                  ],
                                ),
                                value: isSelected,
                                onChanged: (bool? value) {
                                  final maximoToppings = categoria.maximo ?? 0;

                                  setState(() {
                                    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);
                                      }
                                    }
                                    _recalcularTotal();
                                  });
                                },
                              );
                            }).toList(),
                          );
                        }).toList(),
                      ),
                    const Divider(),
                  ],
                );
              },
            ),
          ),
          if (pedidoActual != null && pedidoActual!.id! > 0)
            _buildMesaSelector(),
          if (pedidoActual != null && pedidoActual!.id! > 0)
            const SizedBox(height: 5),
          _buildDiscountSection(),
          const Divider(thickness: 5),
          _buildTotalSection(),
          const SizedBox(height: 25),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              children: [
                if (pedidoActual != null && pedidoActual!.id! > 0) ...[
                  ElevatedButton(
                    onPressed: () => _guardarPedidoExistente(),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: AppTheme.tertiary,
                      textStyle: const TextStyle(fontSize: 22),
                      fixedSize: const Size(250, 50),
                    ),
                    child: Text(
                      'Actualizar Pedido',
                      style: TextStyle(color: AppTheme.quaternary),
                    ),
                  ),
                  const SizedBox(height: 10),
                  ElevatedButton(
                    onPressed: () => _promptForCustomerName(),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.green,
                      textStyle: const TextStyle(fontSize: 22),
                      fixedSize: const Size(250, 50),
                    ),
                    child: Text(
                      'Finalizar Pedido',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ] else ...[
                  if (_isMesasActive)
                    ElevatedButton(
                      onPressed: () => _crearPedidoConModal(),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: AppTheme.tertiary,
                        textStyle: const TextStyle(fontSize: 22),
                        fixedSize: const Size(250, 50),
                      ),
                      child: Text(
                        'Iniciar Pedido',
                        style: TextStyle(color: AppTheme.quaternary),
                      ),
                    ),
                  const SizedBox(height: 5),
                  ElevatedButton(
                    onPressed: () => _promptForCustomerName(),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: AppTheme.rojo,
                      textStyle: const TextStyle(fontSize: 18),
                      fixedSize: const Size(250, 50),
                    ),
                    child: Text(
                      'Finalizar Pedido Sin Mesa',
                      style: TextStyle(color: AppTheme.quaternary),
                    ),
                  ),
                ]
              ],
            ),
          ),
        ],
      ),
    );
  }

  void _mostrarDialogoComentario(
      BuildContext context, ItemCarrito item, int index) {
    TextEditingController comentarioController =
        TextEditingController(text: carrito[index].comentario ?? '');

    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text(
            'Comentario del Producto',
            style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
          ),
          content: TextField(
            controller: comentarioController,
            maxLines: 3,
            decoration: const InputDecoration(
              hintText: 'Escribe un comentario...',
              border: OutlineInputBorder(),
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('Cancelar'),
            ),
            TextButton(
              onPressed: () {
                setState(() {
                  carrito[index].comentario = comentarioController.text.trim();
                });
                Navigator.of(context).pop();
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Comentario guardado')),
                );
              },
              child: const Text('Guardar'),
            ),
          ],
        );
      },
    );
  }

  void eliminarProductoDelCarrito(int index) async {
    bool autorizado = true;

    // Solicitar autenticación solo si el pedido tiene un ID mayor a 0
    if (pedidoActual != null && pedidoActual!.id! > 0) {
      autorizado = await autenticarConCodigo(context);
    }

    if (autorizado) {
      final producto = carrito[index].producto;

      // Verificar si el pedido actual tiene un ID mayor a 0
      if (pedidoActual != null && pedidoActual!.id! > 0) {
        final pedidoProducto = pedidoActual!.productos
            .firstWhereOrNull((p) => p.idProducto == producto.id);

        if (pedidoProducto != null) {
          // Marcar como eliminado en la base de datos
          await Provider.of<PedidoViewModel>(context, listen: false)
              .eliminarProductoDelPedido(producto.id!, pedidoActual!.id!);
        }
      }

      // Remover el producto del carrito en la UI
      setState(() {
        carrito.removeAt(index);
      });

      // Recalcular el total
      _recalcularTotal();

      // Mostrar mensaje de confirmación
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("Producto eliminado del carrito.")),
      );
    }
  }

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

  void quitarProductoDelCarrito(ItemCarrito item) async {
    bool autorizado = true;

    if (pedidoActual != null && pedidoActual!.id! > 0) {
      autorizado = await autenticarConCodigo(context);
    }

    if (autorizado) {
      setState(() {
        if (item.cantidad > 1) {
          item.cantidad--;
        } else {
          if (pedidoActual != null && pedidoActual!.id! > 0) {
            final pedidoProducto = pedidoActual!.productos
                .firstWhereOrNull((p) => p.idProducto == item.producto.id);

            if (pedidoProducto != null) {
              Provider.of<PedidoViewModel>(context, listen: false)
                  .eliminarProductoDelPedido(
                      item.producto.id!, pedidoActual!.id!);
            }
          }

          carrito.remove(item);
        }
      });

      _recalcularTotal();

      // Mostrar mensaje de confirmación
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(item.cantidad > 0
              ? "Cantidad del producto actualizada."
              : "Producto marcado como eliminado."),
        ),
      );
    }
  }

  Widget _buildProductsSection() {
    return Column(
      children: [
        const SizedBox(height: 5),
        _buildSearchBar(),
        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];

                // Si no se está buscando, aplicar el filtro de categoría
                if (!_estadoBusqueda &&
                    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: 65,
      child: Scrollbar(
        thumbVisibility: true,
        trackVisibility: true,
        interactive: true,
        controller: _categoryScrollController,
        child: Padding(
          padding: EdgeInsets.fromLTRB(0, 0, 0, 15),
          child: ListView.builder(
            controller: _categoryScrollController,
            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(
                    backgroundColor:
                        isSelected ? AppTheme.tertiary : Colors.grey,
                    foregroundColor:
                        isSelected ? AppTheme.quaternary : 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),
          suffixIcon: IconButton(
            icon: Icon(Icons.clear),
            onPressed: () {
              _searchController.clear();
              _onSearchChanged('');
            },
          ),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(12.0),
          ),
          enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(12.0),
              borderSide: BorderSide(width: 1.5)),
          focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Colors.black),
            borderRadius: BorderRadius.circular(12.0),
          ),
        ),
        onChanged: _onSearchChanged,
      ),
    );
  }

  Future<bool> autenticarConCodigo(BuildContext context) async {
    final TextEditingController codeController = TextEditingController();

    return await showDialog<bool>(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: const Text("Autenticación requerida",
                  style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22)),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text(
                    "Por favor, introduce el código de autenticación generado.",
                    style: TextStyle(fontSize: 18),
                  ),
                  const SizedBox(height: 16),
                  TextField(
                    controller: codeController,
                    decoration: const InputDecoration(
                      labelText: "Código de autenticación",
                    ),
                  ),
                ],
              ),
              actions: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    TextButton(
                      onPressed: () => Navigator.of(context).pop(false),
                      child: Text('Cancelar',
                          style: TextStyle(
                              fontSize: 18, color: AppTheme.secondary)),
                      style: ButtonStyle(
                          padding: MaterialStatePropertyAll(
                              EdgeInsets.fromLTRB(20, 10, 20, 10)),
                          backgroundColor: MaterialStatePropertyAll(Colors.red),
                          foregroundColor:
                              MaterialStatePropertyAll(AppTheme.secondary)),
                    ),
                    TextButton(
                      onPressed: () {
                        final now = DateTime.now().toUtc();
                        timezone.initializeTimeZones();
                        final pacificTimeZone =
                            timezone.getLocation('America/Los_Angeles');
                        final date =
                            timezone.TZDateTime.from(now, pacificTimeZone);

                        final codigoTotp = OTP.generateTOTPCodeString(
                          'TYSNE4CMT5LVLGWS',
                          date.millisecondsSinceEpoch,
                          algorithm: Algorithm.SHA1,
                          isGoogle: true,
                        );

                        String codigo = codeController.text.trim();
                        List<String> codigosEstaticos = [
                          '172449',
                          '827329',
                          // Agregar más códigos estáticos si es necesario
                        ];

                        bool esCodigoValido =
                            codigosEstaticos.contains(codigo) ||
                                codigo == codigoTotp;

                        if (!esCodigoValido) {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                              content: Text('El código no es correcto'),
                              duration: Duration(seconds: 2),
                            ),
                          );
                          return;
                        }

                        Navigator.of(context).pop(true);
                      },
                      child: Text('Confirmar',
                          style: TextStyle(
                              fontSize: 18, color: AppTheme.quaternary)),
                      style: ButtonStyle(
                          padding: MaterialStatePropertyAll(
                              EdgeInsets.fromLTRB(20, 10, 20, 10)),
                          backgroundColor:
                              MaterialStatePropertyAll(AppTheme.secondary),
                          foregroundColor:
                              MaterialStatePropertyAll(AppTheme.secondary)),
                    ),
                  ],
                )
              ],
            );
          },
        ) ??
        false;
  }

  Widget _buildMesaSelector() {
    return FutureBuilder(
      future: Provider.of<MesaViewModel>(context, listen: false)
          .fetchLocalAll(sinLimite: true),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }

        List<Mesa> mesasDisponibles =
            Provider.of<MesaViewModel>(context, listen: false).mesas;

        TextEditingController mesaSearchController = TextEditingController();

        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              const Text(
                'Mesa:',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
              ),
              const SizedBox(width: 16),
              Expanded(
                child: AppDropdownSearch(
                  controller: mesaSearchController,
                  asyncItems: (String query) async {
                    await Provider.of<MesaViewModel>(context, listen: false)
                        .fetchLocalByName(nombre: query);
                    return Provider.of<MesaViewModel>(context, listen: false)
                        .mesas;
                  },
                  itemAsString: (dynamic mesa) =>
                      (mesa as Mesa).nombre ?? 'Sin Nombre',
                  selectedItem: mesasDisponibles.firstWhere(
                    (mesa) => mesa.id == pedidoActual?.idMesa,
                    orElse: () => null as Mesa,
                  ),
                  onChanged: (dynamic nuevaMesa) {
                    setState(() {
                      pedidoActual?.idMesa = (nuevaMesa as Mesa).id;
                    });
                  },
                  items: mesasDisponibles,
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}
