import '../data/api_response.dart';
import '/models/mesa_model.dart';
import 'package:flutter/material.dart';
import '../services/services.dart';
import 'package:sqflite/sqflite.dart';

class MesaViewModel extends ChangeNotifier {
  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> fetchLocalAll({int page = 1, bool sinLimite = false}) async {
    _currentPage = page;
    var db = await RepoService().db;

    if (!sinLimite) {
      int? count = Sqflite.firstIntValue(
          await db!.rawQuery('SELECT COUNT(*) FROM Mesa'));
      _totalMesas = count ?? 0;
    }

    String? limitOffsetClause;
    if (!sinLimite) {
      int offset = (_limit * (page - 1));
      limitOffsetClause = 'LIMIT $_limit OFFSET $offset';
    } else {
      limitOffsetClause = '';
    }

    var query = await db!
        .rawQuery('SELECT * FROM Mesa ORDER BY id ASC $limitOffsetClause');
    _mesas = query.map((element) => Mesa.fromJson(element)).toList();

    notifyListeners();
  }

  Future<void> fetchLocalByName({required String nombre}) async {
    var db = await RepoService().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 RepoService().guardar(mesa);
    await fetchLocalAll();
  }

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

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

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

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

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

  Future<bool> isMesaActive(String clave) async {
    var db = await RepoService().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;
  }

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

    try {
      Map<String, String> parametros = {
        "claveSucursal": claveSucursal!,
        "limite": "-1"
      };

      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) {
          print("Mesas API obtenidas: ${mesasApi.length}");
          await RepoService().sincronizarMesas(mesasApi);
          await fetchLocalAll();
          return true;
        } else {
          print("No se encontraron mesas en la API.");
        }
      } else {
        print("Error en la respuesta de la API o resultados nulos MESAS.");
      }
      return false;
    } catch (e) {
      print('Error al sincronizar mesas: $e');
      return false;
    }
  }
}
