import 'dart:io';

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:file_picker/file_picker.dart';
import '../../models/models.dart';
import '../../services/repo_service.dart';
import '../../viewmodels/viewmodels.dart';
import '../../widgets/widgets.dart';
import '../../themes/themes.dart';
import '../producto/producto_imagen.dart';

class ProductoForm extends StatefulWidget {
  final Producto producto;

  const ProductoForm({Key? key, required this.producto}) : super(key: key);

  @override
  State<ProductoForm> createState() => Formulario();
}

class Formulario extends State<ProductoForm> {
  final _nombre = TextEditingController();
  final _descripcion = TextEditingController();
  final _precio =
      TextEditingController(); // Mantén esto como String pero conviértelo a `double` más adelante
  final _existencia = TextEditingController();
  final _descuento = TextEditingController();
  final _busquedaCategoria = TextEditingController();
  final _venceDescuento = TextEditingController();
  File? _selectedFile;
  String? _selectedFilePath;
  CategoriaProducto? categoriaProducto;

  Map<int, List<int>> selectedToppingsByCategory = {};
  Map<int, bool> expandedCategoryStates = {};

  List<CategoriaProducto> toppingCategories = [];
  Map<int, List<Producto>> productsByCategory = {};

  @override
  void initState() {
    super.initState();
    _nombre.text = widget.producto.nombre ?? "";
    _descripcion.text = widget.producto.descripcion ?? "";
    _precio.text = widget.producto.precio?.toString() ??
        "0"; // Conversión a String para el campo de texto
    _existencia.text = widget.producto.existencia?.toString() ?? "";
    _descuento.text = widget.producto.descuento?.toString() ?? "";
    _selectedFilePath = widget.producto.imagen;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _loadData();
    });

    Future.microtask(() async {
      await Provider.of<CategoriaProductoViewModel>(context, listen: false)
          .fetchLocalAll();
      List<CategoriaProducto> categories =
          Provider.of<CategoriaProductoViewModel>(context, listen: false)
              .categoriaProductos;
      if (widget.producto.idCategoria != null) {
        categoriaProducto = categories.firstWhere(
            (c) => c.id == widget.producto.idCategoria,
            orElse: () =>
                CategoriaProducto(id: 0, nombre: 'Categoría Default'));
      } else if (categories.isNotEmpty) {
        categoriaProducto = categories.first;
      }

      final productoVM = Provider.of<ProductoViewModel>(context, listen: false);
      await cargarToppingsGuardados(widget.producto.id, productoVM);

      await loadToppingData();

      setState(() {});
    });
  }

  Future<void> cargarToppingsGuardados(
      int? idProducto, ProductoViewModel productoVM) async {
    if (idProducto != null && idProducto > 0) {
      List<int> toppingIds =
          await productoVM.obtenerToppingsPorProducto(idProducto);
      for (var toppingId in toppingIds) {
        Producto? topping = await productoVM.obtenerProductoPorId(toppingId);
        if (topping != null && topping.idCategoria != null) {
          selectedToppingsByCategory[topping.idCategoria!] ??= [];
          selectedToppingsByCategory[topping.idCategoria!]!.add(toppingId);
        }
      }
    }
  }

  void _loadData() async {
    await Provider.of<CategoriaProductoViewModel>(context, listen: false)
        .fetchLocalAll();
  }

  Future<void> _selectImage() async {
    final result = await FilePicker.platform.pickFiles(
      type: FileType.image,
      dialogTitle: 'Seleccionar imagen para el producto',
    );
    if (result != null && result.files.single.path != null) {
      File selectedFile = File(result.files.single.path!);
      setState(() {
        _selectedFile = selectedFile;
      });
    }
  }

  Future<void> loadToppingData() async {
    final productoVM = Provider.of<ProductoViewModel>(context, listen: false);

    toppingCategories = await productoVM.fetchToppingCategories();

    for (var category in toppingCategories) {
      productsByCategory[category.id!] =
          await productoVM.fetchProductsByCategory(category.id!);
    }
  }

  @override
  Widget build(BuildContext context) {
    final ProductoViewModel productoVM =
        Provider.of<ProductoViewModel>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Nuevo Producto',
          style: TextStyle(color: AppTheme.secondary),
        ),
        iconTheme: IconThemeData(color: AppTheme.secondary),
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(8),
        child: Column(
          children: [
            tarjeta(
              Padding(
                padding: const EdgeInsets.all(8),
                child: Column(
                  children: [
                    AppDropdownSearch(
                      etiqueta: 'Categoría',
                      controller: _busquedaCategoria,
                      selectedItem: categoriaProducto,
                      onPressedClear: () {
                        setState(() {
                          categoriaProducto = null;
                        });
                      },
                      itemAsString: (item) => item.nombre,
                      asyncItems: (text) async {
                        return await Provider.of<CategoriaProductoViewModel>(
                                context,
                                listen: false)
                            .getCategoriaProducto(q: text);
                      },
                      onChanged: (newValue) {
                        setState(() {
                          categoriaProducto = newValue as CategoriaProducto?;
                        });
                      },
                      validator: (value) =>
                          value == null ? 'Seleccione una categoría' : null,
                    ),
                    AppTextField(
                      maxLength: 100,
                      etiqueta: 'Nombre',
                      controller: _nombre,
                      hintText: 'Nombre del producto',
                    ),
                    AppTextField(
                      maxLength: 100,
                      etiqueta: 'Precio',
                      controller: _precio,
                      hintText: 'Precio del producto',
                      keyboardType: TextInputType.number,
                    ),
                    const SizedBox(height: 5),
                    if (categoriaProducto != null &&
                        categoriaProducto!.esToping == 0)
                      Column(
                        children: [
                          Align(
                              alignment: Alignment.centerLeft,
                              child: Text(
                                'Toppings a escoger en el pedido:',
                                style: TextStyle(
                                    fontSize: 18, fontWeight: FontWeight.bold),
                              )),
                          buildToppingExpansionTiles(),
                        ],
                      ),
                    const SizedBox(height: 5),
                    AppTextField(
                      maxLength: 1000,
                      maxLines: 3,
                      etiqueta: 'Descripción',
                      controller: _descripcion,
                      hintText: 'Descripción del producto',
                    ),
                    Align(
                      alignment: Alignment.centerLeft,
                      child: ElevatedButton(
                        onPressed: _selectImage,
                        style: ElevatedButton.styleFrom(
                          shape: RoundedRectangleBorder(
                              borderRadius:
                                  BorderRadius.all(Radius.circular(20))),
                          primary: AppTheme.tertiary,
                          onPrimary: AppTheme.quaternary,
                        ),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            Icon(Icons.add, size: 120),
                            Text('Agregar Imagen',
                                style: TextStyle(fontSize: 16)),
                            SizedBox(height: 10),
                          ],
                        ),
                      ),
                    ),
                    if (_selectedFilePath != null &&
                        File(_selectedFilePath!).existsSync())
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Align(
                            alignment: Alignment.centerLeft,
                            child: Padding(
                              padding:
                                  const EdgeInsets.only(top: 10.0, bottom: 4.0),
                              child: Text(
                                'Imagen:',
                                style: TextStyle(
                                    fontSize: 18,
                                    fontWeight: FontWeight.bold,
                                    color: AppTheme.secondary),
                              ),
                            ),
                          ),
                          Image.file(
                            File(_selectedFilePath!),
                            height: 250,
                            fit: BoxFit.cover,
                            key: ValueKey(_selectedFilePath),
                          ),
                        ],
                      ),
                  ],
                ),
              ),
            ),
            SizedBox(height: 15),
            boton("Guardar", () async {
              await saveOrUpdateProduct();
            })
          ],
        ),
      ),
    );
  }

  Widget buildToppingExpansionTiles() {
    return Column(
      children: toppingCategories.map((category) {
        expandedCategoryStates[category.id!] ??= false;

        List<Producto>? products = productsByCategory[category.id!] ?? [];

        bool allSelected =
            selectedToppingsByCategory[category.id]?.length == products.length;

        return ExpansionTile(
          title: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(category.nombre!),
              Checkbox(
                activeColor: AppTheme.primary,
                value: allSelected,
                onChanged: (value) {
                  setState(() {
                    if (value == true) {
                      selectedToppingsByCategory[category.id!] =
                          products.map((p) => p.id!).toList();
                    } else {
                      selectedToppingsByCategory[category.id!] = [];
                    }
                  });
                },
              ),
            ],
          ),
          children: products.map((product) {
            bool isSelected =
                selectedToppingsByCategory[category.id]?.contains(product.id) ??
                    false;
            return CheckboxListTile(
              activeColor: AppTheme.primary,
              title: Text(product.nombre!),
              value: isSelected,
              onChanged: (value) {
                setState(() {
                  if (value == true) {
                    if (selectedToppingsByCategory[category.id!] == null) {
                      selectedToppingsByCategory[category.id!] = [];
                    }
                    selectedToppingsByCategory[category.id!]!.add(product.id!);
                  } else {
                    selectedToppingsByCategory[category.id!]!
                        .remove(product.id);
                  }
                });
              },
            );
          }).toList(),
          initiallyExpanded: expandedCategoryStates[category.id]!,
          onExpansionChanged: (expanded) {
            setState(() {
              expandedCategoryStates[category.id!] = expanded;
            });
          },
        );
      }).toList(),
    );
  }

  @override
  void dispose() {
    _nombre.dispose();
    _descripcion.dispose();
    _precio.dispose();
    _existencia.dispose();
    _descuento.dispose();
    _busquedaCategoria.dispose();
    _venceDescuento.dispose();
    super.dispose();
  }

  Future<void> saveOrUpdateProduct() async {
    if (categoriaProducto == null || categoriaProducto?.id == null) {
      await alerta(context, etiqueta: "Seleccionar categoría");
      return;
    }

    List<Producto> selectedToppings = [];
    selectedToppingsByCategory.forEach((categoryId, productIds) {
      selectedToppings
          .addAll(productIds.map((productId) => Producto(id: productId)));
    });

    if (_precio.text.isEmpty) _precio.text = '0';

    // Conversion del precio a double
    double precio = double.tryParse(_precio.text) ?? 0.0;

    Producto productToUpdate = Producto(
      id: widget.producto.id,
      nombre: _nombre.text,
      descripcion: _descripcion.text,
      precio: precio, // Guardando como String para la base de datos
      idCategoria: categoriaProducto!.id,
      imagen: _selectedFilePath,
      topings: selectedToppings.isNotEmpty ? selectedToppings : null,
    );

    if (productToUpdate.id != null && productToUpdate.id != 0) {
      await Provider.of<ProductoViewModel>(context, listen: false)
          .updateProducto(productToUpdate);

      if (_selectedFile != null) {
        String? imagePath =
            await pickAndStoreImage(_selectedFile!, productToUpdate.id);
        if (imagePath != null) {
          setState(() {
            _selectedFilePath = imagePath;
            productToUpdate.imagen = imagePath;
          });
          await Provider.of<ProductoViewModel>(context, listen: false)
              .updateProductImagePath(productToUpdate.id, imagePath);
        }
      }
    } else {
      Producto nuevoProducto = Producto(
        nombre: _nombre.text,
        descripcion: _descripcion.text,
        precio: precio, // Guardando como String para la base de datos
        idCategoria: categoriaProducto!.id,
        imagen: _selectedFilePath,
        topings: selectedToppings.isNotEmpty ? selectedToppings : null,
      );

      int newProductId =
          await Provider.of<ProductoViewModel>(context, listen: false)
              .addProducto(nuevoProducto);

      if (newProductId != -1 && _selectedFile != null) {
        String? imagePath =
            await pickAndStoreImage(_selectedFile!, newProductId);
        if (imagePath != null) {
          setState(() {
            _selectedFilePath = imagePath;
          });
          await Provider.of<ProductoViewModel>(context, listen: false)
              .updateProductImagePath(newProductId, imagePath);
        }
      }
    }

    print('Datos del producto antes de guardar: ${productToUpdate.toJson()}');
    print(
        'Toppings seleccionados: ${selectedToppings.map((t) => t.id).toList()}');

    if (context.mounted) {
      Navigator.pop(context);
    }
  }
}
