import 'dart:io';

import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:generp/Models/financeModels/paymentRequisitionDetailsResponse.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 'approveRejectPaymentRequestResponse.dart';

class Requesitionlidtdetailsprovider extends ChangeNotifier {
  bool _showMoreDetails = false;
  final numberFormat = NumberFormat.decimalPattern();
  TextEditingController requestedAmount = TextEditingController();
  TextEditingController approvedAmountReadonly = TextEditingController();
  TextEditingController proposedPaymentAccount = TextEditingController();
  TextEditingController approvedAmount = TextEditingController();
  TextEditingController accountName = TextEditingController();
  TextEditingController branch = TextEditingController();
  TextEditingController requestingPurpose = TextEditingController();
  TextEditingController description = TextEditingController();
  TextEditingController amount = TextEditingController();
  TextEditingController paymentMode = TextEditingController();
  TextEditingController bankUpiID = TextEditingController();
  TextEditingController bankName = TextEditingController();
  TextEditingController bankBranchName = TextEditingController();
  TextEditingController bankAccountNumber = TextEditingController();
  TextEditingController bankIfscCode = TextEditingController();
  TextEditingController bankHolderName = TextEditingController();
  TextEditingController paymentAccountSearchController =
      TextEditingController();

  TextEditingController editPaymentRequestedAmountController =
      TextEditingController();
  TextEditingController editPaymentRequestedEditableAmountController =
      TextEditingController();
  bool _editPaymentProcessLoading = false;
  String? editableAmountError;

  String? proposedAmountError;
  PaymentDetails _paymentDetails = PaymentDetails();
  RequestDetails _requestDetails = RequestDetails();
  PaymentRequestDetails _paymentRequestDetails = PaymentRequestDetails();
  PaymentAccounts? _selectedPaymentAccounts;

  List<PaymentModes> _paymentModes = [];
  List<PaymentAccounts> _paymentAccounts = [];

  var _selectedValue;
  var _selectedID;

  List<String> _headings = [];
  List<String> _subHeadings = [];

  String? FileError;
  var _image_picked = 0;
  final ImagePicker _picker = ImagePicker();

  File? _image;
  File? _imageName;

  get image_picked => _image_picked;

  bool get showMoreDetails => _showMoreDetails;

  bool get editPaymentProcessLoading => _editPaymentProcessLoading;

  int get imagePicked => _image_picked;

  File? get imagePath => _imageName;

  File? get imageFilePath => _image;

  set editPaymentProcessLoading(bool value) {
    _editPaymentProcessLoading = value;
    notifyListeners();
  }

  set imagePicked(int value) {
    _image_picked = value;
    notifyListeners();
  }

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

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

  set showMoreDetails(bool value) {
    _showMoreDetails = value;
    notifyListeners();
  }

  PaymentDetails get paymentsDetails => _paymentDetails;

  RequestDetails get requestsDetails => _requestDetails;

  List<PaymentAccounts> get paymentsAccounts => _paymentAccounts;

  List<PaymentModes> get paymentsModes => _paymentModes;

  PaymentRequestDetails get paymentsReqDetails => _paymentRequestDetails;

  PaymentAccounts? get selectedPaymentAccounts => _selectedPaymentAccounts;

  get selectedValue => _selectedValue;

  get selectedID => _selectedID;

  List<String> get subHeadings => _subHeadings;

  set subHeadings(List<String> value) {
    _subHeadings = value;
    notifyListeners();
  }

  List<String> get Headings => _headings;

  set selectedPaymentAccounts(PaymentAccounts? value) {
    _selectedPaymentAccounts = value;
    _selectedValue = value!.name!;
    _selectedID = value.id;
    selectpaymentAccountError = null;
    notifyListeners();
  }

  set selectedValue(value) {
    _selectedValue = value;
    notifyListeners();
  }

  set selectedID(value) {
    _selectedID = value;
    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);
      _image_picked = 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);
      _image_picked = 1;
      FileError = null;
      notifyListeners();
      // var file = FlutterImageCompress.compressWithFile(galleryImage!.path);
    } catch (e) {
      debugPrint("mmmm: ${e.toString()}");
    }
  }

  Future<void> paymentRequesitionDetails(context, paymentRequestId) async {
    try {
      var provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.paymentRequestionDetailsAPI(
        provider.empId,
        provider.session,
        paymentRequestId,
      );
      if (data != null) {
        if (data.error == "0") {
          _headings = [
            "Requested Account",
            "Proposed Account Name",
            "Branch",
            "Requesting Propose",
            "Payment Mode",
            "Created Employee",
            "Attachment",
            "Requested Date",
            "Note",
            "Level 1 Remarks",
            "Level 1 Approved By",
            "Level 2 Remarks",
            "Level 2 Approved By",
            "Approved Amount",
            "Created Date/Time",
            "Updated Date/Time",
          ];
          _paymentDetails =
              data.paymentDetails ??
              PaymentDetails(
                accountId: "-",
                accountName: "-",
                amount: "-",
                attachmentDirFilePath: "-",
                attachmentViewFileName: "-",
                bankAccountHolderName: "-",
                bankAccountNumber: "-",
                bankBranchName: "-",
                bankIfscCode: "-",
                bankName: "-",
                bankUpiId: "-",
                createdDatetime: "-",
                createdEmployeeId: "-",
                description: "-",
                id: "-",
                isExists: "-",
                mode: "-",
                paymentAccountId: "-",
                paymentAccountName: "-",
                paymentDate: "-",
                paymentEmployeeName: "-",
                paymentModeId: "-",
                paymentReferenceNumber: "-",
                paymentRemarks: "-",
                refId: "-",
                refType: "-",
                updatedDatetime: "-",
              );

          _requestDetails =
              data.requestDetails ??
              RequestDetails(
                updatedDatetime: "-",
                id: "-",
                description: "-",
                createdDatetime: "-",
                attachmentViewFileName: "-",
                attachmentDirFilePath: "-",
                amount: "-",
                accountName: "-",
                accountId: "-",
                branch: "-",
                createdEmployee: "-",
                date: "-",
                isProcessedPaymentRequest: "-",
                level1ApprovalRemarks: "-",
                level1Employee: "-",
                level2ApprovalRemarks: "-",
                level2Employee: "-",
                proposedAccount: "-",
                proposedAccountId: "-",
                requestedAmount: "-",
                requestingPurpose: "-",
                requestMode: "-",
                status: "-",
                transDis: "-",
              );

          _subHeadings = [
            _requestDetails.accountName ?? "-",
            _requestDetails.proposedAccount ?? "-",
            _requestDetails.branch ?? "-",
            _requestDetails.requestingPurpose ?? "-",
            _requestDetails.requestMode ?? "-",
            _requestDetails.createdEmployee ?? "-",
            _requestDetails.attachmentViewFileName ?? "-",
            _requestDetails.date ?? "-",
            _requestDetails.description ?? "-",
            _requestDetails.level1ApprovalRemarks ?? "-",
            _requestDetails.level1Employee ?? "-",
            _requestDetails.level2ApprovalRemarks ?? "-",
            _requestDetails.level2Employee ?? "-",
            _requestDetails.amount ?? "-",
            _requestDetails.createdDatetime ?? "-",
            _requestDetails.updatedDatetime ?? "-",
          ];

          print("here 2121");
          preValues();
          notifyListeners();
        }
      }
    } catch (e) {}
  }

  preValues() {// safeNormalizeAmount()
    print("here 212ssass1");
    requestedAmount.text = safeNormalizeAmount(_requestDetails.requestedAmount);
    proposedPaymentAccount.text = _requestDetails.proposedAccount ?? "-";
    approvedAmountReadonly.text = safeNormalizeAmount(_requestDetails.amount);
    approvedAmount.text = safeNormalizeAmount(_requestDetails.amount);
    accountName.text =        _requestDetails.accountName ?? "";
    branch.text =             _requestDetails.branch ?? "";
    requestingPurpose.text =  _requestDetails.requestingPurpose ?? "";
    description.text =       _requestDetails.description ?? "";
    amount.text =             safeNormalizeAmount(_requestDetails.amount);
    paymentMode.text =        _requestDetails.requestMode ?? "";
    bankUpiID.text =          _requestDetails.bankUpiId ?? "";
    bankName.text =           _requestDetails.bankName ?? "";
    bankBranchName.text =     _requestDetails.bankBranchname ?? "";
    bankAccountNumber.text =  _requestDetails.bankAccountNumber ?? "";
    bankIfscCode.text =       _requestDetails.bankIfscCode ?? "";
    bankHolderName.text =     _requestDetails.bankAccountHolderName ?? "";
    notifyListeners();
  }

  String safeNormalizeAmount(String? input) {
    if (input == null || input.trim().isEmpty) return "0";

    // Remove currency symbols, commas and spaces - keep digits and dots
    String cleaned = input.replaceAll(RegExp(r'[^0-9.]'), '');

    // Handle multiple decimal points: keep only first dot
    int firstDot = cleaned.indexOf('.');
    if (firstDot != -1) {
      String before = cleaned.substring(0, firstDot + 1);
      String after = cleaned.substring(firstDot + 1).replaceAll('.', '');
      cleaned = before + after;
    }

    return cleaned.isEmpty ? "0" : cleaned;
  }


  Future<void> approveRejectPaymentRequestAPIFunction(
    context,
    paymentRequestId,
  ) async {
    try {
      var provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.approveRejectPaymentRequestAPI(
        provider.empId,
        provider.session,
        paymentRequestId,
      );
      if (data != null) {
        if (data.error == "0") {
          _paymentModes = data.paymentModes!;
          _paymentAccounts = data.paymentAccounts!;
          _paymentRequestDetails = data.paymentRequestDetails!;
          notifyListeners();
        }
      }
    } catch (e) {}
  }

  String? remarksError;
  String? ApprovedAmountError;
  String? selectpaymentAccountError;
  bool _submitClicked = false;

  bool get submitClicked => _submitClicked;

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

  Future<bool> paymentrequisitionRejectSubmitAPIFunction(
      context,
      mode,
      paymentRequestId,
      approveRemarks,
      ) async {
    print(" === REJECT PROVIDER METHOD STARTED ===");

    // Set loading to true at the start
    _isLoading = true;
    notifyListeners();
    print(" Loading set to TRUE in reject method");

    bool success = false;

    try {
      print(" Starting validation for rejection...");

      // if (approveRemarks.toString().trim().isEmpty) {
      //   print(" Remarks validation failed");
      //   remarksError = "Please Enter Remarks";
      //   _isLoading = false;
      //   notifyListeners();
      //   return false;
      // }

      print(" Validation passed");

      var provider = Provider.of<HomescreenNotifier>(context, listen: false);

      print(" Calling reject API...");
      final data = await ApiCalling.RejectPaymentRequestSubmitAPI(
        provider.empId,
        provider.session,
        mode,
        paymentRequestId,
        approveRemarks,
      );
      print(" Reject API call completed");

      if (data != null) {
        print(" Reject API Response: error=${data.error}, message=${data.message}");

        if (data.error == "0") {
          print(" Reject API SUCCESS");
          success = true;

          if (context.mounted) {
            print(" Context mounted - performing UI operations");
            paymentRequesitionDetails(context, paymentRequestId);
            resetAll();
            toast(context, data.message);
            Navigator.pop(context, true); // Pass true to indicate success
          }
        } else {
          print(" Reject API returned error: ${data.message}");
          if (context.mounted) {
            toast(context, data.message ?? "Rejection failed");
          }
        }
      } else {
        print(" NULL response from reject API");
        if (context.mounted) {
          toast(context, "No response from server");
        }
      }
    } catch (e) {
      print(" EXCEPTION in reject provider method: $e");
      if (context.mounted) {
        toast(context, "Error: ${e.toString()}");
      }
    } finally {
      // Always set loading to false when done
      _isLoading = false;

      notifyListeners();
      print(" Loading set to FALSE in reject method finally block");
    }

    print(" === REJECT PROVIDER METHOD COMPLETED ===");
    return success;
  }

  bool _isLoading = false;

  bool get isLoading => _isLoading;

  set isLoading(bool value) {
    _isLoading = value;
    notifyListeners();
  }

  Future<void> paymentrequisitionApproveSubmitAPIFunction(//this is
      BuildContext context,
      String mode,
      String payment_request_id,
      String approved_amount,
      String approve_remarks,
      String proposed_payment_account_id,
      ) async {
    print(" === PROVIDER METHOD STARTED ===");

    // Set loading to true at the start
    _isLoading = true;
    notifyListeners();

    try {
      print(" Starting validation...");
      if (!validateApproval(approved_amount, approve_remarks, proposed_payment_account_id)) {
        print(" VALIDATION FAILED - Stopping execution");
        _isLoading = false;
        notifyListeners();
        return;
      }
      print(" Validation passed");

      print(" Getting home provider...");
      var homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);
      print(" Emp ID: ${homeProvider.empId}, Session: ${homeProvider.session}");

      print(" Calling API...");
      final data = await ApiCalling.ApprovePaymentRequestSubmitAPI(
        homeProvider.empId,
        homeProvider.session,
        mode,
        payment_request_id,
        approved_amount,
        approve_remarks,
        proposed_payment_account_id,
      );
      print(" API call completed");

      if (data != null) {
        print(" API Response: error=${data.error}, message=${data.message}");

        if (data.error == "0") {
          print(" API SUCCESS - Processing...");

          // Check if context is still valid before UI operations
          if (context.mounted) {
            print(" Context mounted - performing UI operations");
            paymentRequesitionDetails(context, payment_request_id);
            resetAll();
            toast(context, data.message);
            Navigator.pop(context, true);
            print(" UI operations completed");
          } else {
            print("️ Context not mounted - skipping UI operations");
          }

          notifyListeners();
          print(" Notify listeners called");
        } else {
          print(" API returned error: ${data.message}");
          if (context.mounted) {
            toast(context, data.message ?? "Submission failed");
          }
        }
      } else {
        print(" NULL response from API");
        if (context.mounted) {
          toast(context, "No response from server");
        }
      }
    } catch (e, s) {
      print(" EXCEPTION in provider method: $e");
      print(" Stack trace: $s");
      // Show error to user
      if (context.mounted) {
        toast(context, "Error: ${e.toString()}");
      }
    } finally {
      // Set loading to false when everything is done (success or error)
      _isLoading = false;
      notifyListeners();
      print(" Loading state set to false");
    }

    print(" === PROVIDER METHOD COMPLETED ===");
  }


  editPrevalues() {
    editPaymentRequestedAmountController.text =
        _requestDetails.requestedAmount ?? "-";
    editPaymentRequestedEditableAmountController.text =
        _requestDetails.requestedAmount ?? "-";
    notifyListeners();
  }

  onChangeEditableAmount(value, context) {
    var provider = Provider.of<HomescreenNotifier>(context, listen: false);
    if (provider.empId == "5" ||
        provider.empId == "130" ||
        provider.empId == "131" ||
        provider.empId == "6") {
      editableAmountError = "";
    } else {
      if (numberFormat.parse(editPaymentRequestedAmountController.text) <
          numberFormat.parse(
            editPaymentRequestedEditableAmountController.text,
          )) {
        editableAmountError =
            "Approved Amount should not be greater than amount";
      } else {
        editableAmountError = null;
      }
    }
    _editPaymentProcessLoading = false;
    notifyListeners();
  }

  bool validateEditprocessPayment(context) {
    bool isValid = true;
    editableAmountError = null;
    var provider = Provider.of<HomescreenNotifier>(context, listen: false);

    if (editPaymentRequestedEditableAmountController.text.isNotEmpty) {
      if (provider.empId == "5" ||
          provider.empId == "130" ||
          provider.empId == "131" ||
          provider.empId == "6") {
        editableAmountError = null;
      } else {
        if (numberFormat.parse(editPaymentRequestedAmountController.text) <
            numberFormat.parse(
              editPaymentRequestedEditableAmountController.text,
            )) {
          editableAmountError =
              "Approved Amount should not be greater than amount";
          isValid = false;
        } else {
          editableAmountError = null;
        }
      }
    }

    _editPaymentProcessLoading = false;
    notifyListeners();
    return isValid;
  }

  Future<void> editProcessedPaymentAmountAPIFunction(
    context,
    paymentRequestId,
    approvalAmount,
  ) async {
    try {
      _editPaymentProcessLoading = true;
      notifyListeners();
      if (!validateEditprocessPayment(context)) {
        return;
      }
      var provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.editProcessedRequestAmountAPI(
        provider.empId,
        provider.session,
        paymentRequestId,
        approvalAmount,
      );
      if (data != null) {
        if (data.error == "0") {
          _editPaymentProcessLoading = false;
          paymentRequesitionDetails(context, paymentRequestId);
          resetAll();
          toast(context, data.message);
          Navigator.pop(context, true);
          notifyListeners();
        } else {
          _editPaymentProcessLoading = false;
          notifyListeners();
        }
      } else {
        _editPaymentProcessLoading = false;
        notifyListeners();
      }
    } catch (e) {
      _editPaymentProcessLoading = false;
      notifyListeners();
    }
  }

  bool validateApproval(
      String approvedAmount, //
      String approveRemarks, //
      String proposedPaymentAccountId, //
      ) {
    print(" === VALIDATION STARTED ===");
    print("   Approved Amount: '$approvedAmount'");
    print("   Requested Amount: '${requestedAmount.text}'");
    print("   Remarks: '$approveRemarks'");
    print("   Payment Account ID: '$proposedPaymentAccountId'");
    print("   Selected ID: '$_selectedID'");

    remarksError = null;
    ApprovedAmountError = null;
    selectpaymentAccountError = null;
    bool isValid = true;

    // Fix 1: Use the String parameter directly (no .text)
    if (approvedAmount.trim().isEmpty) {
      ApprovedAmountError = "Enter Amount";
      isValid = false;
      print("❌ Approved amount is empty");
    }

    // Fix 2: Use the String parameter directly (no .text)
    // if (approveRemarks.trim().isEmpty) {
    //   remarksError = "Please Enter Remarks";
    //   isValid = false;
    //   print("❌ Remarks are empty");
    // }

    // Fix 3: Parse the String parameters, not .text
    if (approvedAmount.trim().isNotEmpty && requestedAmount.text.trim().isNotEmpty) {
      try {
        final numberFormat = NumberFormat.decimalPattern();
        double approved = numberFormat.parse(approvedAmount.trim()).toDouble();
        double requested = numberFormat.parse(requestedAmount.text.trim()).toDouble();

        print(" Amount Comparison: Approved: $approved, Requested: $requested");

        if (approved > requested) {
          ApprovedAmountError = "Approved Amount should not be greater than requested amount";
          isValid = false;
          print(" Approved amount exceeds requested amount");
        }
      } catch (e) {
        print(" Error parsing amounts: $e");
        ApprovedAmountError = "Invalid amount format";
        isValid = false;
      }
    }

    // Fix 4: Use the parameter OR check both for consistency
    // if (proposedPaymentAccountId.isEmpty && _selectedID.isEmpty) {
    //   selectpaymentAccountError = "Please select an account";
    //   isValid = false;
    //   // print(" No payment account selected");
    // } else if (proposedPaymentAccountId.isNotEmpty && _selectedID.isEmpty) {
    //   // If parameter has value but _selectedID doesn't, sync them
    //   _selectedID = proposedPaymentAccountId;
    //   // print(" Synced selected ID from parameter: $_selectedID");
    // }

    _submitClicked = false;
    notifyListeners();

    // print(" === VALIDATION RESULT: $isValid ===");
    return isValid;
  }

  checkApprovalDropDown() {}

  Future<void> paymentrequisitionProcessSubmitAPIFunction(
    context,
    mode,
    referenceNum,
    paymentAmount,
    paymentRequestId,
    paymentAccountId,
    processingRemarks,
    attachment,
  ) async {
    try {
      var provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.processApproveRejectPaymentRequestSubmitAPI(
        provider.empId,
        provider.session,
        mode,
        referenceNum,
        paymentAmount,
        paymentRequestId,
        paymentAccountId,
        processingRemarks,
        attachment,
      );
      if (data != null) {
        if (data.error == "0") {
          paymentRequesitionDetails(context, paymentRequestId);
          resetAll();
          toast(context, data.message);
          Navigator.pop(context);
        }
      }
    } catch (e) {}
  }

  resetAll() {
    checkDropDownReset();
    editPaymentRequestedAmountController.clear();
    editPaymentRequestedEditableAmountController.clear();
    _editPaymentProcessLoading = false;
    editableAmountError = null;
    requestedAmount.clear();
    proposedPaymentAccount.clear();
    approvedAmountReadonly.clear();
    approvedAmount.clear();
    accountName.clear();
    branch.clear();
    requestingPurpose.clear();
    description.clear();
    amount.clear();
    paymentMode.clear();
    bankUpiID.clear();
    bankName.clear();
    bankBranchName.clear();
    bankAccountNumber.clear();
    bankIfscCode.clear();
    bankHolderName.clear();
    paymentAccountSearchController.clear();
    _selectedPaymentAccounts = null;
    _selectedValue = "";
    _selectedID = null;
    proposedAmountError = null;
    remarksError = null;
    ApprovedAmountError = null;
    selectpaymentAccountError = null;

    notifyListeners();
  }

  resetRequired() {
    remarksError = null;
    selectpaymentAccountError = null;
    notifyListeners();
  }

  onChangeApprov(value) {
    final numberFormat = NumberFormat.decimalPattern();
    if (numberFormat.parse(approvedAmount.text) >
        numberFormat.parse(requestedAmount.text)) {
      ApprovedAmountError =
          "Approved Amount should not be greater than requested amount";
    } else {
      ApprovedAmountError = null;
    }
    notifyListeners();
  }

  void checkDropDownReset() {
    if (!_paymentAccounts.contains(_selectedPaymentAccounts) &&
        _selectedPaymentAccounts != null) {
      _selectedPaymentAccounts = null;
      _selectedID = null;
      _selectedValue = "";
    }
    notifyListeners();
  }
}
