import 'package:flutter/material.dart';
import 'package:get/get.dart';


import '../../../core/config/server_response.dart';
import '../../../core/data/repositories/app_repositories.dart';
import '../../../core/dialogs/custom_loading.dart';
import '../../../core/utils/SessionCache.dart';
import '../../../core/utils/logs_utils.dart';
import '../../../custom_widgets/Fields/input_field.dart';
import '../../../custom_widgets/custom_dropdown.dart';
import '../../../custom_widgets/custom_toasty.dart';
import '../../../custom_widgets/date_picker.dart';
import '../../../models/DepositAccountResponse.dart';
import '../../../models/accountStatementResponseModel.dart';

class AccountStatementController extends GetxController {
  late InputField depositAccountField;
  RxBool isExpanded = false.obs;
  bool isCredit = false;
  bool isLoading = true;
  RxInt selectedIndex = 0.obs;

  late CustomDropDown genderField;

  final AppRepositories repository = Get.find<AppRepositories>();

  List<String> accountNumberList = SessionCache.instance.depositAccountList.map((element) => element.mbmBkmsnumber).toList();

  RxList<AccountStatementResponseModel> accountStatement = RxList.empty();

  RxList<AccountStatementResponseModel> allAccountStatement = RxList.empty();

  ///drop down
  RxList<DropDown> allDepositAccounts = RxList.empty();

  Rx<DepositAccount> selectedDepositAccount = DepositAccount.empty().obs;

  @override
  void onInit() {
    super.onInit();
    dp("Deposit List", accountStatement);

    for (int i = 0; i < SessionCache.instance.depositAccountList.length; i++) {
      DepositAccount depositAccount = SessionCache.instance.depositAccountList.elementAt(i);

      allDepositAccounts.add(
        DropDown(i.toString(), "${depositAccount.mbmBkmstitle} - ${depositAccount.mbmBkmsnumber}", depositAccount),
      );
    }

    //
  }

  @override
  Future<void> onReady() async {
    super.onReady();
    isLoading = true;
    update();
    // showLoader();

    var accountNumber = Get.arguments;

    dp("Account number", accountNumber);

    Future.delayed(Duration.zero).then((value) {
      if (accountNumber != null) {
        //

        var selectDepositAcc = allDepositAccounts.firstWhere((e) => (e.data as DepositAccount).mbmBkmsnumber == accountNumber['accountNumber']);

        selectedDepositAccount.value = selectDepositAcc.data;

        depositAccountField.setText(selectDepositAcc.label);
      } else {
        //

        selectedDepositAccount.value = allDepositAccounts.first.data as DepositAccount;

        depositAccountField.setText(allDepositAccounts.first.label);
      }

      fetchAccountStatementTransition();
    });
  }

  void updateSelectedDeposit(DropDown item) {
    selectedDepositAccount.value = item.data as DepositAccount;
    dp("Data update", item);
    fetchAccountStatementTransition();
  }

  void addItemToTop(AccountStatementResponseModel newItem) {
    accountStatement.insert(0, newItem);
  }

  Future<void> fetchAccountStatementTransition() async {
    ServerResponse response = await repository.fetchAccountStatement(selectedDepositAccount.value.mbmBkmsnumber);

    if (response.isError) {
      Toasty.error(response.errorMsg);
      hideLoader();
      isLoading = false;
      update();
      return;
    }

    List<AccountStatementResponseModel> list = List<AccountStatementResponseModel>.from(((response.response ?? []) as List<dynamic>).map((x) => AccountStatementResponseModel.fromMap(x)));

    dp("------------------------", list.toString());

    accountStatement.assignAll(list);
    allAccountStatement.assignAll(list);

    hideLoader();

    isLoading = false;

    update();
  }

  (DateTime, DateTime) weekFirstAndLastDate() {
    // Get the current date
    DateTime today = DateTime.now();

// Define the first day of the week (adjust if needed)
    int firstDayOfWeek = MaterialLocalizations.of(Get.context!).firstDayOfWeekIndex;

// Calculate the offset from today to the first day of the week
    int daysOffset = today.weekday - firstDayOfWeek;

// Handle negative offsets for weeks starting before current day
    daysOffset = daysOffset < 0 ? daysOffset + DateTime.daysPerWeek : daysOffset;

// Get the first date of the current week
    DateTime firstDate = today.subtract(Duration(days: daysOffset));

// Get the last date of the current week
    DateTime lastDate = firstDate.add(const Duration(days: DateTime.daysPerWeek - 1));

// Now you have both firstDate and lastDate representing the current week
    return (firstDate, lastDate);
  }

  (DateTime, DateTime) monthFirstAndLastDate() {
    //

    DateTime today = DateTime.now();

// Get the year
    int year = today.year;

// Get the month
    int month = today.month;

// Create the first date of the month
    DateTime firstDate = DateTime(year, month, 1);

// Get the last day of the month (tricky part)
    DateTime lastDate = DateTime(year, month + 1, 0);
    return (firstDate, lastDate);
  }

  var currentDate = DateTime.now();

  // void updateRange(int i) {
  //   dp("Current selected", i);
  //   selectedIndex.value = i;
  //   accountStatement.assignAll(allAccountStatement);
  //
  //   if (i == 1) {
  //     accountStatement.value = accountStatement.where((e) {
  //       DateTime date = DateTime.parse(e.drSgtGntrdate);
  //       dp("Date 1", date);
  //       return DateTime(date.year, date.month, date.day) == DateTime(currentDate.year, currentDate.month, currentDate.day);
  //     }).toList();
  //   }
  //   if (i == 2) {
  //     //
  //
  //     var weekDate = weekFirstAndLastDate();
  //
  //     dp("Week date", weekDate);
  //
  //     accountStatement.value = accountStatement.where((e) => DateTime.parse(e.drSgtGntrdate).isAfter(weekDate.$1) && DateTime.parse(e.drSgtGntrdate).isBefore(weekDate.$2)).toList();
  //   }
  //   if (i == 3) {
  //     accountStatement.value = accountStatement.where((e) {
  //       DateTime date = DateTime.parse(e.drSgtGntrdate);
  //       dp("Date 1", date);
  //       return date.month == currentDate.month && date.year == currentDate.year;
  //     }).toList();
  //   }
  //   if (i == 4) {
  //     accountStatement.value = accountStatement.where((e) {
  //       DateTime date = DateTime.parse(e.drSgtGntrdate);
  //       dp("Date 1", date);
  //       return date.year == currentDate.year;
  //     }).toList();
  //   }
  // }
  void updateRange(int i) {
    dp("Current selected", i);
    selectedIndex.value = i;
    accountStatement.assignAll(allAccountStatement);

    /// Check All Transactions
    if (i == 1) {
      accountStatement.value = accountStatement.where((e) {
        DateTime date = DateTime.parse(e.drSgtGntrdate);
        dp("Date 1", date);
        return DateTime(date.year, date.month, date.day) == DateTime(currentDate.year, currentDate.month, currentDate.day);
      }).toList();
    }

    /// Check Week Transactions
    if (i == 2) {
      var weekDate = weekFirstAndLastDate();
      dp("Week date", weekDate);

      accountStatement.value = accountStatement.where((e) {
        DateTime date = DateTime.parse(e.drSgtGntrdate);
        return date.isAfter(weekDate.$1.subtract(const Duration(days: 1))) && date.isBefore(weekDate.$2.add(const Duration(days: 1)));
      }).toList();
    }

    /// Month wise Transactions
    if (i == 3) {
      var monthDate = monthFirstAndLastDate();
      dp("Month date", monthDate);

      accountStatement.value = accountStatement.where((e) {
        DateTime date = DateTime.parse(e.drSgtGntrdate);
        return date.isAfter(monthDate.$1.subtract(const Duration(days: 1))) && date.isBefore(monthDate.$2.add(const Duration(days: 1)));
      }).toList();
    }

    /// Yearly Transaction
    if (i == 4) {
      accountStatement.value = accountStatement.where((e) {
        DateTime date = DateTime.parse(e.drSgtGntrdate);
        dp("Date 1", date);
        return date.year == currentDate.year;
      }).toList();
    }
  }
  // void showDateRangePic() async {
  //   //
  //   accountStatement.assignAll(allAccountStatement);
  //
  //   var range = await DatePicker.showRangeDatePicker();
  //
  //   dp("Date range", range?[0]);
  //
  //   dp("Date range", range?[1]);
  //
  //   if (range == null || range.isEmpty) {
  //     // Toasty.error("Range is not selected");
  //     return;
  //   }
  //
  //   var firstDate = DateTime(range[0]!.year, range[0]!.month, range[0]!.day, 24, 0, 0, 0);
  //
  //   var lastDate = DateTime(range[1]!.year, range[1]!.month, range[1]!.day, 23, 0, 0, 0);
  //
  //   dp("Las date", lastDate);
  //
  //   accountStatement.value = accountStatement.where((e) {
  //     DateTime date = DateTime.parse(e.drSgtGntrdate);
  //
  //     dp("Date 1", date);
  //
  //     return date.isAfter(firstDate) && date.isBefore(lastDate);
  //   }).toList();
  // }

  void showDateRangePic() async {
    accountStatement.assignAll(allAccountStatement);

    var range = await DatePicker.showRangeDatePicker();

    if (range == null) {
      // User clicked Cancel, do nothing
      return;
    }

    if (range.isEmpty || range.length != 2 || range[0] == null || range[1] == null) {
      // Show error message if the range is not properly selected
      Toasty.error("Please select both start and end dates.");
      return;
    }

    dp("Date range", range[0]);
    dp("Date range", range[1]);

    var firstDate = DateTime(range[0]!.year, range[0]!.month, range[0]!.day, 0, 0, 0, 0);
    var lastDate = DateTime(range[1]!.year, range[1]!.month, range[1]!.day, 23, 59, 59, 999);


   var currentDate = DateTime.now();
    if (lastDate.isAfter(currentDate) || !lastDate.isAtSameMomentAs(currentDate)) {
      // Show error message if the to date is after the current date (excluding current date)
      Toasty.error("Please select a date range up to the current date.");
      return;
    }


    dp("First date", firstDate);
    dp("Last date", lastDate);

    accountStatement.value = accountStatement.where((e) {
      DateTime date = DateTime.parse(e.drSgtGntrdate);
      dp("Transaction date", date);
      return date.isAfter(firstDate.subtract(Duration(milliseconds: 1))) && date.isBefore(lastDate.add(Duration(milliseconds: 1)));
    }).toList();
  }


}
