import 'dart:io';

import 'package:camera/camera.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:generp/Models/financeModels/addDirectPaymentResponse.dart';
import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/Utils/commonServices.dart';
import 'package:generp/services/api_calling.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';

import '../../Models/financeModels/addPaymentRequestionResponse.dart';
import '../../Models/financeModels/paymentRequesitionListsResponse.dart';
import 'package:csv/csv.dart';
import 'package:excel/excel.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';

import '../../Models/financeModels/paymentRequestionBankDetailsResponse.dart';
import '../../Utils/app_colors.dart';

class Requestionlistprovider extends ChangeNotifier {
  TextEditingController reqPurposeController = TextEditingController();
  TextEditingController descController = TextEditingController();
  TextEditingController amountController = TextEditingController();
  TextEditingController bankNameController = TextEditingController();
  TextEditingController bankBranchController = TextEditingController();
  TextEditingController bankAccNumberController = TextEditingController();
  TextEditingController bankIfscController = TextEditingController();
  TextEditingController bankAcHolderController = TextEditingController();
  TextEditingController bankUpiController = TextEditingController();
  TextEditingController paymentReferenceController = TextEditingController();
  TextEditingController dateController = TextEditingController();
  TextEditingController accountSearchController = TextEditingController();
  TextEditingController paymentAccountSearchController =
      TextEditingController();

  // Date picker state
  DateTime? _date;
  String? _formattedDate;
  List<Accounts> _accounts = [];
  List<PaymentModes> _paymentModes = [];
  List<Employees> _approvalEmployee = [];
  List<String> _requestingPurposes = [];
  List<RequistionList> _requisitionList = [];

  List<DirectAccounts> _directAccounts = [];

  List<DirectPaymentAccounts> _directPaymentAccounts = [];

  List<DirectPaymentModes> _directPaymentModes = [];

  Employees? _selectedApprovalEmployee;
  String? _selectedApprovalEmployeeID;
  String? _selectedApprovalEmployeeValue;

  DirectAccounts? _selectedDirectAccounts;

  DirectPaymentAccounts? _selectDirectPaymentAccounts;

  DirectPaymentModes? _selectDirectPaymentModes;

  GetDetails _getBankDetails = GetDetails();

  String _directAccountID = "";
  String _directAccountValue = "";
  String _directPaymentAccountsID = "";
  String _directPaymentAccountsValue = "";
  String _directPaymentModesID = "";
  String _directPaymentModesValues = "";

  List<Employees> get approvalEmployee => _approvalEmployee;

  Employees? get selectedApprovalEmployee => _selectedApprovalEmployee;

  String? get selectedApprovalEmployeeID => _selectedApprovalEmployeeID;

  String? get selectedApprovalEmployeeValue => _selectedApprovalEmployeeValue;

  List<DirectAccounts> get directAccounts => _directAccounts;

  List<DirectPaymentAccounts> get directPaymentAccounts =>
      _directPaymentAccounts;

  GetDetails get getBankDetails => _getBankDetails;

  List<DirectPaymentModes> get directPaymentModes => _directPaymentModes;

  DirectAccounts? get selectDirectAccounts => _selectedDirectAccounts;

  DirectPaymentAccounts? get selectDirectPaymentAccounts =>
      _selectDirectPaymentAccounts;

  DirectPaymentModes? get selectDirectPaymentModes => _selectDirectPaymentModes;

  String get directAccountId => _directAccountID;

  String get directAccountValue => _directAccountValue;

  String get directPaymentAccountsID => _directPaymentAccountsID;

  String get directPaymentAccountsValue => _directPaymentAccountsValue;

  String get directPaymentModesID => _directPaymentModesID;

  String get directPaymentModesValues => _directPaymentModesValues;

  // Date picker methods
  String? get formattedDate => _formattedDate;

  set selectedApprovalEmployee(Employees? value) {
    _selectedApprovalEmployee = value;
    _selectedApprovalEmployeeID = value!.id!;
    _selectedApprovalEmployeeValue = value.name!;
    notifyListeners();
  }

  set selectedApprovalEmployeeValue(String? value) {
    _selectedApprovalEmployeeValue = value;
    notifyListeners();
  }

  set selectedApprovalEmployeeID(String? value) {
    _selectedApprovalEmployeeID = value;
    notifyListeners();
  }

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

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

  set selectDirectAccounts(DirectAccounts? value) {
    _selectedDirectAccounts = value;
    _directAccountID = value!.id!;
    _directAccountValue = value.name!;
    selectDirectAccountError = null;
    notifyListeners();
  }

  set selectDirectPaymentAccounts(DirectPaymentAccounts? value) {
    _selectDirectPaymentAccounts = value;
    _directPaymentAccountsID = value!.id!;
    _directPaymentAccountsValue = value.name!;
    selectDirectPaymentAccountError = null;
    notifyListeners();
  }

  set selectDirectPaymentModes(DirectPaymentModes? value) {
    _selectDirectPaymentModes = value;
    _directPaymentModesID = value!.id!;
    _directPaymentModesValues = value.name!;
    selectDirectPaymentError = null;
    notifyListeners();
  }

  set directAccountId(String value) {
    _directAccountID = value;
    notifyListeners();
  }

  set directAccountValue(String value) {
    _directAccountValue = value;
    notifyListeners();
  }

  set directPaymentAccountsID(String value) {
    _directPaymentAccountsID = value;
    notifyListeners();
  }

  set directPaymentAccountsValue(String value) {
    _directPaymentAccountsValue = value;
    notifyListeners();
  }

  set directPaymentModesID(String value) {
    _directPaymentModesID = value;
    notifyListeners();
  }

  set directPaymentModesValues(String value) {
    _directPaymentModesValues = value;
    notifyListeners();
  }

  Accounts? _selectedAccounts;
  PaymentModes? _selectedPayment;
  String? _selectReqPurpose;

  String _paymentModeId = "";
  String _paymentModeValue = "";
  String _accountId = "";
  String _accountValue = "";
  String _reqPurpose = "";

  String? selectAccountError;
  String? selectDirectAccountError;
  String? dateError;
  String? selectDirectPaymentAccountError;
  String? selectDirectPaymentError;
  String? paymentreferenceerror;
  String? reqPurposeError;
  String? descriptionError;
  String? amountError;
  String? selectPaymentError;
  String? bankNameError;
  String? bankBranchError;
  String? bankNumberError;
  String? bankIFSCError;
  String? bankHolderError;
  String? UPIError;
  String? FileError;

  bool buttonEnabled = false;
  bool _isLoading = true;

  bool _submitClicked = false;

  var _image_picked = 0;
  final ImagePicker _picker = ImagePicker();

  File? _image;
  File? _imageName;

  bool get isLoading => _isLoading;

  String get paymentModeId => _paymentModeId;

  String get paymentModeValue => _paymentModeValue;

  get image_picked => _image_picked;

  File? get imagePath => _imageName;

  File? get imageFilePath => _image;

  get imagePicked => _image_picked;

  String get accountId => _accountId;

  String get accountValue => _accountValue;

  String get reqPurpose => _reqPurpose;

  String? get selectReqPurpose => _selectReqPurpose;

  Accounts? get selectedAccount => _selectedAccounts;

  PaymentModes? get selectedPayment => _selectedPayment;

  List<Accounts> get accounts => _accounts;

  List<PaymentModes> get paymentModes => _paymentModes;

  List<String> get requestingPurposes => _requestingPurposes;

  List<RequistionList> get requisitionList => _requisitionList;

  bool get submitClicked => _submitClicked;

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

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

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

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

  set selectedAccount(Accounts? value) {
    _selectedAccounts = value;
    _accountId = value!.id!;
    _accountValue = value.name!;
    selectAccountError = null;

    notifyListeners();
  }

  set selectedPayment(PaymentModes? value) {
    _selectedPayment = value;
    _paymentModeId = value!.id!;
    _paymentModeValue = value.name!;
    selectPaymentError = null;

    notifyListeners();
  }

  set selectReqPurpose(String? value) {
    _selectReqPurpose = value;
    reqPurposeError = null;

    notifyListeners();
  }

  set paymentModeId(String value) {
    _paymentModeId = value;
    notifyListeners();
  }

  set paymentModeValue(String value) {
    _paymentModeValue = value;
    notifyListeners();
  }

  set accountId(String value) {
    _accountId = value;
    notifyListeners();
  }

  set accountValue(String value) {
    _accountValue = value;
    notifyListeners();
  }

  set reqPurposeId(String value) {
    _reqPurpose = 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> addPaymentRequestionViewAPI(context, mode) async {
    try {
      var homeProvider = Provider.of<HomescreenNotifier>(
        context,
        listen: false,
      );
      final data = await ApiCalling.addPaymentRequestionViewAPI(
        homeProvider.empId,
        homeProvider.session,
        mode,
      );
      _accounts.clear();
      _paymentModes.clear();
      _requestingPurposes.clear();
      _approvalEmployee.clear();
      notifyListeners();
      if (data != null) {
        if (data.error == "0") {
          checkDropdownselected();
          _accounts = data.accounts ?? [];
          if (mode != "self") {
            _accounts = [
              Accounts(id: "", name: "Select Account"),
              ...data.accounts ?? [],
            ];
          }
          print("1234234");
          if (mode == "self" && data.accounts!.length == 1) {
            paymentRequestionBankDetailsAPIFunction(
              context,
              data.accounts!.first.id,
            );
          }
          _approvalEmployee = data.employees ?? [];
          _approvalEmployee = [
            Employees(id: "", name: "Select"),
            ...data.employees ?? [],
          ];
          _paymentModes = data.paymentModes ?? [];
          _paymentModes = [
            PaymentModes(name: "Select", id: ""),
            ...data.paymentModes ?? [],
          ];
          _requestingPurposes = data.requestingPurposes ?? [];
          _requestingPurposes = ["Select", ...data.requestingPurposes ?? []];
          notifyListeners();
        } else {}
      }
    } catch (e) {}
  }

  Future<void> paymentRequestionBankDetailsAPIFunction(
    context,
    accountId,
  ) async {
    try {
      var homeProvider = Provider.of<HomescreenNotifier>(
        context,
        listen: false,
      );
      final data = await ApiCalling.paymentRequestionBankDetailsAPI(
        homeProvider.empId,
        homeProvider.session,
        accountId,
      );

      notifyListeners();
      if (data != null) {
        if (data.error == "0") {
          _getBankDetails = data.getDetails!;

          bankNameController.text = data.getDetails!.bankName ?? "-";
          bankBranchController.text = data.getDetails!.bankBranchName ?? "-";
          bankIfscController.text = data.getDetails!.bankIfscCode ?? "-";
          bankAcHolderController.text =
              data.getDetails!.bankAccountHolderName ?? "-";
          bankAccNumberController.text =
              data.getDetails!.bankAccountNumber ?? "-";
          bankUpiController.text = data.getDetails!.bankUpiId ?? "-";
          notifyListeners();
        } else {}
      }
    } catch (e) {}
  }

  Future<void> addPaymentRequestionSubmitAPI(
    context,
    mode,
    approvalEmployeeID,
  ) async {
    try {
      if (!validateForm(context, mode)) {
        return;
      }
      _submitClicked = true;
      notifyListeners();

      var homeProvider = Provider.of<HomescreenNotifier>(
        context,
        listen: false,
      );
      final data = await ApiCalling.addPaymentRequestionSubmitAPI(
        homeProvider.empId,
        homeProvider.session,
        mode,
        _accountId,
        ["self", "admin"].contains(mode)
            ? _selectReqPurpose
            : reqPurposeController.text,
        descController.text,
        amountController.text,
        _paymentModeId,
        bankNameController.text,
        bankBranchController.text,
        bankAccNumberController.text,
        bankIfscController.text,
        bankAcHolderController.text,
        bankUpiController.text,
        approvalEmployeeID,
        _image,
      );
      if (data != null) {
        if (data.error == "0") {
          print(data.error == "0");
          _submitClicked = false;
          notifyListeners();
          toast(context, "Added Successfully");
          resetForm();
          Navigator.pop(context, true);
          notifyListeners();
        } else {
          _submitClicked = false;
          notifyListeners();
        }
      } else {
        _submitClicked = false;
        notifyListeners();
      }
    } catch (e) {
      _submitClicked = false;
      notifyListeners();
    }
  }

  Future<void> addDirectPaymentRequestionViewAPI(context) async {
    try {
      var homeProvider = Provider.of<HomescreenNotifier>(
        context,
        listen: false,
      );
      final data = await ApiCalling.addDirectPaymentRequestionViewAPI(
        homeProvider.empId,
        homeProvider.session,
      );
      if (data != null) {
        if (data.error == "0") {
          _directPaymentAccounts = data.paymentAccounts!;
          _directPaymentAccounts = [
            DirectPaymentAccounts(id: "", name: "Select"),
            ...data.paymentAccounts!,
          ];
          _directPaymentModes = data.paymentModes!;
          _directPaymentModes = [
            DirectPaymentModes(name: "Select", id: ""),
            ...data.paymentModes!,
          ];
          _directAccounts = data.accounts!;
          _directAccounts = [
            DirectAccounts(id: "", name: "Select"),
            ...data.accounts!,
          ];
          checkdirectPaymentDropDownsSlected();

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

  Future<void> addDirectPaymentRequestionSubmitAPI(context, paymentDate) async {
    try {
      if (!validateDirectForm(context)) {
        return;
      }
      _submitClicked = true;
      notifyListeners();
      var homeProvider = Provider.of<HomescreenNotifier>(
        context,
        listen: false,
      );
      final data = await ApiCalling.addDirectPaymentRequestionSubmitAPI(
        homeProvider.empId,
        homeProvider.session,
        _directAccountID,
        _directPaymentAccountsID,
        descController.text,
        _directPaymentModesID,
        amountController.text,
        paymentDate,
        paymentReferenceController.text,
        bankNameController.text,
        bankBranchController.text,
        bankAccNumberController.text,
        bankIfscController.text,
        bankAcHolderController.text,
        bankUpiController.text,
        _image,
      );
      if (data != null) {
        if (data.error == "0") {
          _submitClicked = false;
          toast(context, "Added Successfully");
          resetForm();
          Navigator.pop(context, true);
          notifyListeners();
        } else {
          _submitClicked = false;
          notifyListeners();
        }
      } else {
        _submitClicked = false;
        notifyListeners();
      }
    } catch (e) {
      _submitClicked = false;
      notifyListeners();
    }
  }

  int _pageNum = 1;
  bool _hasMoreData = true;
  bool _isLoadingMore = false;

  bool get isLoadingMore => _isLoadingMore;
  bool get hasMoreData => _hasMoreData;

  int _currentPage = 1;
  int get currentPage => _currentPage;

  /// Reset before a fresh load (pull-to-refresh or filter change)
  void resetPagination() {
    _currentPage = 1;
    _hasMoreData = true;
    _requisitionList.clear();
    notifyListeners();
  }

  Future<void> paymentRequestionListsAPIFunction(
    BuildContext context,
    String mode,
    String from,
    String to, {
    bool append = false,
  }) async {
    try {
      var homeProvider = Provider.of<HomescreenNotifier>(
        context,
        listen: false,
      );

      if (!append) {
        // reset for first page
        _pageNum = 1;
        _hasMoreData = true;
        _requisitionList.clear();
        _isLoading = true;
      } else {
        _isLoadingMore = true;
      }
      notifyListeners();

      final data = await ApiCalling.paymentRequestionListsAPI(
        homeProvider.empId,
        homeProvider.session,
        mode,
        from,
        to,
        _pageNum.toString(),
      );
      debugPrint(
        'empId: ${homeProvider.empId}, session: ${homeProvider.session}, pageNumber: $_pageNum',
      );

      if (data != null && data.error == "0") {
        if (append) {
          final existingIds = _requisitionList.map((e) => e.id).toSet();
          final newItems =
              data.requistionList!
                  .where((item) => !existingIds.contains(item.id))
                  .toList();
          _requisitionList.addAll(newItems);
        } else {
          _requisitionList = data.requistionList ?? [];
        }

        // check if more data
        if (data.requistionList == null || data.requistionList!.length < 10) {
          _hasMoreData = false;
        } else {
          _pageNum++;
        }
      } else {
        _hasMoreData = false;
      }
    } catch (e) {
      _hasMoreData = false;
    } finally {
      _isLoading = false;
      _isLoadingMore = false;
      notifyListeners();
    }
  }

  void showDatePickerDialog(BuildContext context) {
    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);
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
    );
  }

  List<List<String>> prepareExportData() {
    final headers = [
      'ID',
      'Account Name',
      'Branch',
      'Purpose',
      'Description',
      'Amount',
      'Mode',
      'Status',
      'Date',
    ];

    final rows =
        requisitionList
            .map(
              (item) => [
                item.id ?? '',
                item.accountName ?? '',
                item.branch ?? '',
                item.requestingPurpose ?? '',
                item.description ?? '',
                item.amount ?? '',
                item.requestMode ?? '',
                item.status ?? '',
                item.date ?? '',
              ],
            )
            .toList();

    return [headers, ...rows];
  }

  void copyToClipboard(BuildContext context) async {
    try {
      if (requisitionList.isEmpty) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text("No data to copy")));
        return;
      }
      final data = prepareExportData();
      String raw = data.map((row) => row.join('\t')).join('\n');
      print('Clipboard data: $raw');
      await Clipboard.setData(ClipboardData(text: raw));
      toast(context, "Copied to Clipboard");
    } catch (e) {
      print('Error copying to clipboard: $e');
    }
  }

  Future<String> getSaveDirectory() async {
    // Try Downloads directory first
    try {
      if (Platform.isAndroid) {
        // Request storage permission for Android
        if (await Permission.storage.request().isGranted ||
            await Permission.manageExternalStorage.request().isGranted) {
          final dir = await getApplicationDocumentsDirectory();
          print('Using Downloads directory: ${dir.path}');
          return dir.path;
        }
      }
    } catch (e) {
      print('Error accessing Downloads directory: $e');
    }

    // Fallback to shared Documents directory
    try {
      final dir = await getDownloadsDirectory();
      if (dir != null) {
        final customDir = Directory('${dir.path}/RequisitionData');
        if (!await customDir.exists()) {
          await customDir.create(recursive: true);
        }
        print('Using custom Documents directory: ${customDir.path}');
        return customDir.path;
      }
    } catch (e) {
      print('Error accessing Documents directory: $e');
    }

    // Final fallback to app's Documents directory
    final dir = await getApplicationDocumentsDirectory();
    print('Using app Documents directory: ${dir.path}');
    return dir.path;
  }

  Future<void> downloadCSV(BuildContext context) async {
    try {
      if (requisitionList.isEmpty) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text("No data to export")));
        return;
      }
      final data = prepareExportData();
      final csvData = const ListToCsvConverter().convert(data);
      final dirPath = await getSaveDirectory();
      final file = File('$dirPath/requisition_data.csv');
      await file.writeAsString(csvData);
      print('CSV saved at: ${file.path}');
      bool exists = await file.exists();
      print('File exists: $exists');
      // await OpenFile.open(file.path); // Open the file
      // await Share.share(file.path); // Share the file
      toast(context, "CSV Downloaded");
    } catch (e) {
      print('Error downloading CSV: $e');
    }
  }

  Future<void> downloadXLS(BuildContext context) async {
    try {
      if (requisitionList.isEmpty) {
        toast(context, "No Data to export");
        return;
      }
      final data = prepareExportData();
      var excel = Excel.createExcel();
      Sheet sheet = excel['Sheet1'];
      for (var row in data) {
        sheet.appendRow(row.map((cell) => TextCellValue(cell)).toList());
      }
      final dirPath = await getSaveDirectory();
      final file = File('$dirPath/requisition_data.xlsx');
      final bytes = excel.encode();
      if (bytes == null) throw Exception("Excel encoding failed");
      await file.writeAsBytes(bytes);
      print('XLSX saved at: ${file.path}');
      bool exists = await file.exists();
      print('File exists: $exists');
      // await OpenFile.open(file.path); // Open the file
      // await Share.share([file.path], text: 'Requisition Data XLSX'); // Share the file
      toast(context, ("XLSX Downloaded and opened"));
    } catch (e) {
      print('Error downloading XLSX: $e');
    }
  }

  Future<void> downloadPDF(BuildContext context) async {
    try {
      if (requisitionList.isEmpty) {
        toast(context, "No Data to export");
        return;
      }
      final data = prepareExportData();
      final pdf = pw.Document();
      pdf.addPage(
        pw.Page(build: (context) => pw.Table.fromTextArray(data: data)),
      );
      final dirPath = await getSaveDirectory();
      final file = File('$dirPath/requisition_data.pdf');
      await file.writeAsBytes(await pdf.save());
      print('PDF saved at: ${file.path}');
      bool exists = await file.exists();
      print('File exists: $exists');
      // await OpenFile.open(file.path); // Open the file
      // await Share.shareXFiles([file.path], text: 'Requisition Data PDF'); // Share the file
      toast(context, "PDF Downloaded ");
    } catch (e) {
      print('Error downloading PDF: $e');
    }
  }

  Future<void> printData(BuildContext context) async {
    try {
      if (requisitionList.isEmpty) {
        toast(context, "No Data to Print");
        return;
      }
      final data = prepareExportData();
      final pdf = pw.Document();
      pdf.addPage(
        pw.Page(build: (context) => pw.Table.fromTextArray(data: data)),
      );
      await Printing.layoutPdf(
        onLayout: (PdfPageFormat format) async => pdf.save(),
      );
    } catch (e) {
      print('Error printing data: $e');
    }
  }

  // void copyToClipboard(context) {
  //   final data = prepareExportData();
  //   String raw = data.map((row) => row.join('\t')).join('\n');
  //   Clipboard.setData(ClipboardData(text: raw));
  //   ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Copied to clipboard")));
  // }
  //
  // Future<void> downloadCSV(context) async {
  //   final data = prepareExportData();
  //   final csvData = const ListToCsvConverter().convert(data);
  //   final dir = await getApplicationDocumentsDirectory();
  //   final file = File('${dir.path}/requisition_data.csv');
  //   await file.writeAsString(csvData);
  //   ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("CSV Downloaded")));
  // }
  //
  // Future<void> downloadXLS(context) async {
  //   final data = prepareExportData();
  //   var excel = Excel.createExcel();
  //   Sheet sheet = excel['Sheet1'];
  //
  //   for (var row in data) {
  //     sheet.appendRow(row.map((cell) => TextCellValue(cell)).toList());
  //   }
  //   final dir = await getApplicationDocumentsDirectory();
  //   final file = File('${dir.path}/requisition_data.xlsx');
  //   await file.writeAsBytes(excel.encode()!);
  //   ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("XLSX Downloaded")));
  // }
  //
  // Future<void> downloadPDF(context) async {
  //   final data = prepareExportData();
  //   final pdf = pw.Document();
  //   pdf.addPage(
  //     pw.Page(
  //       build: (context) => pw.Table.fromTextArray(data: data),
  //     ),
  //   );
  //   final dir = await getApplicationDocumentsDirectory();
  //   final file = File('${dir.path}/requisition_data.pdf');
  //   await file.writeAsBytes(await pdf.save());
  //   ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("PDF Downloaded")));
  // }
  //
  // Future<void> printData(context) async {
  //   final data = prepareExportData();
  //   final pdf = pw.Document();
  //   pdf.addPage(
  //     pw.Page(
  //       build: (context) => pw.Table.fromTextArray(data: data),
  //     ),
  //   );
  //   await Printing.layoutPdf(
  //     onLayout: (PdfPageFormat format) async => pdf.save(),
  //   );
  // }

  void resetForm() {
    print("ios calling");
    _submitClicked = false;
    accountSearchController.clear();
    paymentAccountSearchController.clear();
    reqPurposeController.clear();
    descController.clear();
    amountController.clear();
    bankNameController.clear();
    bankBranchController.clear();
    bankAccNumberController.clear();
    bankIfscController.clear();
    bankAcHolderController.clear();
    bankUpiController.clear();
    paymentReferenceController.clear();
    dateController.clear();
    _formattedDate = "";
    _selectedAccounts = null;
    _selectedPayment = null;
    _selectReqPurpose = null;

    _paymentModeId = "";
    _paymentModeValue = "";
    _accountId = "";
    _accountValue = "";
    _reqPurpose = "";

    _image = null;
    _imageName = null;
    _image_picked = 0;

    _submitClicked = false;

    // Clear validation errors
    selectAccountError = null;
    selectDirectAccountError = null;
    selectDirectAccountError = null;
    dateError = null;
    paymentreferenceerror = null;
    reqPurposeError = null;
    descriptionError = null;
    amountError = null;
    selectPaymentError = null;
    bankNameError = null;
    bankBranchError = null;
    bankNumberError = null;
    bankIFSCError = null;
    bankHolderError = null;
    UPIError = null;
    FileError = null;
    buttonEnabled = false;
    checkDropdownselected();
    checkdirectPaymentDropDownsSlected();
    notifyListeners();
  }

  void checkdirectPaymentDropDownsSlected() {
    if (_selectedDirectAccounts != null &&
        !_directAccounts.contains(_selectedDirectAccounts)) {
      _selectedDirectAccounts = null;
      _directAccountID = "";
      _directAccountValue = "";
    }

    if (_selectDirectPaymentModes != null &&
        !_directPaymentModes.contains(_selectDirectPaymentModes)) {
      _selectDirectPaymentModes = null;
      _directPaymentModesID = "";
      _directPaymentModesValues = "";
    }
    if (_selectDirectPaymentAccounts != null &&
        !_directPaymentAccounts.contains(_selectDirectPaymentAccounts)) {
      _selectDirectPaymentAccounts = null;
      _directPaymentAccountsID = "";
      _directPaymentAccountsValue = "";
    }
  }

  void checkDropdownselected() {
    if (_selectedAccounts != null && !_accounts.contains(_selectedAccounts)) {
      _selectedAccounts = null;
      _accountId = "";
      _accountValue = "";
    }
    if (_selectedPayment != null && !_paymentModes.contains(_selectedPayment)) {
      _selectedPayment = null;
      _paymentModeId = "";
    }

    if (_selectReqPurpose != null &&
        !_requestingPurposes.contains(_selectReqPurpose)) {
      _selectReqPurpose = null;
    }

    if (_selectedApprovalEmployee != null &&
        !_approvalEmployee.contains(_selectedApprovalEmployee)) {
      _selectedApprovalEmployee = null;
      _selectedApprovalEmployeeID = null;
      _selectedApprovalEmployeeValue = null;
    }
    notifyListeners();
  }

  bool validateForm(BuildContext context, String mode) {
    // Reset all errors
    selectAccountError = null;
    reqPurposeError = null;
    descriptionError = null;
    amountError = null;
    selectPaymentError = null;
    bankNameError = null;
    bankBranchError = null;
    bankNumberError = null;
    bankIFSCError = null;
    bankHolderError = null;
    UPIError = null;
    FileError = null;

    bool isValid = true;

    if (_selectedAccounts == null || _accountId.isEmpty) {
      selectAccountError = "Please select an account";
      isValid = false;
      _submitClicked = false;
    }

    if (["self", "admin"].contains(mode)) {
      if (_selectReqPurpose == null || _selectReqPurpose!.isEmpty) {
        reqPurposeError = "Please select a requisition purpose";
        isValid = false;
        _submitClicked = false;
      }
    } else {
      if (reqPurposeController.text.trim().isEmpty) {
        reqPurposeError = "Please enter a requisition purpose";
        isValid = false;
        _submitClicked = false;
      }
    }

    if (descController.text.trim().isEmpty) {
      descriptionError = "Please enter a description";
      isValid = false;
      _submitClicked = false;
    }

    if (amountController.text.trim().isEmpty) {
      amountError = "Please enter an amount";
      isValid = false;
      _submitClicked = false;
    }

    if (_selectedPayment == null || _paymentModeId.isEmpty) {
      selectPaymentError = "Please select a payment mode";
      isValid = false;
      _submitClicked = false;
    }

    if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) {
      if (bankNameController.text.trim().isEmpty) {
        bankNameError = "Please enter bank name";
        isValid = false;
        _submitClicked = false;
      }

      if (bankBranchController.text.trim().isEmpty) {
        bankBranchError = "Please enter bank branch";
        isValid = false;
        _submitClicked = false;
      }
      if (bankAccNumberController.text.trim().isEmpty) {
        bankNumberError = "Please enter account number";
        isValid = false;
        _submitClicked = false;
      }
      if (bankIfscController.text.trim().isEmpty) {
        bankIFSCError = "Please enter IFSC code";
        isValid = false;
        _submitClicked = false;
      }
      if (bankAcHolderController.text.trim().isEmpty) {
        bankHolderError = "Please enter account holder name";
        isValid = false;
        _submitClicked = false;
      }
    }

    if (_paymentModeValue == "UPI") {
      if (bankUpiController.text.trim().isEmpty) {
        UPIError = "Please enter UPI ID";
        isValid = false;
        _submitClicked = false;
      }
      if (!RegExp(
        r"^[a-zA-Z0-9.-]{2,256}@[a-zA-Z][a-zA-Z]{2,64}$",
      ).hasMatch(bankUpiController.text)) {
        UPIError = "Please enter UPI ID correctly.";
        isValid = false;
        _submitClicked = false;
      }
    }

    // if (_image_picked == 0) {
    //   FileError = "Please attach a file";
    //   isValid = false;_submitClicked = false;
    // }
    buttonEnabled = isValid;
    _submitClicked = false;
    notifyListeners();
    return isValid;
  }

  bool validateDirectForm(BuildContext context) {
    selectAccountError = null;
    selectDirectAccountError = null;
    selectDirectPaymentAccountError = null;
    reqPurposeError = null;
    descriptionError = null;
    amountError = null;
    selectPaymentError = null;
    bankNameError = null;
    bankBranchError = null;
    bankNumberError = null;
    bankIFSCError = null;
    bankHolderError = null;
    paymentreferenceerror = null;
    selectDirectPaymentError = null;
    UPIError = null;
    bool isValid = true;
    if (_selectedDirectAccounts == null || _directAccountID.isEmpty) {
      selectDirectAccountError = "Please select an Account";
      isValid = false;
    }

    if (_selectDirectPaymentAccounts == null ||
        _directPaymentAccountsID.isEmpty) {
      selectDirectPaymentAccountError = "Please select an Account";
      isValid = false;
    }

    if (amountController.text.trim().isEmpty) {
      amountError = "Please enter an amount";
      isValid = false;
    }
    if (dateController.text.trim().isEmpty || _formattedDate!.isEmpty) {
      dateError = "Please select Date";
      isValid = false;
    }
    if (_selectDirectPaymentModes == null || _directPaymentModesID.isEmpty) {
      selectDirectPaymentError = "Please select a payment mode";
      isValid = false;
    }
    if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) {
      if (bankNameController.text.trim().isEmpty) {
        bankNameError = "Please enter bank name";
        isValid = false;
      }
      if (bankBranchController.text.trim().isEmpty) {
        bankBranchError = "Please enter bank branch";
        isValid = false;
      }
      if (bankAccNumberController.text.trim().isEmpty) {
        bankNumberError = "Please enter account number";
        isValid = false;
      }
      if (bankIfscController.text.trim().isEmpty) {
        bankIFSCError = "Please enter IFSC code";
        isValid = false;
      }
      if (bankAcHolderController.text.trim().isEmpty) {
        bankHolderError = "Please enter account holder name";
        isValid = false;
      }
    }

    if (_paymentModeValue == "UPI") {
      if (bankAcHolderController.text.trim().isEmpty) {
        bankHolderError = "Please enter account holder name";
        isValid = false;
      }
      if (bankUpiController.text.trim().isEmpty) {
        UPIError = "Please enter UPI ID";
        isValid = false;
      }
    }
    if (paymentReferenceController.text.trim().isEmpty) {
      paymentreferenceerror = "please enter refernce number";
      isValid = false;
    }
    if (descController.text.trim().isEmpty) {
      descriptionError = "Please Enter Description";
      isValid = false;
    }
    // if (_image_picked == 0) {
    //   FileError = "Please attach a file";
    //   isValid = false;
    // }
    _submitClicked = false;
    notifyListeners();
    return isValid;
  }

  void updateReqPupose(String value) {
    reqPurposeError = null;
    notifyListeners();
  }

  void updateDescription(String value) {
    descriptionError = null;
    notifyListeners();
  }

  void updateReference(String value) {
    paymentreferenceerror = null;
    notifyListeners();
  }

  void updateAmount(String value) {
    amountError = null;
    notifyListeners();
  }

  void updateBankName(String value) {
    bankNameError = null;
    notifyListeners();
  }

  void updateBankBranch(String value) {
    bankBranchError = null;
    notifyListeners();
  }

  void updateNumber(String value) {
    bankNumberError = null;
    notifyListeners();
  }

  void updateIFSC(String value) {
    bankIFSCError = null;
    notifyListeners();
  }

  void updateHolder(String value) {
    bankHolderError = null;
    notifyListeners();
  }

  void updateUPI(String value) {
    UPIError = null;
    notifyListeners();
  }
}
