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,s){

    }
  }

  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,s){
      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,s){

    }
  }

  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,s){
      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 (_description == null || _selectedDescription==null) {
      descriptionError = "Please select";
      isValid = false;
    }
    if(paymentReceivedDateController.text.trim().isEmpty){
      isValid = false;
      paymentModeError = "Please Enter the Amount";
    }
    if (_paymentMode == null || _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();
    orderAmountControllers.forEach((controller) => 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: 216,
        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);
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}