import 'dart:async';
import 'dart:io';

import 'package:camera/camera.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/Utils/commonServices.dart';
import 'package:generp/services/api_calling.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

import '../../Models/ordersModels/AddOrderPaymentSelectAccountResponse.dart';
import '../../Models/ordersModels/AddOrderPaymentSelectOrderResponse.dart';
import '../../Utils/app_colors.dart';

class Addpaymentprovider extends ChangeNotifier {
  bool _submitClicked = false;
  TextEditingController dropDownSearchController = TextEditingController();

  TextEditingController amountController = TextEditingController();
  TextEditingController orderAdjustedAmountController = TextEditingController();
  TextEditingController descriptionController = TextEditingController();
  TextEditingController paymentReceivedDateController = TextEditingController();
  TextEditingController paymentRefController = TextEditingController();

  String selectAccountError = "";
  String amountError = "";
  String orderAdjustedAmountError = "";
  String descriptionError = "";
  String paymentModeError = "";
  String paymentRefError = "";

  List<TextEditingController> orderAmountControllers = [];

  String? FileError;
  String? dateError;
  bool _isLoading = false;
  int _imagePicked = 0;
  File? _image;
  File? _imageName;
  final ImagePicker _picker = ImagePicker();
  DateTime? _date;
  String? _formattedDate;
  String? _formattedDateToSend;
  Timer? _debounce;

  List<String> _paymentMode = [];
  List<String> _description = [];
  List<AccountList> _accountList = [];
  List<OrderList> _orderList = [];
  List<Map<String, String>> _selectedOrders = [];

  String? _selectedPaymentMode;
  String? _selectedDescription;
  AccountList? _selectedAccountList;
  String? _selectedAccountID;
  String? _selectedAccountName;
  OrderList? _selectedOrderLists;
  List<String?> _selectedOrderIds = [];
  List<String?> _selectedOrderNumbers = [];
  List<String?> _selectedTotalAmounts = [];
  List<String?> _selectedBalanceAmounts = [];
  List<String?> _selectedCreatedDatetimes = [];

  bool get submitClicked => _submitClicked;
  List<String> get paymentMode => _paymentMode;
  List<String> get description => _description;
  bool get isLoading => _isLoading;
  List<AccountList> get accountList => _accountList;
  List<OrderList> get orderList => _orderList;
  List<Map<String, String>> get selectedOrders => _selectedOrders;

  String? get selectedPaymentMode => _selectedPaymentMode;
  String? get selectedDescription => _selectedDescription;
  AccountList? get selectedAccountList => _selectedAccountList;
  String? get selectedAccountID => _selectedAccountID;
  String? get selectedAccountName => _selectedAccountName;
  OrderList? get selectedOrderLists => _selectedOrderLists;
  List<String?> get selectedOrderIds => _selectedOrderIds;
  List<String?> get selectedOrderNumbers => _selectedOrderNumbers;
  List<String?> get selectedTotalAmounts => _selectedTotalAmounts;
  List<String?> get selectedBalanceAmounts => _selectedBalanceAmounts;
  List<String?> get selectedCreatedDatetimes => _selectedCreatedDatetimes;
  String? get formattedDate => _formattedDate;
  String? get formattedDateToSend => _formattedDateToSend;

  DateTime? get dateNow => _date;
  File? get imagePath => _imageName;
  File? get imageFilePath => _image;
  int get imagePicked => _imagePicked;

  set submitClicked(bool value) {
    _submitClicked = value;
    notifyListeners();
  }

  set accountList(List<AccountList> value) {
    _accountList = value;
    notifyListeners();
  }

  set selectedPaymentMode(String? value) {
    _selectedPaymentMode = value;
    paymentModeError = "";
    notifyListeners();
  }

  set selectedOrders(value) {
    _selectedOrders = selectedOrders;
    notifyListeners();
  }

  set selectedDescription(String? value) {
    _selectedDescription = value;
    descriptionError = "";
    notifyListeners();
  }

  set selectedAccountList(AccountList? value) {
    _selectedAccountList = value;
    _selectedAccountID = value?.id!;
    _selectedAccountName = value!.text!;
    selectAccountError = "";
    notifyListeners();
  }

  set selectedAccountID(String? value) {
    _selectedAccountID = value;
    notifyListeners();
  }

  set selectedAccountName(String? value) {
    _selectedAccountName = value;
    notifyListeners();
  }

  set selectedOrderLists(OrderList? value) {
    _selectedOrderLists = value;
    notifyListeners();
  }

  void updateSelectedOrderId(int index, OrderList? value) {
    _selectedOrderLists = value!;
    _updateAdjustedAmount();
    _selectedOrderIds[index] = value.orderId;
    print(_selectedOrderIds[index]);
    notifyListeners();
  }

  set selectedOrderNumbers(List<String?> value) {
    _selectedOrderNumbers = value;
    notifyListeners();
  }

  set selectedTotalAmounts(List<String?> value) {
    _selectedTotalAmounts = value;
    notifyListeners();
  }

  set selectedBalanceAmounts(List<String?> value) {
    _selectedBalanceAmounts = value;
    notifyListeners();
  }

  set selectedCreatedDatetimes(List<String?> value) {
    _selectedCreatedDatetimes = value;
    notifyListeners();
  }

  set imagePath(File? value) {
    _imageName = value;
    notifyListeners();
  }

  set imageFilePath(File? value) {
    _image = value;
    notifyListeners();
  }

  set imagePicked(value) {
    _imagePicked = value;
    notifyListeners();
  }

  set formattedDate(String? value) {
    _formattedDate = value;
    paymentReceivedDateController.text = _formattedDate!;
    dateError = null;
    notifyListeners();
  }

  void setDate(DateTime newDate) {
    _date = newDate;
    _formattedDate = DateFormat('d MMM yyyy').format(newDate);
    _formattedDateToSend = DateFormat('yyyy-MM-dd').format(newDate);
    paymentReceivedDateController.text = _formattedDate!;
    dateError = null;
    notifyListeners();
  }

  void addNewRow() {
    // if (_selectedOrderIds.length < _orderList.length ) {
    final controller = TextEditingController();

    // Add a listener to recalculate the total when the text changes
    controller.addListener(_updateAdjustedAmount);

    orderAmountControllers.add(TextEditingController());
    _selectedOrderIds.add(null);

    notifyListeners();
  }

  void removeRow(int index) {
    orderAmountControllers[index].removeListener(_updateAdjustedAmount);
    orderAmountControllers[index].dispose();
    orderAmountControllers.removeAt(index);
    _selectedOrderIds.removeAt(index);
    _updateAdjustedAmount();
    notifyListeners();
  }

  void _updateAdjustedAmount() {
    int tempAdjustAmount = 0;

    for (int i = 0; i < orderAmountControllers.length; i++) {
      final text = orderAmountControllers[i].text;
      if (_selectedOrderIds[i] != null && text.isNotEmpty) {
        tempAdjustAmount += int.tryParse(text) ?? 0;
      }
    }
    int amountControllerAmount = int.parse(amountController.text.toString());
    if (tempAdjustAmount > amountControllerAmount) {
      orderAdjustedAmountError =
          "Amount Should not be greater than Total Amount";
    } else {
      orderAdjustedAmountError = "";
    }

    orderAdjustedAmountController.text = tempAdjustAmount.toString();
    notifyListeners();
  }

  void updateAdjustedAmount() => _updateAdjustedAmount();

  List<Map<String, String>> getFormData() {
    _selectedOrders = [];
    Map<String, String> latestEntries = {};
    var tempAdjustAmount = 0;
    for (int i = 0; i < orderAmountControllers.length; i++) {
      if (_selectedOrderIds[i] != null &&
          orderAmountControllers[i].text.isNotEmpty) {
        // latestEntries[_selectedOrderIds[i]!] = orderAmountControllers[i].text;
        _selectedOrders.add({
          "order_id": _selectedOrderIds[i]!,
          "amount": orderAmountControllers[i].text,
        });
        tempAdjustAmount =
            tempAdjustAmount +
            int.parse(
              double.parse(orderAmountControllers[i].text).round().toString(),
            );
      }
    }

    print("Form Data: $_selectedOrders");
    orderAdjustedAmountController.text = tempAdjustAmount.toString();
    print(tempAdjustAmount);
    notifyListeners();
    return _selectedOrders;
  }

  Future<void> ordersAddPaymentAPIViewFunction(context) async {
    try {
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.addOrderpaymentListViewAPI(
        provider.empId,
        provider.session,
      );
      if (data != null) {
        if (data.error == "0") {
          _paymentMode = data.paymentMode!;
          _description = data.description!;
          checkDropdownselected();
          // if (_selectedAccountList != null &&
          //     !_accountList.contains(_selectedAccountList)) {
          //   dropDownSearchController.clear();
          //   _selectedAccountList = null;
          //   _selectedAccountID = "";
          //   _selectedAccountName = "";
          // }

          notifyListeners();
        } else {}
      } else {}
    } catch (e) {}
  }

  void onSearchChanged(
    BuildContext context,
    String mode,
    String? accountId,
    String search,
  ) {
    if (_debounce?.isActive ?? false) _debounce!.cancel();
    _debounce = Timer(const Duration(milliseconds: 300), () {
      // if (search.isNotEmpty) { // Only call API for non-empty search
      ordersAddPaymentSelectAccountAPIFunction(
        context,
        mode,
        accountId,
        search,
      );
      // } else {
      //   _accountList = []; // Clear list for empty search
      //   _isLoading = false;
      //   notifyListeners();
      // }
    });
  }

  Future<void> ordersAddPaymentSelectAccountAPIFunction(
    context,
    mode,
    accountId,
    search,
  ) async {
    print(search);
    try {
      if (search.isEmpty) {
        _accountList = [];
        _isLoading = false;
        notifyListeners();
        return;
      }
      _isLoading = true;
      notifyListeners();
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.AddOrderPaymentSelectAccountAPI(
        provider.empId,
        provider.session,
        mode,
        search,
      );
      if (data != null) {
        if (data.error == "0") {
          _accountList = data.accountList!;
          if (_selectedAccountList != null &&
              !_accountList.contains(_selectedAccountList)) {
            _selectedAccountList = null;
            _selectedAccountID = null;
            _selectedAccountName = null;
          }
          _isLoading = false;

          notifyListeners();

          if (_accountList.isNotEmpty && _selectedAccountID != null) {
            await ordersAddPaymentSelectOrderAPIFunction(
              context,
              _selectedAccountID,
            );
          }
        } else {
          selectAccountError = data.message ?? "Failed to load accounts";
          _isLoading = false;
          notifyListeners();
        }
      } else {
        selectAccountError = "No data received from server";
        _isLoading = false;
        notifyListeners();
      }
    } catch (e) {
      selectAccountError = "An error occurred while fetching accounts";
      _isLoading = false;
      notifyListeners();
    }
  }

  Future<void> ordersAddPaymentSelectOrderAPIFunction(
    context,
    accountID,
  ) async {
    try {
      print("ACID:$accountID");
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.AddOrderPaymentSelectOrderAPI(
        provider.empId,
        provider.session,
        accountID,
      );
      if (data != null) {
        if (data.error == "0") {
          _orderList = data.orderList!;
          notifyListeners();
        } else {}
      } else {}
    } catch (e) {}
  }

  Future<void> ordersAddPaymentAPISubmitFunction(
    context,
    accountId,
    selDescription,
    selectedOrders,
    paymentMode,
  ) async {
    try {
      if (!validateAddPayment()) {
        return;
      }
      _submitClicked = true;
      notifyListeners();

      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.addOrderpaymentListSubmitAPI(
        provider.empId,
        provider.session,
        accountId,
        selDescription,
        selectedOrders,
        amountController.text,
        paymentReceivedDateController.text,
        paymentMode,
        paymentRefController.text,
        _image,
      );
      if (data != null) {
        if (data.error == "0") {
          _submitClicked = false;
          resetForm();
          Navigator.pop(context);
          toast(context, data.message);
          notifyListeners();
        } else {
          _submitClicked = false;
          notifyListeners();
          toast(context, data.message);
        }
      } else {
        submitClicked = false;
        notifyListeners();
      }
    } catch (e) {
      submitClicked = false;
      notifyListeners();
    }
  }

  imgFromCamera(context) async {
    // Capture a photo
    try {
      final XFile? galleryImage = await _picker.pickImage(
        source: ImageSource.camera,
        imageQuality: 50,
      );
      debugPrint("added");

      _image = File(galleryImage!.path);
      _imageName = File(galleryImage.name);
      _imagePicked = 1;
      FileError = null;
      notifyListeners();
    } catch (e) {
      debugPrint("mmmm: ${e.toString()}");
    }
  }

  imgFromGallery(context) async {
    // Pick an image
    try {
      final XFile? galleryImage = await _picker.pickImage(
        source: ImageSource.gallery,
      );
      final bytes = (await galleryImage?.readAsBytes())?.lengthInBytes;
      final kb = bytes! / 1024;
      final mb = kb / 1024;

      debugPrint("Jenny: bytes:$bytes, kb:$kb, mb: $mb");

      _image = File(galleryImage!.path);
      _imageName = File(galleryImage.name);
      _imagePicked = 1;
      FileError = null;
      notifyListeners();
      // var file = FlutterImageCompress.compressWithFile(galleryImage!.path);
    } catch (e) {
      debugPrint("mmmm: ${e.toString()}");
    }
  }

  void onChangeAmount(value) {
    _updateAdjustedAmount();
    amountError = "";
    notifyListeners();
  }

  void onChangeorderAdjustedAmount(value) {
    _updateAdjustedAmount();
    notifyListeners();
  }

  void onChangeDescription(value) {
    descriptionError = "";
    notifyListeners();
  }

  void onChangepaymentRef(value) {
    paymentRefError = "";
    notifyListeners();
  }

  bool validateAddPayment() {
    bool isValid = true;
    selectAccountError = "";
    amountError = "";
    orderAdjustedAmountError = "";
    descriptionError = "";
    paymentModeError = "";
    paymentRefError = "";
    if (_selectedAccountList == null || _selectedAccountID == null) {
      selectAccountError = "Please select an Account";
      isValid = false;
    }
    if (amountController.text.trim().isEmpty) {
      isValid = false;
      amountError = "Please Enter the Amount";
    }
    if (orderAdjustedAmountController.text.trim().isEmpty) {
      isValid = false;
      orderAdjustedAmountError = "Please Enter the Amount";
    }
    if (_selectedDescription == null) {
      descriptionError = "Please select";
      isValid = false;
    }
    if (paymentReceivedDateController.text.trim().isEmpty) {
      isValid = false;
      paymentModeError = "Please Enter the Amount";
    }
    if (_selectedPaymentMode == null) {
      paymentModeError = "Please select an Account";
      isValid = false;
    }

    if (paymentRefController.text.trim().isEmpty) {
      isValid = false;
      paymentRefError = "Please Enter the Payment reference";
    }
    _submitClicked = false;
    notifyListeners();
    return isValid;
  }

  void resetForm() {
    dropDownSearchController.clear();
    amountController.clear();
    orderAdjustedAmountController.clear();
    descriptionController.clear();
    paymentReceivedDateController.clear();
    paymentRefController.clear();
    _selectedAccountList = null;
    _selectedAccountID = null;
    _selectedAccountName = null;
    _selectedOrderIds.clear();
    _selectedOrderNumbers.clear();
    _selectedTotalAmounts.clear();
    _selectedBalanceAmounts.clear();
    _selectedCreatedDatetimes.clear();
    _image = null;
    _imageName = null;
    _imagePicked = 0;
    _selectedOrders.clear();
    for (var controller in orderAmountControllers) {
      controller.dispose();
    }
    orderAmountControllers.clear();
    selectAccountError = "";
    amountError = "";
    orderAdjustedAmountError = "";
    descriptionError = "";
    paymentModeError = "";
    paymentRefError = "";
    FileError = null;
    dateError = null;
    _accountList = [];
    _selectedAccountID = "";
    _selectedAccountList = null;
    _selectedAccountName = "";
    checkDropdownselected();
    notifyListeners();
  }

  void checkDropdownselected() {
    if (_selectedAccountList != null &&
        !_accountList.contains(_selectedAccountList)) {
      _selectedAccountID = null;
      _selectedAccountName = "";
    }

    if (_selectedOrderLists != null &&
        !_orderList.contains(_selectedOrderLists)) {
      _selectedOrderLists = null;
      _selectedOrderIds.clear();
      _selectedOrderIds = [];
      _selectedOrderIds.clear();
      _selectedOrderNumbers.clear();
      _selectedTotalAmounts.clear();
      _selectedBalanceAmounts.clear();
      _selectedCreatedDatetimes.clear();
    }
    notifyListeners();
  }

  void showDatePickerDialog(BuildContext context) {
    if (_date == null) {
      setDate(
        DateTime.now(),
      ); // Ensure current date is set before opening the picker
    }
    showCupertinoModalPopup<void>(
      context: context,
      builder:
          (BuildContext context) => Container(
            height: 250,
            padding: const EdgeInsets.only(top: 6.0),
            margin: EdgeInsets.only(
              bottom: MediaQuery.of(context).viewInsets.bottom,
            ),
            color: CupertinoColors.systemBackground.resolveFrom(context),
            child: SafeArea(
              top: false,
              child: Column(
                children: [
                  Expanded(
                    flex: 2,
                    child: SizedBox(
                      height: 40,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          CupertinoButton(
                            child: Text(
                              'Cancel',
                              style: TextStyle(
                                fontFamily: "JakartaMedium",
                                color: AppColors.app_blue,
                              ),
                            ),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                          CupertinoButton(
                            child: Text(
                              'Done',
                              style: TextStyle(
                                fontFamily: "JakartaMedium",
                                color: AppColors.app_blue,
                              ),
                            ),
                            onPressed: () {
                              setDate(_date ?? DateTime.now());
                              Navigator.pop(context);
                            },
                          ),
                        ],
                      ),
                    ),
                  ),
                  Expanded(
                    flex: 4,
                    child: CupertinoDatePicker(
                      dateOrder: DatePickerDateOrder.dmy,
                      initialDateTime: _date ?? DateTime.now(),
                      mode: CupertinoDatePickerMode.date,
                      use24hFormat: true,
                      showDayOfWeek: true,
                      onDateTimeChanged: (DateTime newDate) {
                        setDate(newDate);
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
    );
  }
}
