// ignore_for_file: use_build_context_synchronously import 'dart:math'; import 'package:filcnaplo/api/providers/user_provider.dart'; import 'package:filcnaplo/api/providers/database_provider.dart'; import 'package:filcnaplo/models/user.dart'; import 'package:filcnaplo_kreta_api/client/api.dart'; import 'package:filcnaplo_kreta_api/client/client.dart'; import 'package:filcnaplo_kreta_api/models/message.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class MessageProvider with ChangeNotifier { late List _messages; late List _recipients; late BuildContext _context; List get messages => _messages; List get recipients => _recipients; MessageProvider({ List initialMessages = const [], List initialRecipients = const [], required BuildContext context, }) { _messages = List.castFrom(initialMessages); _recipients = List.castFrom(initialRecipients); _context = context; if (_messages.isEmpty) restore(); } Future restore() async { String? userId = Provider.of(_context, listen: false).id; // Load messages from the database if (userId != null) { var dbMessages = await Provider.of(_context, listen: false) .userQuery .getMessages(userId: userId); _messages = dbMessages; notifyListeners(); } } // Fetches all types of Messages Future fetchAll() => Future.forEach(MessageType.values, (MessageType v) => fetch(type: v)); // Fetches Messages from the Kreta API then stores them in the database Future fetch({MessageType type = MessageType.inbox}) async { // Check Message Type if (type == MessageType.draft) return; String messageType = ["beerkezett", "elkuldott", "torolt"].elementAt(type.index); // Check User User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot fetch Messages for User null"; // Get messages List? messagesJson = await Provider.of(_context, listen: false) .getAPI(KretaAPI.messages(messageType)); if (messagesJson == null) throw "Cannot fetch Messages for User ${user.id}"; // Parse messages List messages = []; await Future.wait(List.generate(messagesJson.length, (index) { return () async { Map message = messagesJson.cast()[index]; Map? messageJson = await Provider.of(_context, listen: false) .getAPI(KretaAPI.message(message["azonosito"].toString())); if (messageJson != null) { messages.add(Message.fromJson(messageJson, forceType: type)); } }(); })); await store(messages, type); } // Stores Messages in the database Future store(List messages, MessageType type) async { // Only store the specified type _messages.removeWhere((m) => m.type == type); _messages.addAll(messages); User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot store Messages for User null"; String userId = user.id; await Provider.of(_context, listen: false) .userStore .storeMessages(_messages, userId: userId); notifyListeners(); } // restore recipients Future restoreRecipients() async { String? userId = Provider.of(_context, listen: false).id; // Load messages from the database if (userId != null) { var dbRecipients = await Provider.of(_context, listen: false) .userQuery .getRecipients(userId: userId); _recipients = dbRecipients; notifyListeners(); } } // fetch recipients Future fetchRecipients() async { Map addressable = {}; // check user User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot fetch Messages for User null"; // get categories List? availableCategoriesJson = await Provider.of(_context, listen: false) .getAPI(KretaAPI.recipientCategories); // print(availableCategoriesJson); // get recipients List? recipientTeachersJson = await Provider.of(_context, listen: false) .getAPI(KretaAPI.recipientTeachers); List? recipientDirectorateJson = await Provider.of(_context, listen: false) .getAPI(KretaAPI.recipientDirectorate); if (availableCategoriesJson == null || recipientTeachersJson == null || recipientDirectorateJson == null) { throw "Cannot fetch Recipients for User ${user.id}"; } for (var e in availableCategoriesJson) { // print(e); switch (e['kod']) { case 'TANAR': addressable .addAll({AddresseeType.teachers: SendRecipientType.fromJson(e)}); break; case 'IGAZGATOSAG': addressable.addAll( {AddresseeType.directorate: SendRecipientType.fromJson(e)}); break; default: break; } } // parse recipients List recipients = []; if (addressable.containsKey(AddresseeType.teachers)) { recipients.addAll(recipientTeachersJson.map((e) => SendRecipient.fromJson(e, addressable[AddresseeType.teachers]!))); } if (addressable.containsKey(AddresseeType.directorate)) { recipients.addAll(recipientDirectorateJson.map((e) => SendRecipient.fromJson(e, addressable[AddresseeType.directorate]!))); } if (kDebugMode) { print(addressable); print(recipients); print(recipients.first.json); } storeRecipients(recipients); } // store recipients Future storeRecipients(List recipients) async { _recipients.addAll(recipients); User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot store Recipients for User null"; String userId = user.id; await Provider.of(_context, listen: false) .userStore .storeRecipients(_recipients, userId: userId); notifyListeners(); } // send message Future sendMessage({ required List recipients, String subject = "Nincs tárgy", required String messageText, }) async { List recipientList = []; User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot send Message as User null"; for (var r in recipients) { recipientList.add({ "azonosito": r.id ?? "", "kretaAzonosito": r.kretaId ?? "", "nev": r.name ?? "Teszt Lajos", "tipus": { "kod": r.type.code, "leiras": r.type.description, "azonosito": r.type.id, "nev": r.type.name, "rovidNev": r.type.shortName, } }); } Object body = { "cimzettLista": recipientList, "csatolmanyok": [], "azonosito": Random().nextInt(10000) + 10000, "feladoNev": user.name, "feladoTitulus": user.role == Role.parent ? "Szülő" : "Diák", "kuldesDatum": DateTime.now().toIso8601String(), "targy": subject, "szoveg": messageText, "elozoUzenetAzonosito": 0, }; // send the message await Provider.of(_context, listen: false) .postAPI(KretaAPI.sendMessage, autoHeader: true, body: body); } }