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

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:generp/Models/ordersModels/addOrderAccontDetailsResponse.dart';
import 'package:generp/Utils/commonServices.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geolocator/geolocator.dart' as geo_location;
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:location/location.dart' as Location;
import 'package:provider/provider.dart';

import '../../Models/commonModels/DistrictsResponse.dart';
import '../../Models/commonModels/SubLocationsResponse.dart';
import '../../Models/ordersModels/AddOrderPaymentSelectAccountResponse.dart';
import '../../Models/ordersModels/AddOrderViewResponse.dart';
import '../../Models/ordersModels/addOrderTpcAgentListResponse.dart';
import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart';

class Addorderprovider extends ChangeNotifier {TextEditingController dropDownSearchController = TextEditingController();
TextEditingController dropDownTpcSearchController = TextEditingController();

TextEditingController billingNameController = TextEditingController();
TextEditingController billingAddressController = TextEditingController();
TextEditingController billingPincodeController = TextEditingController();
TextEditingController dispatchAddressController = TextEditingController();
TextEditingController dispatchPincodeController = TextEditingController();
TextEditingController gstController = TextEditingController();
TextEditingController orderReceivedDateController = TextEditingController();
TextEditingController tpcAmountController = TextEditingController();

List<TextEditingController> ProductControllers = [];
List<TextEditingController> PriceControllers = [];
List<TextEditingController> QuantityControllers = [];
List<TextEditingController> CGSTControllers = [];
List<TextEditingController> SGSTControllers = [];
List<TextEditingController> IGSTControllers = [];
List<TextEditingController> TotalPriceControllers = [];
List<TextEditingController> TaxableValueControllers = [];

TextEditingController basicAmountReadOnlyController = TextEditingController();
TextEditingController cgstReadOnlyController = TextEditingController();
TextEditingController sgstReadOnlyController = TextEditingController();
TextEditingController igstReadOnlyController = TextEditingController();
TextEditingController totalReadOnlyAmountController = TextEditingController();
TextEditingController noteController = TextEditingController();
List<AccountList> _accountList = [];
List<Employees> _employees = [];
List<States> _billingStates = [];
List<States> _dispatchStates = [];
List<SaleProducts> _saleProducts = [];

List<Districts> _billingDistricts = [];
List<Districts> _dispatchDistricts = [];
List<SubLocations> _billingSubLocations = [];
List<SubLocations> _dispatchSubLocations = [];

List<String> _unloadingScope = [];
List<String> _freightScope = [];
List<String> _erectionScope = [];
List<String> _tpcApplicable = [];
List<TpcList> _tpcAgent = [];

AccountDetails _accountDetails = AccountDetails();

String selectAccountError = "";
String billingNameError = "";
String billingAddressError = "";
String billingPincodeError = "";
String dispatchAddressError = "";
String dispatchPincodeError = "";
String tpcAmountError = "";
String gstError = "";

AccountList? _selectedAccountList;
String? _selectedAccountID;
String? _selectedAccountName;

Employees? _selectedEmployees;
String? _selectedEmployeeID;
String? _selectedEmployeeName;

States? _selectedBillingStates;
String? _selectedBillingStateID;
String? _selectedBillingStateName;

Districts? _selectedBillingDistricts;
String? _selectedBillingDistrictID;
String? _selectedBillingDistrictValue;

SubLocations? _selectedBillingSubLocations;
String? _selectedBillingSubLocID;
String? _selectedBillingSubLocValue;

States? _selectedDispatchStates;
String? _selectedDispatchStateID;
String? _selectedDispatchStateName;

Districts? _selectedDispatchDistricts;
String? _selectedDispatchDistrictID;
String? _selectedDispatchDistrictValue;

SubLocations? _selectedDispatchSubLocations;
String? _selectedDispatchSubLocID;
String? _selectedDispatchSubLocValue;

SaleProducts? _selectedSaleProducts;

List<String?> _selectedSaleProductID = [];
String? _selectedSaleProductName;

String? _selectedUnloadingScope;
String? _selectedFreightScope;
String? _selectedErectionScope;
String? _selectedTpcStatus;
TpcList? _selectedTpcAgent;
String? _selectedTpcAgentID;
String? _selectedTpcAgentValue;




LatLng startLocation = const LatLng(17.439112226708446, 78.43292499146135);
LatLng? currentLocationLatLng;
String latlongs = "";
Set<Marker> markers = {};
Location.LocationData? currentLocation;
bool isLocationEnabled = false;
bool hasLocationPermission = false;

String? FileError;
String? dateError;
bool _isLoading = false;
int _imagePicked = 0;
File? _image;
File? _imageName;
final ImagePicker _picker = ImagePicker();
DateTime? _date;
String? _formattedDate;
Timer? _debounce;
List<Map<String, String>> _selectedOrders = [];

List<Map<String, String>> get selectedOrders => _selectedOrders;

bool _submitClicked = false;

bool get submitClicked => _submitClicked;

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

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

bool get isLoading => _isLoading;

String? get formattedDate => _formattedDate;

DateTime? get dateNow => _date;

File? get imagePath => _imageName;

File? get imageFilePath => _image;

int get imagePicked => _imagePicked;

List<AccountList> get accountList => _accountList;

List<Employees> get employees => _employees;

List<SaleProducts> get saleProducts => _saleProducts;

List<String> get unloadingScope => _unloadingScope;

List<String> get freightScope => _freightScope;

List<String> get erectionScope => _erectionScope;

List<String> get tpcApplicable => _tpcApplicable;

List<TpcList> get tpcAgent => _tpcAgent;

AccountList? get selectedAccountList => _selectedAccountList;

String? get selectedAccountID => _selectedAccountID;

String? get selectedAccountName => _selectedAccountName;

Employees? get selectedEmployees => _selectedEmployees;

String? get selectedEmployeeID => _selectedEmployeeID;

String? get selectedEmployeeName => _selectedEmployeeName;

List<States> get billingStates => _billingStates;

States? get selecetdBillingStates => _selectedBillingStates;

String? get selectedBillingStateID => _selectedBillingStateID;

String? get selectedBillingStateName => _selectedBillingStateName;

List<Districts> get billingDistricts => _billingDistricts;

List<SubLocations> get billingSubLocations => _billingSubLocations;

Districts? get selectedBillingDistricts => _selectedBillingDistricts;

String? get selectedBillingDistrictId => _selectedBillingDistrictID;

String? get selectedBillingDistrictValue => _selectedBillingDistrictValue;

SubLocations? get selectedBillingSubLocations => _selectedBillingSubLocations;

String? get selectedBillingSubLocID => _selectedBillingSubLocID;

String? get selectedBillingSubLocValue => _selectedBillingSubLocValue;

List<States> get dispatchStates => _dispatchStates;

States? get selecetdDispatchStates => _selectedDispatchStates;

String? get selectedDispatchStateID => _selectedDispatchStateID;

String? get selectedDispatchStateName => _selectedDispatchStateName;

List<Districts> get dispatchDistricts => _dispatchDistricts;

List<SubLocations> get dispatchSubLocations => _dispatchSubLocations;

Districts? get selectedDispatchDistricts => _selectedDispatchDistricts;

String? get selectedDispatchDistrictId => _selectedDispatchDistrictID;

String? get selectedDispatchDistrictValue => _selectedDispatchDistrictValue;

SubLocations? get selectedDispatchSubLocations =>
    _selectedDispatchSubLocations;

String? get selectedDispatchSubLocID => _selectedDispatchSubLocID;

String? get selectedDispatchSubLocValue => _selectedDispatchSubLocValue;

SaleProducts? get selectedSaleProducts => _selectedSaleProducts;

List<String?> get selectedSaleProductID => _selectedSaleProductID;

String? get selectedSaleProductName => _selectedSaleProductName;

String? get selectedUnloadingScope => _selectedUnloadingScope;

String? get selectedFreightScope => _selectedFreightScope;

String? get selectedErectionScope => _selectedErectionScope;

String? get selectedTpcStatus => _selectedTpcStatus;

TpcList? get selectedTpcAgent => _selectedTpcAgent;

String? get selectedTpcAgentID => _selectedTpcAgentID;

String? get selectedTpcAgentValue => _selectedTpcAgentValue;

AccountDetails get accountDetails => _accountDetails;

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

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

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

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

set selectedEmployees(Employees? value) {
  _selectedEmployees = value;
  _selectedEmployeeID = value!.id;
  _selectedEmployeeName = value!.name!;
  notifyListeners();
}

set selectedEmployeeID(String? value) {
  _selectedEmployeeID = value;
  notifyListeners();
}

set selectedEmployeeName(String? value) {
  _selectedEmployeeName = value;
  notifyListeners();
}

set selecetdBillingStates(States? value) {
  _selectedBillingStates = value;
  _selectedBillingStateID = value!.id;
  _selectedBillingStateName = value!.name!;
  notifyListeners();
}

set selectedBillingStateID(String? value) {
  _selectedBillingStateID = value;
  notifyListeners();
}

set selectedBillingStateName(String? value) {
  _selectedBillingStateName = value;
  notifyListeners();
}

set selectedBillingDistricts(Districts? value) {
  _selectedBillingDistricts = value;
  _selectedBillingDistrictID = value!.id;
  _selectedBillingDistrictValue = value!.district;
  // districtError = null;
  notifyListeners();
}

set selectedBillingSubLocations(SubLocations? value) {
  _selectedBillingSubLocations = value;
  _selectedBillingSubLocID = value!.id;
  _selectedBillingSubLocValue = value!.subLocality!;
  // localityError = null;
  notifyListeners();
}

set selectedBillingDistrictId(value) {
  _selectedBillingDistrictID = value;
  notifyListeners();
}

set selectedBillingDistrictValue(value) {
  _selectedBillingDistrictValue = value;
  notifyListeners();
}

set selectedBillingSubLocID(value) {
  _selectedBillingSubLocID = value;
  notifyListeners();
}

set selectedBillingSubLocValue(value) {
  _selectedBillingSubLocValue = value;
  notifyListeners();
}

set selecetdDispatchStates(States? value) {
  _selectedDispatchStates = value;
  _selectedDispatchStateID = value!.id;
  _selectedDispatchStateName = value!.name!;
  notifyListeners();
}

set selectedDispatchStateID(String? value) {
  _selectedDispatchStateID = value;
  notifyListeners();
}

set selectedDispatchStateName(String? value) {
  _selectedDispatchStateName = value;
  notifyListeners();
}

set selectedDispatchDistricts(Districts? value) {
  _selectedDispatchDistricts = value;
  _selectedDispatchDistrictID = value!.id;
  _selectedDispatchDistrictValue = value!.district;
  // districtError = null;
  notifyListeners();
}

set selectedDispatchSubLocations(SubLocations? value) {
  _selectedDispatchSubLocations = value;
  _selectedDispatchSubLocID = value!.id;
  _selectedDispatchSubLocValue = value!.subLocality!;
  // localityError = null;
  notifyListeners();
}

set selectedDispatchDistrictId(value) {
  _selectedDispatchDistrictID = value;
  notifyListeners();
}

set selectedDispatchDistrictValue(value) {
  _selectedDispatchDistrictValue = value;
  notifyListeners();
}

set selectedDispatchSubLocID(value) {
  _selectedDispatchSubLocID = value;
  notifyListeners();
}

set selectedDispatchSubLocValue(value) {
  _selectedDispatchSubLocValue = value;
  notifyListeners();
}

set selectedSaleProducts(SaleProducts? value) {
  _selectedSaleProducts = value;
  // _selectedSaleProductID = value!.id!;
  // _selectedSaleProductName = value!.prodName;
  notifyListeners();
}

set selectedSaleProductID(List<String?> value) {
  _selectedSaleProductID = value;
  notifyListeners();
}

set selectedSaleProductName(String? value) {
  _selectedSaleProductName = value;
  notifyListeners();
}

set selectedUnloadingScope(String? value) {
  _selectedUnloadingScope = value;
  notifyListeners();
}

set selectedFreightScope(String? value) {
  _selectedFreightScope = value;
  notifyListeners();
}

set selectedErectionScope(String? value) {
  _selectedErectionScope = value;
  notifyListeners();
}

set selectedTpcStatus(String? value) {
  _selectedTpcStatus = value;
  notifyListeners();
}

set selectedTpcAgent(TpcList? value) {
  _selectedTpcAgent = value;
  _selectedTpcAgentID = value!.id;
  _selectedTpcAgentValue = value!.text;
  notifyListeners();
}

set selectedTpcAgentID(String? value) {
  _selectedTpcAgentID = value;
  notifyListeners();
}

set selectedTpcAgentValue(String? value) {
  _selectedTpcAgentValue = value;
  notifyListeners();
}

set accountDetails(AccountDetails value) {
  _accountDetails = 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;
  orderReceivedDateController.text = _formattedDate!;
  dateError = null;
  notifyListeners();
}

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

dynamic get basicAmount {
  double total = 0;
  for (var controller in TaxableValueControllers) {
    total += double.tryParse(controller.text)?.round() ?? 0.0;
  }
  basicAmountReadOnlyController.text = total.toStringAsFixed(2);
  return total;
}

dynamic get cgstAmount {
  double total = 0;
  for (int i = 0; i < ProductControllers.length; i++) {
    final taxableValue =
        double.tryParse(TaxableValueControllers[i].text) ?? 0.0;
    final cgst = double.tryParse(CGSTControllers[i].text) ?? 0.0;
    total += (taxableValue * cgst) / 100;
  }
  cgstReadOnlyController.text = total.toStringAsFixed(2);
  return total;
}

dynamic get sgstAmount {
  double total = 0;
  for (int i = 0; i < ProductControllers.length; i++) {
    final taxableValue =
        double.tryParse(TaxableValueControllers[i].text) ?? 0.0;
    final sgst = double.tryParse(SGSTControllers[i].text) ?? 0.0;
    total += (taxableValue * sgst).round()  / 100;
  }
  sgstReadOnlyController.text = total.toStringAsFixed(2);
  return total;
}

dynamic get igstAmount {
  double total = 0;
  for (int i = 0; i < ProductControllers.length; i++) {
    final taxableValue =
        double.tryParse(TaxableValueControllers[i].text) ?? 0.0;
    final igst = double.tryParse(IGSTControllers[i].text) ?? 0.0;
    total += (taxableValue * igst).round()  / 100;
  }
  igstReadOnlyController.text = total.toStringAsFixed(2);
  return total;
}

dynamic get totalAmount {
  double total = basicAmount + cgstAmount + sgstAmount + igstAmount;
  totalReadOnlyAmountController.text = total.round().toStringAsFixed(2);
  return total! ;
}

void addNewRow() {
  ProductControllers.add(TextEditingController());
  PriceControllers.add(TextEditingController());
  QuantityControllers.add(TextEditingController(text: '1'));
  CGSTControllers.add(TextEditingController(text: '9'));
  SGSTControllers.add(TextEditingController(text: '9'));
  IGSTControllers.add(TextEditingController(text: '0'));
  TaxableValueControllers.add(TextEditingController());

  selectedSaleProductID.add(null);
  notifyListeners();
}

void removeRow(int index) {
  if (index >= 0 && index < ProductControllers.length) {
    ProductControllers[index].dispose();
    PriceControllers[index].dispose();
    QuantityControllers[index].dispose();
    CGSTControllers[index].dispose();
    SGSTControllers[index].dispose();
    IGSTControllers[index].dispose();
    TaxableValueControllers[index].dispose();
    ProductControllers.removeAt(index);
    PriceControllers.removeAt(index);
    QuantityControllers.removeAt(index);
    CGSTControllers.removeAt(index);
    SGSTControllers.removeAt(index);
    IGSTControllers.removeAt(index);
    TaxableValueControllers.removeAt(index);
    selectedSaleProductID.removeAt(index);
    notifyListeners();
  }
}

void updateSelectedProduct(int index, SaleProducts? product) {
  if (index >= 0 && index < _saleProducts.length) {
    _selectedSaleProducts = product;
    _selectedSaleProductID[index] = product!.id;
    PriceControllers[index].text = product!.price!;
    updateRowCalculations(index);
    notifyListeners();
  }
}

void updateRowCalculations(int index) {
  if (index >= 0 && index < PriceControllers.length) {
    final inclusivePrice =
        double.tryParse(PriceControllers[index].text) ?? 0.0;
    final quantity = double.tryParse(QuantityControllers[index].text) ?? 1.0;
    final cgst = double.tryParse(CGSTControllers[index].text) ?? 0.0;
    final sgst = double.tryParse(SGSTControllers[index].text) ?? 0.0;
    final igst = double.tryParse(IGSTControllers[index].text) ?? 0.0;
    final totalTaxRate = (cgst + sgst + igst) / 100;
    // Calculate taxable value per unit
    final taxableValuePerUnit = inclusivePrice / (1 + totalTaxRate);
    // Total taxable value = taxable value per unit * quantity
    final totalTaxableValue = taxableValuePerUnit * quantity;
    TaxableValueControllers[index].text = totalTaxableValue.toStringAsFixed(
      0,
    );
    notifyListeners();
  }
}


  Map<String, dynamic> getFormData() {
    final List<Map<String, dynamic>> orders = [];
    for (int i = 0; i < ProductControllers.length; i++) {
      orders.add({
        'product_id': selectedSaleProductID[i],
        'product_name': ProductControllers[i].text,
        'inclusive_price': PriceControllers[i].text,
        'quantity': QuantityControllers[i].text,
        'cgst': CGSTControllers[i].text,
        'sgst': SGSTControllers[i].text,
        'igst': IGSTControllers[i].text,
        'taxable_value': TaxableValueControllers[i].text,
      });
    }
    return {
      'orders': orders,
      'basic_amount': basicAmount.toStringAsFixed(2),
      'cgst_amount': cgstAmount.toStringAsFixed(2),
      'sgst_amount': sgstAmount.toStringAsFixed(2),
      'igst_amount': igstAmount.toStringAsFixed(2),
      'total_amount': totalAmount.toStringAsFixed(2),
      'note': noteController.text,
    };
  }

  //
  //
  // void updateSelectedOrderId(int index, SaleProducts? value) {
  //   if (index >= 0 && index < _selectedSaleProductID.length) {
  //     _selectedSaleProductID[index] = value!.id;
  //     ProductControllers[index].text = value!.prodName!;
  //     PriceControllers[index].text = value.price!;
  //     notifyListeners();
  //   } else {
  //     print("Invalid index: $index");
  //   }
  // }
  // void addNewRow() {
  //   // Create a unique TextEditingController for each field
  //   ProductControllers.add(TextEditingController());
  //   PriceControllers.add(TextEditingController());
  //   QuantityControllers.add(TextEditingController());
  //   CGSTControllers.add(TextEditingController(text: "9"));
  //   SGSTControllers.add(TextEditingController(text: "9"));
  //   IGSTControllers.add(TextEditingController());
  //   TotalPriceControllers.add(TextEditingController());
  //   _selectedSaleProductID.add(null); // Safe to add null since List<String?> allows nullable strings
  //   notifyListeners();
  // }
  //
  // void removeRow(int index) {
  //   if (index >= 0 && index < ProductControllers.length) {
  //     ProductControllers[index].dispose();
  //     ProductControllers.removeAt(index);
  //     PriceControllers[index].dispose();
  //     PriceControllers.removeAt(index);
  //     QuantityControllers[index].dispose();
  //     QuantityControllers.removeAt(index);
  //     CGSTControllers[index].dispose();
  //     CGSTControllers.removeAt(index);
  //     SGSTControllers[index].dispose();
  //     SGSTControllers.removeAt(index);
  //     IGSTControllers[index].dispose();
  //     IGSTControllers.removeAt(index);
  //     TotalPriceControllers[index].dispose();
  //     TotalPriceControllers.removeAt(index);
  //     _selectedSaleProductID.removeAt(index);
  //     notifyListeners();
  //   } else {
  //     print("Invalid index: $index");
  //   }
  // }
  // double get basicAmount {
  //   double total = 0;
  //   for (int i = 0; i < TotalPriceControllers.length; i++) {
  //     total += double.tryParse(TotalPriceControllers[i].text) ?? 0.0;
  //   }
  //   return total;
  // }
  //
  // double get cgstAmount {
  //   double total = 0;
  //   for (int i = 0; i < ProductControllers.length; i++) {
  //     final price = double.tryParse(PriceControllers[i].text) ?? 0.0;
  //     final quantity = double.tryParse(QuantityControllers[i].text) ?? 0.0;
  //     final cgst = double.tryParse(CGSTControllers[i].text) ?? 0.0;
  //     total += (price * quantity * cgst) / 100;
  //   }
  //   return total;
  // }
  //
  // double get sgstAmount {
  //   double total = 0;
  //   for (int i = 0; i < ProductControllers.length; i++) {
  //     final price = double.tryParse(PriceControllers[i].text) ?? 0.0;
  //     final quantity = double.tryParse(QuantityControllers[i].text) ?? 0.0;
  //     final sgst = double.tryParse(SGSTControllers[i].text) ?? 0.0;
  //     total += (price * quantity * sgst) / 100;
  //   }
  //   return total;
  // }
  //
  // double get igstAmount {
  //   double total = 0;
  //   for (int i = 0; i < ProductControllers.length; i++) {
  //     final price = double.tryParse(PriceControllers[i].text) ?? 0.0;
  //     final quantity = double.tryParse(QuantityControllers[i].text) ?? 0.0;
  //     final igst = double.tryParse(IGSTControllers[i].text) ?? 0.0;
  //     total += (price * quantity * igst) / 100;
  //   }
  //   return total;
  // }
  //
  // double get totalAmount => basicAmount + cgstAmount + sgstAmount + igstAmount;
  //
  //
  // // List<Map<String, String>> getFormData() {
  // //   _selectedOrders = [];
  // //
  // //   // Iterate over rows
  // //   for (int i = 0; i < ProductControllers.length; i++) {
  // //     // Only include rows with a valid product ID
  // //     if (_selectedSaleProductID[i] != null &&
  // //         ProductControllers[i].text.isNotEmpty) {
  // //       // Create a map for the current row's data
  // //       final rowData = {
  // //         "product_id": _selectedSaleProductID[i]!,
  // //         "product_name": ProductControllers[i].text,
  // //         "price": PriceControllers[i].text.isNotEmpty ? PriceControllers[i].text : "0",
  // //         "qty": QuantityControllers[i].text.isNotEmpty ? QuantityControllers[i].text : "0",
  // //         "cgst_p": CGSTControllers[i].text.isNotEmpty ? CGSTControllers[i].text : "0",
  // //         "sgst_p": SGSTControllers[i].text.isNotEmpty ? SGSTControllers[i].text : "0",
  // //         "igst_p": IGSTControllers[i].text.isNotEmpty ? IGSTControllers[i].text : "0",
  // //         "total_price": TotalPriceControllers[i].text.isNotEmpty ? TotalPriceControllers[i].text : "0",
  // //       };
  // //       _selectedOrders.add(rowData);
  // //     }
  // //   }
  // //
  // //   print("Form Data: $_selectedOrders");
  // //   notifyListeners();
  // //   return _selectedOrders;
  // // }
  //
  // Map<String, dynamic> getFormData() {
  //   final List<Map<String, dynamic>> orders = [];
  //   for (int i = 0; i < ProductControllers.length; i++) {
  //     orders.add({
  //       'product_id': selectedSaleProductID[i],
  //       'product_name': ProductControllers[i].text,
  //       'price': PriceControllers[i].text,
  //       'quantity': QuantityControllers[i].text,
  //       'cgst': CGSTControllers[i].text,
  //       'sgst': SGSTControllers[i].text,
  //       'igst': IGSTControllers[i].text,
  //       'total_price': TotalPriceControllers[i].text,
  //     });
  //   }
  //   return {
  //     'orders': orders,
  //     'basic_amount': basicAmount.toStringAsFixed(2),
  //     'cgst_amount': cgstAmount.toStringAsFixed(2),
  //     'sgst_amount': sgstAmount.toStringAsFixed(2),
  //     'igst_amount': igstAmount.toStringAsFixed(2),
  //     'total_amount': totalAmount.toStringAsFixed(2),
  //     'note': noteController.text,
  //   };
  // }

  Future<void> ordersAddOrderAPIViewFunction(context, mode) async {
    try {
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.addOrderViewAPI(
        provider.empId,
        provider.session,
        mode,
      );
      if (data != null) {
        if (data.error == "0") {
          _tpcApplicable = ["Yes","No"];
          _erectionScope = data.erectionScope!;
          _unloadingScope = data.unloadingScope!;
          _freightScope = data.freightScope!;
          _employees = data.employees!;
          _billingStates = data.states!;
          _dispatchStates = data.states!;
          _saleProducts = data.saleProducts!;

          checkDropdownselected();

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

  void checkDropdownselected() {
    if (_selectedAccountList != null &&
        !_accountList.contains(_selectedAccountList)) {
      _selectedAccountID = null;
      _selectedAccountName = "";
    }
    if (_selectedEmployees != null &&
        !_employees.contains(_selectedEmployees)) {
      _selectedEmployeeID = null;
      _selectedEmployeeName = "";
    }
    if (_selectedBillingStates != null &&
        !_billingStates.contains(_selectedBillingStates)) {
      _selectedBillingStateID = null;
      _selectedBillingStateName = "";

    }
    if (_selectedBillingDistricts != null &&
        !_billingDistricts.contains(_selectedBillingDistricts)) {
      _selectedBillingDistrictID = null;
      _selectedBillingDistrictValue = "";
    }
    if (_selectedBillingSubLocations != null &&
        !_billingSubLocations.contains(_selectedBillingSubLocations)) {
      _selectedBillingSubLocID = null;
      _selectedBillingSubLocValue = "";
    }
    if (_selectedDispatchStates != null &&
        !_dispatchStates.contains(_selectedDispatchStates)) {
      _selectedDispatchStateID = null;
      _selectedDispatchStateName = "";
    }
    if (_selectedDispatchDistricts != null &&
        !_dispatchDistricts.contains(_selectedDispatchDistricts)) {
      _selectedDispatchDistrictID = null;
      _selectedDispatchDistrictValue = "";
    }
    if (_selectedDispatchSubLocations != null &&
        !_dispatchSubLocations.contains(_selectedDispatchSubLocations)) {
      _selectedDispatchSubLocID = null;
      _selectedDispatchSubLocValue = "";
    }
    if (_selectedUnloadingScope != null &&
        !_unloadingScope.contains(_selectedUnloadingScope)) {
      _selectedUnloadingScope = null;
    }
    if (_selectedFreightScope != null &&
        !_freightScope.contains(_selectedFreightScope)) {
      _selectedFreightScope = null;
    }
    if (_selectedErectionScope != null &&
        !_erectionScope.contains(_selectedErectionScope)) {
      _selectedErectionScope = null;
    }

    if (_selectedTpcStatus != null &&
        !_tpcApplicable.contains(_selectedTpcStatus)) {
      _selectedTpcStatus = null;
    }

    if (_selectedTpcAgent != null &&
        !_tpcAgent.contains(_selectedTpcAgent)) {
      _selectedTpcAgentID = null;
      _selectedTpcAgentValue = "";
    }
    notifyListeners();
  }

  Future<void> ordersAddOrderAccountDetailsAPIFunction(
    context,
    account_id,
  ) async {
    try {
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.addOrderAccountDetailsAPI(
        provider.empId,
        provider.session,
        account_id,
      );
      if (data != null) {
        if (data.error == "0") {
          _accountDetails = data.accountDetails!;
          data.accountDetails!.accManagerId!;
          billingNameController.text = data.accountDetails!.name!;
          _selectedBillingSubLocID = data.accountDetails!.subLocality!;
          _selectedBillingDistrictID = data.accountDetails!.district!;
          _selectedBillingStateID = data.accountDetails!.state!;
          billingPincodeController.text = data.accountDetails!.pincode!;
          billingAddressController.text = data.accountDetails!.address!;
          orderReceivedDateController.text = data.accountDetails!.date!;

          gstController.text = data.accountDetails!.gstNumber!;
          notifyListeners();
        } else {}
      } else {}
    } catch (e, s) {}
  }

  Future<void> getDistrictAPI(context, stateID) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      _billingDistricts.clear();
      notifyListeners();
      final data = await ApiCalling.commonAddAccountViewDistrictAPI(
        homeProv.empId,
        homeProv.session,
        stateID,
      );
      if (data != null) {
        if (data.error == "0") {
          _billingDistricts = data.districts!;

          notifyListeners();
        }
      }
    } catch (e, s) {}
  }
  Future<void> getDispatchDistrictAPI(context, stateID) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      _dispatchDistricts.clear();
      notifyListeners();
      final data = await ApiCalling.commonAddAccountViewDistrictAPI(
        homeProv.empId,
        homeProv.session,
        stateID,
      );
      if (data != null) {
        if (data.error == "0") {
          _dispatchDistricts = data.districts!;

          notifyListeners();
        }
      }
    } catch (e, s) {}
  }

  Future<void> getSubLocationAPI(context, districtID) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      _billingSubLocations.clear();
      notifyListeners();
      final data = await ApiCalling.commonAddAccountViewSubLocationAPI(
        homeProv.empId,
        homeProv.session,
        districtID,
      );
      if (data != null) {
        if (data.error == "0") {
          _billingSubLocations = data.subLocations!;

          notifyListeners();
        }
      }
    } catch (e, s) {}
  }
  Future<void> getDispatchSubLocationAPI(context, districtID) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      _dispatchSubLocations.clear();
      notifyListeners();
      final data = await ApiCalling.commonAddAccountViewSubLocationAPI(
        homeProv.empId,
        homeProv.session,
        districtID,
      );
      if (data != null) {
        if (data.error == "0") {
          _dispatchSubLocations = data.subLocations!;

          notifyListeners();
        }
      }
    } catch (e, s) {}
  }

  Future<void> ordersAddOrderTPCAgentFunction(context,mode, text) async {
    try {
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.addOrderTPCAgentListAPI(
        provider.empId,
        provider.session,
        mode,
        text,
      );
      if (data != null) {
        if (data.error == "0") {
          _tpcAgent = data.tpcList!;
          notifyListeners();
        } else {}
      } else {}
    } catch (e, s) {}
  }

  Future<void> ordersAddOrderAPISubmitFunction(
    context,
    mode,
    selected_empid,
    selected_acid,
    selected_dis_stateId,
    selected_dis_districtId,
    selected_dis_subLocId,
    unloading_scope,
    frieght_scope,
    erection_scope,
    tpc_status,
    selected_bil_stateId,
    selected_bil_districtId,
    selected_bil_subLocId,
    tpc_agent_id,
    order_products,
  ) async {
    try {
      _submitClicked = true;
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.addOrderSubmitAPI(
        provider.empId,
        provider.session,
        mode,
        selected_empid,
        selected_acid,
        selected_dis_stateId,
        selected_dis_districtId,
        selected_dis_subLocId,
        dispatchPincodeController.text,
        dispatchAddressController.text,
        basicAmount,
        cgstAmount,
        sgstAmount,
        igstAmount,
        totalAmount,
        formattedDate,
        noteController.text,
        unloading_scope,
        frieght_scope,
        erection_scope,
        tpc_status,
        billingNameController.text,
        gstController.text,
        billingPincodeController.text,
        billingAddressController.text,
        selected_bil_stateId,
        selected_bil_districtId,
        selected_bil_subLocId,
        order_products,
        "",
        "",
        "",
        currentLocationLatLng,
        tpcAmountController.text,
        tpc_agent_id,
        _image,
      );
      if (data != null) {
        if (data.error == "0") {
          _submitClicked = false;
          resetForm();
          Navigator.pop(context);
          toast(context, data.message);
          notifyListeners();
        } else {
          _submitClicked = false;
          notifyListeners();
        }
      } else {
        _submitClicked = false;
        notifyListeners();
      }
    } catch (e, s) {
      _submitClicked = false;
      notifyListeners();
    }
  }

  Future<void> getCurrentLocation() async {
    try {
      Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: geo_location.LocationAccuracy.high,
      );
      currentLocationLatLng = LatLng(position.latitude, position.longitude);
      notifyListeners();
    } catch (e) {
      print("Error getting current location: $e");
    }
  }

  Future<void> getLocationPermission(BuildContext context) async {
    isLocationEnabled = await Geolocator.isLocationServiceEnabled();
    LocationPermission permission = await Geolocator.checkPermission();
    hasLocationPermission =
        permission == LocationPermission.always ||
        permission == LocationPermission.whileInUse;

    final Location.Location location = Location.Location();
    bool serviceEnabled = await location.serviceEnabled();
    if (!serviceEnabled) {
      serviceEnabled = await location.requestService();
      if (!serviceEnabled) {
        return;
      }
    }

    if (!isLocationEnabled || !hasLocationPermission) {
      permission = await Geolocator.requestPermission();
      if (permission != LocationPermission.always &&
          permission != LocationPermission.whileInUse) {
        showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('Location Permission Required'),
              content: Text(
                'Please allow the app to access your location for core functionality.',
              ),
              actions: <Widget>[
                TextButton(
                  style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.white),
                    overlayColor: MaterialStateProperty.all(Colors.white),
                  ),
                  onPressed: () async {
                    // await openAppSettings();
                    // Navigator.of(context).pop();
                    // Navigator.pushReplacement(
                    //   context,
                    //   MaterialPageRoute(builder: (context) => Attendance()),
                    // );
                  },
                  child: Text('OK'),
                ),
              ],
            );
          },
        );
        return;
      }
    }

    final Location.LocationData locData = await location.getLocation();
    if (locData != null) {
      currentLocation = locData;
      currentLocationLatLng = LatLng(locData.latitude!, locData.longitude!);

      markers.clear();
      markers.add(
        Marker(
          markerId: MarkerId('current_location'),
          position: LatLng(locData.latitude!, locData.longitude!),
          infoWindow: InfoWindow(title: 'Current Location'),
          icon: BitmapDescriptor.defaultMarker,
        ),
      );
      latlongs = '${locData.latitude},${locData.longitude}';

      notifyListeners();
    }
  }

  Future<void> ordersAddOrderSelectAccountAPIFunction(
    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();
        } 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();
    }
  }

  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 onChangedBillingName(value) {
    billingNameError = "";
    notifyListeners();
  }

  void onChangedBillingAddress(value) {
    billingAddressError = "";
    notifyListeners();
  }

  void onChangedBillingPincode(value) {
    billingPincodeError = "";
    notifyListeners();
  }

  void onChangedDispatchAddress(value) {
    dispatchAddressError = "";
    notifyListeners();
  }

  void onChangedDispatchPincode(value) {
    dispatchPincodeError = "";
    notifyListeners();
  }

  void onChangedGst(value) {
    gstError = "";
    notifyListeners();
  }

  void onChangeTpcAmount(value) {
    tpcAmountError = "";
    notifyListeners();
  }

  void resetForm() {
    _submitClicked = false;
    dropDownSearchController.clear();
    dropDownTpcSearchController.clear();
    billingNameController.clear();
    billingAddressController.clear();
    billingPincodeController.clear();
    dispatchAddressController.clear();
    dispatchPincodeController.clear();
    gstController.clear();
    orderReceivedDateController.clear();
    tpcAmountController.clear();
    gstController.clear();
    orderReceivedDateController.clear();
    noteController.clear();

    ProductControllers.forEach((action) => action.dispose());
    ProductControllers.clear();
    PriceControllers.forEach((action) => action.dispose());
    PriceControllers.clear();
    QuantityControllers.forEach((action) => action.dispose());
    QuantityControllers.clear();
    CGSTControllers.forEach((action) => action.dispose());
    CGSTControllers.clear();
    SGSTControllers.forEach((action) => action.dispose());
    SGSTControllers.clear();
    IGSTControllers.forEach((action) => action.dispose());
    IGSTControllers.clear();
    TotalPriceControllers.forEach((action) => action.dispose());
    TotalPriceControllers.clear();
    TaxableValueControllers.forEach((action) => action.dispose());
    TaxableValueControllers.clear();
    basicAmountReadOnlyController.clear();
    cgstReadOnlyController.clear();
    sgstReadOnlyController.clear();
    igstReadOnlyController.clear();
    totalReadOnlyAmountController.clear();

    _image = null;
    _imageName = null;
    _imagePicked = 0;

    selectAccountError = "";
    billingNameError = "";
    billingAddressError = "";
    billingPincodeError = "";
    dispatchAddressError = "";
    dispatchPincodeError = "";

    _selectedAccountList = null;
    _selectedEmployees = null;
    _selectedBillingStates = null;
    _selectedBillingDistricts = null;
    _selectedBillingSubLocations = null;
    _selectedDispatchStates = null;
    _selectedDispatchDistricts = null;
    _selectedDispatchSubLocations = null;
    _selectedSaleProducts = null;
    _selectedTpcAgent = null;
    _selectedUnloadingScope = null;
    _selectedFreightScope = null;
    _selectedErectionScope = null;
    _selectedTpcStatus = null;
    _selectedAccountID = "";
    _selectedAccountName = "";

    _selectedEmployeeID = "";
    _selectedEmployeeName = "";
    _selectedBillingStateID = "";
    _selectedBillingStateName = "";
    _selectedBillingDistrictID = "";
    _selectedBillingDistrictValue = "";
    _selectedBillingSubLocID = "";
    _selectedBillingSubLocValue = "";
    _selectedDispatchStateID = "";
    _selectedDispatchStateName = "";
    _selectedDispatchDistrictID = "";
    _selectedDispatchDistrictValue = "";
    _selectedDispatchSubLocID = "";
    _selectedDispatchSubLocValue = "";
    _selectedSaleProductID = [];
    _selectedSaleProductName = "";
    _selectedTpcStatus = "";
    _selectedTpcAgentID = "";
    _selectedTpcAgentValue = "";

    gstError = "";
    FileError = null;
    dateError = null;
    checkDropdownselected();
    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: 1,
                    child: SizedBox(
                      height: 40,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          CupertinoButton(
                            child: Text(
                              'Cancel',
                              style: TextStyle(fontFamily: "JakartaMedium"),
                            ),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                          CupertinoButton(
                            child: Text(
                              'Done',
                              style: TextStyle(fontFamily: "JakartaMedium"),
                            ),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                        ],
                      ),
                    ),
                  ),
                  Expanded(
                    flex: 3,
                    child: CupertinoDatePicker(
                      initialDateTime: _date ?? DateTime.now(),
                      mode: CupertinoDatePickerMode.date,
                      use24hFormat: true,
                      showDayOfWeek: true,
                      onDateTimeChanged: (DateTime newDate) {
                        setDate(newDate);
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
    );
  }
}
