import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import '../../core/services/reposit_factory.dart';
import '../../core/services/services.dart';
import '../../core/models/models.dart';

class MesaViewModel extends ChangeNotifier {
  final Repository<Mesa> mesaRepository;

  MesaViewModel({required this.mesaRepository});

  String _busqueda = "";
  String get busqueda => _busqueda;

  List<Mesa> _mesas = [];
  bool _isLoading = false;
  Mesa? _selectedMesa;

  List<Mesa> get mesas => _mesas;
  bool get isLoading => _isLoading;
  Mesa? get selectedMesa => _selectedMesa;

  int _currentPage = 1;
  int _totalMesas = 0;
  int _limit = 10;

  int get currentPage => _currentPage;
  int get totalMesas => _totalMesas;
  int get totalPages => (_totalMesas / _limit).ceil();

  setBusqueda(String value) {
    _busqueda = value;
    notifyListeners();
  }

  void selectMesa(Mesa mesa) {
    _selectedMesa = mesa;
    notifyListeners();
  }

  Future<void> fetchLocal() async {
    _isLoading = true;
    notifyListeners();

    final resultado =
        await mesaRepository.consultarConOrden(orderBy: 'nombre ASC');

    _mesas = resultado;
    _isLoading = false;
    notifyListeners();
  }

  Future<void> fetchLocalByName({required String nombre}) async {
    var db = await DatabaseService().db;
    var query = await db!.query(
      'Mesa',
      where: 'nombre LIKE "%$nombre%"',
      orderBy: 'id asc',
    );
    List<Mesa> aux = [];
    for (var element in query) {
      Mesa mesa = Mesa.fromJson(element);
      aux.add(mesa);
    }
    _mesas = aux;
    notifyListeners();
  }

  Mesa fetchLocalById({required int? idMesa}) {
    final mesa = mesas.firstWhere((mesa) => mesa.id == idMesa,
        orElse: () => Mesa(id: 0, nombre: 'Mesa desconocida'));
    return mesa;
  }

  Future<void> addMesa(Mesa mesa) async {
    mesa.creado = DateTime.now().toUtc();
    await DatabaseService().guardar(mesa);
    await fetchLocal();
  }

  Future<void> updateMesa(Mesa mesa) async {
    setIsLoading(true);
    try {
      mesa.modificado = DateTime.now().toUtc();
      await DatabaseService().guardar(mesa);
      await fetchLocal();
    } catch (e) {
      debugPrint('Error updating mesa: $e');
    }
    setIsLoading(false);
  }

  Future<void> deleteMesa(int id) async {
    await DatabaseService().eliminar<Mesa>(id);
    fetchLocal();
  }

  void setIsLoading(bool loading) {
    _isLoading = loading;
    notifyListeners();
  }

  // void nextPage() {
  //   if (_currentPage < totalPages) {
  //     fetchLocal(page: _currentPage + 1);
  //   }
  // }

  // void previousPage() {
  //   if (_currentPage > 1) {
  //     fetchLocal(page: _currentPage - 1);
  //   }
  // }

  Future<bool> isMesaActive(String clave) async {
    var db = await DatabaseService().db;
    var result = await db!.query(
      'Mesa',
      where: 'clave = ?',
      whereArgs: [clave],
    );

    if (result.isNotEmpty) {
      var mesa = Mesa.fromJson(result.first);
      return mesa.activa == true;
    }

    return false;
  }
  // TODO: Implementar CambiarEstadoMesa, actualizar modelo
  // void CambiarEstadoPedidoMesa(Mesa mesa) async {
  //   var db = await DatabaseService().db;
  //   await db!.update(
  //     'Mesa',
  //     {'estado': mesa.estado.toString()},
  //     where: 'id = ?',
  //     whereArgs: [mesa.id],
  //   );
  //   fetchLocal();
  // }

  //todo: Cambio de estado de mesa provisional
  void CambiarEstadoPedidoMesa(EstadoPedido nuevoestado) {
    if (_selectedMesa != null) {
      _selectedMesa!.estado = nuevoestado;
      notifyListeners();
    }
  }

  Future<bool> sincronizarMesas() async {
    String? claveSucursal =
        await DatabaseService().obtenerClaveSucursalSeleccionada();

    try {
      Map<String, String> parametros = {
        "claveSucursal": claveSucursal!,
        "limite": "-1"
      };
      //? peticion de Mesa
      final response = ApiResponse(await BaseService()
          .get('/pos/mesa', queryParameters: parametros, withAuth: true));

      if (response.isOk && response.resultados != null) {
        List<Mesa> mesasApi =
            response.resultados!.map((json) => Mesa.fromApi(json)).toList();

        if (mesasApi.isNotEmpty) {
          debugPrint("Mesas API obtenidas: ${mesasApi.length}");
          await DatabaseService().sincronizarMesas(mesasApi);
          return true;
        } else {
          debugPrint("No se encontraron mesas en la API.");
        }
      } else {
        debugPrint("Error en la respuesta de la API o resultados nulos MESAS.");
      }
      return false;
    } catch (e) {
      debugPrint('Error al sincronizar mesas: $e');
      return false;
    }
  }
}
