import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:get_storage/get_storage.dart'; import 'package:http/http.dart' as http; import 'package:device_info_plus/device_info_plus.dart'; import '../models/response_output.dart'; import '../helper/constants.dart'; enum MainView { dashboard, traun, sarleinsbach, lannach, settings } class HomeController extends GetxController { // Der Key, mit dem wir das Scaffold von hier aus steuern final GlobalKey scaffoldKey = GlobalKey(); final boxSettings = GetStorage(); final currentView = MainView.dashboard.obs; //--------------Settings View--------------------------- final userWebMethodesController = TextEditingController().obs; final passwordWebMethodesController = TextEditingController().obs; final powerUrlController = TextEditingController().obs; void saveSettings() { String wbUser = userWebMethodesController.value.text; String wbPassword = passwordWebMethodesController.value.text; String wbPowerUrl = powerUrlController.value.text; boxSettings.write('wbUser', wbUser); boxSettings.write('wbPassword', wbPassword); boxSettings.write('wbPowerUrl', wbPowerUrl); kDisplaySnackBarGreen("Settings saved successfully!"); print('Einstellungen gespeichert:'); print('Admin User: $wbUser'); print('Admin Password: $wbPassword'); print('Web Methodes Power URL: $wbPowerUrl'); } //------------------------------------------------------ // http get request to fetch data from the provided URL //------------------------------------------------------ final dateFromToIsoController = TextEditingController().obs; final dateToIsoController = TextEditingController().obs; final inputSwitchBranches = RxnString('TraunPV'); final responseOutputTraunPV = ResponseOutput().obs; final responseOutputTraunImport = ResponseOutput().obs; final responseOutputSarleinsbachPV = ResponseOutput().obs; final responseOutputSarleinsbachImport = ResponseOutput().obs; final responseOutputLannachPV = ResponseOutput().obs; final responseOutputLannachImport = ResponseOutput().obs; /// Map: Branch → (PV Observable, Import Observable) Map> get _branchConfig => { 'TraunPV': { 'pv': responseOutputTraunPV, 'import': responseOutputTraunImport, 'pvSuffix': 'TraunPV', 'importSuffix': 'TraunImport', }, 'TraunImport': { 'pv': responseOutputTraunPV, 'import': responseOutputTraunImport, 'pvSuffix': 'TraunPV', 'importSuffix': 'TraunImport', }, 'SarleinsbachPV': { 'pv': responseOutputSarleinsbachPV, 'import': responseOutputSarleinsbachImport, 'pvSuffix': 'SarleinsbachPV', 'importSuffix': 'SarleinsbachImport', }, 'SarleinsbachImport': { 'pv': responseOutputSarleinsbachPV, 'import': responseOutputSarleinsbachImport, 'pvSuffix': 'SarleinsbachPV', 'importSuffix': 'SarleinsbachImport', }, 'LannachPV': { 'pv': responseOutputLannachPV, 'import': responseOutputLannachImport, 'pvSuffix': 'LannachPV', 'importSuffix': 'LannachImport', }, 'LannachImport': { 'pv': responseOutputLannachPV, 'import': responseOutputLannachImport, 'pvSuffix': 'LannachPV', 'importSuffix': 'LannachImport', }, }; //Device Info data Future isAndroidSimulator() async { // Prüfen, ob es überhaupt Android ist if (!Platform.isAndroid) return false; final deviceInfo = DeviceInfoPlugin(); final androidInfo = await deviceInfo.androidInfo; // Wenn es KEIN physisches Gerät ist, ist es ein Simulator/Emulator return !androidInfo.isPhysicalDevice; } void fetchData() async { final inputFromIso = dateFromToIsoController.value.text; final inputToIso = dateToIsoController.value.text; final branch = inputSwitchBranches.value; if (branch == null || branch.isEmpty) { kDisplaySnackBarRed('Ungültiger Standort ausgewählt.'); return; } final baseUrl = getBaseUrl; if (baseUrl.isEmpty) { kDisplaySnackBarRed('Bitte zuerst die Server-URL eintragen.'); return; } final config = _branchConfig[branch]; if (config == null) { kDisplaySnackBarRed('Unbekannte Branche: $branch'); return; } final credentials = '${userWebMethodesController.value.text}:${passwordWebMethodesController.value.text}'; final basicAuth = 'Basic ${base64Encode(utf8.encode(credentials))}'; final baseUri = Uri.parse(baseUrl); try { // Fetch PV Daten await _fetchAndStore( baseUri, inputFromIso, inputToIso, config['pvSuffix'], config['pv'], basicAuth, ); // Fetch Import Daten await _fetchAndStore( baseUri, inputFromIso, inputToIso, config['importSuffix'], config['import'], basicAuth, ); } catch (e) { print('Error: $e'); kDisplaySnackBarRed('Netzwerkfehler: $e'); } } /// Hilfsfunktion - reduziert Codeverdoppelung Future _fetchAndStore( Uri baseUri, String inputFromIso, String inputToIso, String switchBranch, dynamic responseObservable, String basicAuth, ) async { final uri = baseUri.replace( queryParameters: { ...baseUri.queryParameters, 'InputFromIso': inputFromIso, 'InputToIso': inputToIso, 'InputSwitchBranches': switchBranch, }, ); try { final response = await http.get( uri, headers: {'Authorization': basicAuth, 'Accept': 'application/json'}, ); final statusGroup = response.statusCode ~/ 100; if (statusGroup == 2) { print('✓ $switchBranch erfolgreich geladen'); responseObservable.value = ResponseOutput.fromJson( jsonDecode(response.body), ); } else if (statusGroup == 4) { kDisplaySnackBarRed('Fehler 4xx: ${response.statusCode}'); } else if (statusGroup == 5) { kDisplaySnackBarRed('Fehler 5xx: ${response.statusCode}'); } else { kDisplaySnackBarRed('Fehler: ${response.statusCode}'); } } catch (e) { print('Error fetching $switchBranch: $e'); rethrow; } } final isEmulator = false.obs; // Synchroner Getter String get getBaseUrl { if (kIsWeb) { return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?'; } if (isEmulator.value) { return 'http://10.12.101.27:5556/invoke/IFN_ASKI_Service.flows/getAskiData?'; } return powerUrlController.value.text.trim(); } /// Wählt die richtige Base-URL: /// Web: localhost:3000 (Reverse Proxy) /// Desktop: Direkt von Settings // Future _getBaseUrl() async { // final settingsUrl = powerUrlController.value.text.trim(); // // Auf Web: verwende Reverse Proxy auf localhost:3000 // if (kIsWeb) { // return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?'; // } // if (await isAndroidSimulator()) { // return 'http://10.12.101.27:5556/invoke/IFN_ASKI_Service.flows/getAskiData?'; // } // // Auf Desktop (Windows, Linux, macOS): direkt von Settings // return settingsUrl; // } void changeView(MainView view) { currentView.value = view; if (currentView.value == MainView.dashboard) { inputSwitchBranches.value = 'TraunPV'; } else if (currentView.value == MainView.traun) { inputSwitchBranches.value = 'TraunPV'; } else if (currentView.value == MainView.sarleinsbach) { inputSwitchBranches.value = 'SarleinsbachPV'; } else if (currentView.value == MainView.lannach) { inputSwitchBranches.value = 'LannachPV'; } if (currentView.value != MainView.dashboard) { fetchData(); // Fetch data whenever the view changes } } void toggleDrawer() { final ScaffoldState? state = scaffoldKey.currentState; if (state != null) { if (state.isDrawerOpen) { print("Schließe Drawer..."); state.closeDrawer(); // Wartet auf das Ende der Schließ-Animation print("Drawer geschlossen."); } else { print("Öffne Drawer..."); state.openDrawer(); // Wartet auf das Ende der Öffnen-Animation print("Drawer geöffnet."); } } } @override void onInit() async { super.onInit(); if (!kIsWeb && Platform.isAndroid) { final deviceInfo = DeviceInfoPlugin(); final androidInfo = await deviceInfo.androidInfo; isEmulator(!androidInfo.isPhysicalDevice); } _readStorageData(); } void _readStorageData() { bool hasWbUser = boxSettings.hasData('wbUser'); if (hasWbUser) { userWebMethodesController.value.text = boxSettings.read('wbUser'); } bool hasWbPassword = boxSettings.hasData('wbPassword'); if (hasWbPassword) { passwordWebMethodesController.value.text = boxSettings.read('wbPassword'); } bool hasWbPowerUrl = boxSettings.hasData('wbPowerUrl'); if (hasWbPowerUrl) { powerUrlController.value.text = boxSettings.read('wbPowerUrl'); } //fromDateTimeIso and toDateTimeIso dateFromToIsoController.value.text = DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day, ).toIso8601String(); dateToIsoController.value.text = DateTime.now().toIso8601String(); } @override void onClose() { userWebMethodesController.close(); powerUrlController.close(); passwordWebMethodesController.close(); dateFromToIsoController.close(); dateToIsoController.close(); super.onClose(); } }