import 'package:appwrite/appwrite.dart';
import 'package:appwrite/models.dart' as models;
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:intl/intl.dart';
import '../../utils/extensions/static_helper.dart';
import '../../data/repository/location_repository.dart';
import '../../data/repository/appwrite_repository.dart';
import '../login/login_view.dart';
import '../tanklist/tanklist_view.dart';

class TankController extends GetxController {
  final _dataBox = GetStorage('MyUserStorage');
  //AppWrite API-REST get Data
  final AppwriteRepository _authRepository = AppwriteRepository();
  // GEOLOCATING Services
  final LocationRepository _locationRepository = LocationRepository();

  // Rx-Variablen für die UI, um auf Änderungen zu reagieren
  final circleAvatarUserChar = 'A'.obs;
  final userNameToDisplay = 'Test User'.obs;
  final Rx<Position?> currentPosition = Rx<Position?>(null);
  final Rx<bool> isLoading = false.obs;
  final Rx<String?> errorMessage = Rx<String?>(null);
  final rxOrtString = '?'.obs;
  final rxSessionIdString = '?'.obs;
  final rxSummePreisString = '0.00'.obs;
  // TextEditingController für die Formulareingaben
  final formKeyTank = GlobalKey<FormState>();
  bool isFormValid = false;
  DateTime? _selectedDateTime;
  final dateController = TextEditingController();
  final f = DateFormat('yyyy-MM-dd');
  final kilometerStandEdittingController = TextEditingController();
  final mengeController = TextEditingController();
  final pricePerLiterController = TextEditingController();
  final ortController = TextEditingController();

  final FocusNode firstFocusNode = FocusNode(); // Deklariere den FocusNode

  // Methode für das ausgewählte Datum
  Future<void> selectDateTime(BuildContext context) async {
    // 1. Datum auswählen
    final DateTime? pickedDate = await showDatePicker(
      context: context,
      initialDate: _selectedDateTime ?? DateTime.now(),
      firstDate: DateTime(2000),
      lastDate: DateTime(2101),
    );
    _selectedDateTime = pickedDate;
    if (_selectedDateTime != null) {
      dateController.text = _selectedDateTime!.toIso8601String().substring(
            0,
            10,
          );
    }
  }

  /// Methode zum Abrufen des Standorts.
  Future<void> fetchCurrentLocation() async {
    isLoading.value = true;
    errorMessage.value = null;
    try {
      final Position position = await _locationRepository.getCurrentPosition();
      currentPosition.value = position;
      final double latitude = position.latitude;
      final double longitude = position.longitude;
      // Hier kannst du die Logik hinzufügen, um den Standort zu verwenden, z.B.
      // den Standort in der UI anzuzeigen oder an einen Server zu senden.
      var map = {'lat': latitude, 'lng': longitude};
      rxOrtString.value = await _locationRepository.getNearbyLocation(map);
      ortController.text = rxOrtString.value;
      // Print Standortinformationen in der Konsole
      print('Nearby Location: ${rxOrtString.value}');
      print('Current Position: Latitude: $latitude, Longitude: $longitude');
    } catch (e) {
      // Hier fängst du die Fehler aus dem Repository auf
      errorMessage.value = e.toString();
    } finally {
      isLoading.value = false;
    }
    update();
  }

  void clearTextEditingController() {
    formKeyTank.currentState!.reset();
    // Den Fokus wieder auf das erste Feld legen
    FocusScope.of(Get.context!).requestFocus(firstFocusNode);
    // TextEditingController zurücksetzen
    _selectedDateTime = null; // Datum zurücksetzen
    dateController.clear();
    kilometerStandEdittingController.clear();
    mengeController.clear();
    pricePerLiterController.clear();
    ortController.clear();
  }

  String? validateKilometerStand(String? value) {
    if (value == null || value.isEmpty) {
      return 'Bitte Kilometerstand eingeben';
    }
    if (!GetUtils.isNum(value)) {
      return 'Bitte geben Sie eine gültige Zahl ein';
    }
    return null;
  }

  String? validateMenge(String? value) {
    if (value == null || value.isEmpty) {
      return 'Bitte Menge eingeben';
    }
    if (!GetUtils.isNum(value)) {
      return 'Bitte geben Sie eine gültige Zahl ein';
    }
    return null;
  }

  String? validatePricePerLiter(String? value) {
    if (value == null || value.isEmpty) {
      return 'Bitte Preis pro Liter eingeben';
    }
    if (!GetUtils.isNum(value)) {
      return 'Bitte geben Sie eine gültige Zahl ein';
    }
    return null;
  }

  String? validateOrt(String? value) {
    if (value == null || value.isEmpty) {
      return 'Bitte Ort eingeben...';
    }
    return null;
  }

  //Go to Login Page
  void logoutSessionAndGoToLoginPage() async {
    // Handle logout logic here
    print('Logout session and go to login page');
    // Clear GetStorage session ID
    StaticHelper.removeFromStorage();
    print('Session ID removed from GetStorage');
    await _authRepository.logout();
    Get.offAndToNamed(LoginPage.namedRoute);
    StaticHelper.getMySnackeBar(
        'Logout', 'Sie wurden abgemeldet!', Colors.blue);
  }

  @override
  void onInit() {
    super.onInit();
    // Rufe den Standort direkt beim Initialisieren des Controllers ab, falls gewünscht.
    fetchCurrentLocation();
  }

  @override
  void onReady() async {
    super.onReady();
    if (_dataBox.hasData('sessionId')) {
      rxSessionIdString(_dataBox.read('sessionId').toString());
    }
    await getCurrentLoggedinUser();
    FocusScope.of(Get.context!).requestFocus(firstFocusNode);
    print('TankController is ready');
  }

  Future<void> getCurrentLoggedinUser() async {
    await _authRepository.getCurrentUser.then((models.User user) {
      // Hier kannst du den Benutzernamen und das Avatar-Zeichen setzen
      userNameToDisplay.value = user.name;
      circleAvatarUserChar.value = user.name.substring(0, 1).toUpperCase();
    }).catchError((error) {
      print('Fehler beim Abrufen des Benutzers: $error');
    });
  }

  @override
  void onClose() {
    dateController.dispose();
    kilometerStandEdittingController.dispose();
    mengeController.dispose();
    pricePerLiterController.dispose();
    ortController.dispose();
    firstFocusNode.dispose(); // Dispose den FocusNode
  }

  void updateSumPrice() {
    final double menge = double.tryParse(mengeController.text) ?? 0.0;
    final double pricePerLiter =
        double.tryParse(pricePerLiterController.text) ?? 0.0;
    final double sumPrice = menge * pricePerLiter;
    rxSummePreisString.value = sumPrice.toStringAsFixed(
      2,
    ); // Formatieren auf 2 Dezimalstellen
  }

  void saveTankstopp() async {
    bool isErrorBySaving = false;
    String messageToUser = '';
    isFormValid = formKeyTank.currentState!.validate();
    if (!isFormValid) {
      print('Formular ist ungültig');
      messageToUser = 'Bitte überprüfen Sie Ihre Eingaben.';
      Get.snackbar(
        'Fehler',
        messageToUser,
        snackPosition: SnackPosition.BOTTOM,
        duration: const Duration(seconds: 2),
      );
      return;
    } else {
      print('Formular ist gültig');
      formKeyTank.currentState!.save();
      try {
        //creatiung a tank stop
        await _authRepository.createTankStop({
          'userId': _dataBox.read('userId'),
          'date': f.format(DateTime.parse(dateController.text)),
          'odometer': kilometerStandEdittingController.text,
          'liters': mengeController.text,
          'pricePerLiter': pricePerLiterController.text,
          'location': ortController.text,
        }).then((models.Document document) {
          print('Tankstopp erfolgreich gespeichert: ${document.data}');
          messageToUser = 'Tankstopp erfolgreich gespeichert!';
          isErrorBySaving = false;
        })
            // Handle specific Appwrite exceptions
            .catchError((error) {
          isErrorBySaving = true;
          if (error is AppwriteException) {
            // Handle specific Appwrite exceptions
            messageToUser = 'Appwrite Fehler: ${error.message}';
            print('Appwrite Fehler: ${error.message}');
          } else {
            // Handle other types of errors
            messageToUser = 'Allgemeiner Fehler: $error';
            print('Allgemeiner Fehler: $error');
          }
          print('Fehler bei der speicherung: $error');
        });
      }
      // Handle any other exceptions that might occur
      catch (e) {
        isErrorBySaving = true;
        messageToUser = 'Fehler beim Speichern des Tankstopps: $e';
        print('Fehler beim speichern: $e');
      }
      if (!isErrorBySaving) {
        clearTextEditingController();
      }
      // Handle button press logic here
      String title = isErrorBySaving ? 'Fehler' : 'Erfolg';
      Get.snackbar(
        title,
        messageToUser,
        backgroundColor: isErrorBySaving ? Colors.red : Colors.green,
        snackPosition: SnackPosition.BOTTOM,
        duration: const Duration(seconds: 4),
      );
    }
  }

  goToTankStopsView() async {
    clearTextEditingController();
    await Get.offAndToNamed(TanklistPage.namedRoute);
  }
}
