import 'dart:convert';

import 'package:flutter/material.dart';
import '/data/api_response.dart';

import '../data/session/session_storage.dart';
import '../models/models.dart';
import '../services/base_service.dart';

class AdministracionViewModel extends ChangeNotifier {
  bool _isLoading = false;
  bool get isLoading => _isLoading;

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

  List<Modulo> _modulos = [];
  List<Modulo> get modulos => _modulos;

  List<ModuloPermiso> _permisos = [];
  List<ModuloPermiso> get permisos => _permisos;

  List<String> _lospermisos = [];
  List<String> get lospermisos => _lospermisos;

  List<PermisoPerfil> _permisoPerfil = [];
  List<PermisoPerfil> get permisoPerfil => _permisoPerfil;

  Modulo? _selectedModelo;
  Modulo? get selectedModelo => _selectedModelo;

  ModuloPermiso? _selectedModeloPermiso;
  ModuloPermiso? get selectedModeloPermiso => _selectedModeloPermiso;

  PermisoPerfil? _selectedPermisoPerfil;
  PermisoPerfil? get selectedPermisoPerfil => _selectedPermisoPerfil;

  Map<String, bool> _selectedPermisos = {};
  Map<String, bool> get selectedPermisos => _selectedPermisos;

  Map<String, bool> selectedPerfilesPermisos = {};

  int pagina = 1;
  int totalPaginas = 1;
  int limite = 10;

  Future<void> fetchModulos() async {
    Map<String, String> parametros = {"ordenar": "nombre-asc"};
    if (_busqueda.isNotEmpty) {
      parametros = {"ordenar": "nombre-asc", "q": _busqueda};
    }
    var r =
        await BaseService().get("admin/modulo", queryParameters: parametros);
    Map<String, dynamic> resJson = jsonDecode(r.body);
    List<Modulo> aux = [];
    if (r.statusCode == 200) {
      for (var x in resJson['resultado']) {
        Modulo modelo = Modulo.fromJson(x);
        aux.add(modelo);
      }
    }
    _modulos = aux;
    notifyListeners();
  }

  Future fetchPermisos({int limitee = 10}) async {
    Map<String, String> parametros = {
      "ordenar": "nombre-asc",
      "pagina": "$pagina",
      "limite": "$limite"
    };
    if (limitee == -1) {
      parametros['limite'] = limitee.toString();
    }
    if (_busqueda.isNotEmpty) {
      parametros = {"ordenar": "nombre-asc", "buscar": _busqueda};
    }
    var r = ApiResponse(await BaseService()
        .get("admin/modulo-permiso", queryParameters: parametros));
    pagina = r.paginacion!.pagina;
    var total = r.paginacion!.total / r.paginacion!.limite;
    totalPaginas = total > 0 ? total.ceil() : 1;
    List<ModuloPermiso> aux = [];
    if (r.isOk) {
      for (var x in r.resultados!) {
        ModuloPermiso modelo = ModuloPermiso.fromJson(x);
        aux.add(modelo);
      }
    }
    _permisos = aux;
    notifyListeners();
  }

  Future<void> fetchPermisosPerfil() async {
    Map<String, String> parametros = {"ordenar": "nombre-asc"};
    if (_busqueda.isNotEmpty) {
      parametros = {"ordenar": "nombre-asc", "q": _busqueda};
    }
    var r = await BaseService()
        .get("admin/permiso-perfil", queryParameters: parametros);
    Map<String, dynamic> resJson = jsonDecode(r.body);
    List<PermisoPerfil> aux = [];
    if (r.statusCode == 200) {
      for (var x in resJson['resultado']) {
        PermisoPerfil modelo = PermisoPerfil.fromJson(x);
        aux.add(modelo);
      }
    }
    _permisoPerfil = aux;
    notifyListeners();
  }

  Future<void> fetchOrdenesTaller(
      {String? idEmpresa,
      String? fechai,
      String? fechaf,
      String? estatus,
      String? tipo,
      String? limite}) async {
    Map<String, String> parametros = {'ordenar': 'creado-desc'};

    if (limite != null) {
      parametros['limite'] = limite;
    }

    if (idEmpresa != null && idEmpresa != '') {
      parametros['idEmpresa'] = idEmpresa;
    }

    if (fechai != null) {
      parametros["fechaInicio"] = fechai;
    }
    if (fechaf != null) {
      parametros["fechaFin"] = fechaf;
    }

    if (estatus != null && estatus != '') {
      parametros['estatus'] = estatus;
    }

    if (tipo != null && tipo != '') {
      parametros['tipoUnidad'] = tipo;
    }

    notifyListeners();
  }

  setIsLoading(bool loading) {
    if (_isLoading != loading) {
      _isLoading = loading;
      notifyListeners();
    }
  }

  selectModelo(Modulo? modelo) {
    _selectedModelo = modelo;
    notifyListeners();
  }

  selectPermiso(ModuloPermiso? modelo) {
    _selectedModeloPermiso = modelo;
    notifyListeners();
  }

  void selectPermisoPerfil(PermisoPerfil? modelo) {
    _selectedPermisoPerfil = modelo;
    if (modelo != null && modelo.id != null) {
      // Cargar permisos del perfil
      cargarPermisosDelPerfil(modelo.id!);
    }
    notifyListeners();
  }

  Future<void> cargarPermisosDelPerfil(String perfilId) async {
    setIsLoading(true);
    try {
      var r = await BaseService().get("admin/permiso-perfil",
          queryParameters: {'expand': 'permisos', 'id': perfilId});
      Map<String, dynamic> resJson = jsonDecode(r.body);
      List<dynamic> permisos = resJson['resultado'][0][
          'permisos']; // Acceder a la lista de permisos dentro del primer elemento de 'resultado'

      List<String> permisosIds =
          []; // Lista para almacenar los identificadores de permisos
      for (var permiso in permisos) {
        String permisoId =
            permiso['id']; // Obtener el valor de 'id' como String
        permisosIds.add(permisoId); // Agregar el identificador a la lista
      }

      // Asignar la lista de identificadores al mapa _selectedPermisos
      _selectedPermisos =
          Map.fromIterable(permisosIds, key: (id) => id, value: (_) => true);

      notifyListeners();
    } catch (e) {
      print("Error al cargar los permisos: $e");
    } finally {
      setIsLoading(false);
    }
  }

  Future<void> eliminar(Modulo m) async {
    var r = await BaseService()
        .delete("admin/modulo", body: {"id": m.id.toString()});
    Map<String, dynamic> resJson = jsonDecode(r.body);
    if (r.statusCode == 200) {}
  }

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

  Future<void> guardarModelo(
      {required Modulo modelo,
      required String? nombre,
      required String? clave}) async {
    modelo.nombre = nombre;
    modelo.id = clave;
    modelo.creado = DateTime.now();
    var r = await BaseService().post("admin/modulo", body: modelo.toJson());
    if (r.statusCode == 200) {}
    notifyListeners();
  }

  Future<void> guardarModeloPermiso({
    required ModuloPermiso modelo,
    required String? nombre,
    required String? clave,
    required String? descripcion,
    required String? idModulo,
  }) async {
    modelo.nombre = nombre;
    modelo.id = clave;
    modelo.idModulo = idModulo;
    modelo.descripcion = descripcion;
    modelo.creado = DateTime.now();
    var r =
        await BaseService().post("admin/modulo-permiso", body: modelo.toJson());
    if (r.statusCode == 200) {}
    notifyListeners();
  }

  Future<void> guardarPermisoPerfil({
    required PermisoPerfil modelo,
    required String? nombre,
    required String? clave,
    required String? descripcion,
    required List<String> permisosSeleccionados,
  }) async {
    setIsLoading(true);
    try {
      var requestBody = {
        'nombre': nombre,
        'clave': clave,
        'descripcion': descripcion,
        'permisos': permisosSeleccionados,
      };

      // Si el modelo tiene un ID asignado, agregarlo al cuerpo de la solicitud
      if (modelo.id != null) {
        requestBody['id'] = modelo.id;
      }

      var r = await BaseService()
          .post("admin/permiso-perfil/guardar", body: requestBody);
      if (r.statusCode == 200) {
        print('Perfil guardado exitosamente');
      } else {
        throw Exception('Error al guardar el perfil: ${r.statusCode}');
      }
    } catch (e) {
      print('Error al guardar el perfil: $e');
    } finally {
      setIsLoading(false);
    }
  }

  Map<String, dynamic> validarModelo(
      {required String nombre, required String clave}) {
    if (nombre.isEmpty) {
      return {"data": false, "mensaje": ""};
    }
    return {"data": true, "mensaje": ""};
  }

  Map<String, dynamic> validarModeloPermiso(
      {required String nombre, required String clave}) {
    if (clave.isEmpty) {
      return {"data": false, "mensaje": "Capturar Clave de Permiso"};
    }
    return {"data": true, "mensaje": ""};
  }

  Map<String, dynamic> validarPermisoPerfil(
      {required String nombre, required String clave}) {
    if (clave.isEmpty) {
      return {"data": false, "mensaje": "Capturar Clave de Permiso Perfil"};
    }
    return {"data": true, "mensaje": ""};
  }

  Future<void> eliminarModuloPermiso(ModuloPermiso m) async {
    var r = await BaseService()
        .delete("admin/modulo-permiso", body: {"id": m.id.toString()});
    Map<String, dynamic> resJson = jsonDecode(r.body);
    if (r.statusCode == 200) {}
  }

  Future<void> eliminarPermisoPerfil(PermisoPerfil m) async {
    var r = await BaseService()
        .delete("admin/permiso-perfil/eliminar", body: {"id": m.id.toString()});
    Map<String, dynamic> resJson = jsonDecode(r.body);
    if (r.statusCode == 200) {}
  }

  Future obtenerPerfil() async {
    String id = (await SessionStorage().getId()).toString();
    Map<String, String> parametros = {"expand": "permisos", "id": id};
    var r = ApiResponse(
        await BaseService().get("admin/usuario", queryParameters: parametros));
    List<String> aux = [];
    if (r.statusCode == 200 &&
        r.resultados!.first["permisos"] != null &&
        (r.resultados!.first["permisos"] as List).isNotEmpty) {
      for (var x in (r.resultados!.first["permisos"] as List)) {
        aux.add(x);
      }
    }
    _lospermisos = aux;
    notifyListeners();
  }

  cambiarPagina(int nuevaPagina, {bool segmentar = false}) {
    pagina = nuevaPagina;
    fetchPermisos();
  }

  obtenerTablero(
      {int? mlimite = 0,
      String? fechai,
      String? fechaf,
      bool segmentar = false,
      String? tipo}) async {
    Map<String, String> parametros = {
      /* "ordenar": "id-desc",
      "expand": "planta,media,empresa,chofer,salida,ayudante,unidad", */
    };

    if (fechai != null) {
      parametros["fechaInicio"] = fechai;
    }
    if (fechaf != null) {
      parametros["fechaFin"] = fechaf;
    }

    notifyListeners();
  }
}
