import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/services/api_calling.dart';
import 'package:generp/Utils/commonServices.dart';
import 'package:provider/provider.dart';
import '../../Models/commonModels/DistrictsResponse.dart';
import '../../Models/commonModels/EditCommonAccFormDetailsResponse.dart';
import '../../Models/commonModels/SubLocationsResponse.dart';
import '../../Models/financeModels/ValidateBankAccountDetailsResponse.dart';
import '../../Models/financeModels/ValidateGstNumResponse.dart';
import '../../Models/commonModels/commonAddAccountsViewResponse.dart';

class EditCommonAccountProvider extends ChangeNotifier {
  // --- Text controllers used by edit form (only required ones) ---
  final TextEditingController nameController = TextEditingController();
  final TextEditingController mobileController = TextEditingController();
  final TextEditingController addressController = TextEditingController();
  final TextEditingController bankNameController = TextEditingController();
  final TextEditingController branchNameController = TextEditingController();
  final TextEditingController bankIfscCotroller = TextEditingController();
  final TextEditingController bankHolderNameController = TextEditingController();
  final TextEditingController gstNumberController = TextEditingController();
  final TextEditingController bankAcNumberController = TextEditingController();
  final TextEditingController bankUpiController = TextEditingController();

  // contact person details (kept because your form uses them)
  final TextEditingController contactPersonController = TextEditingController();
  // final TextEditingController contectPersonDesignationController = TextEditingController();
  // final TextEditingController contectPersonAltMobController = TextEditingController();
  // final TextEditingController contectPersonTeleController = TextEditingController();
  final TextEditingController contectPersonMailController = TextEditingController();

  // small search controllers for dropdown search widgets
  final TextEditingController stateSearchController = TextEditingController();
  final TextEditingController districtSearchController = TextEditingController();
  final TextEditingController subLocSearchController = TextEditingController();

  // --- simple error strings for UI ---
  String? accountError;
  String? nameError;
  String? mobileError;
  String? stateError;
  String? districtError;
  String? localityError;
  String? addressError;
  String? gstNumberError;
  String? banknameError;
  String? bankBranchError;
  String? bankIFSCError;
  String? bankHolderNameError;
  String? bankAcNumberError;
  String? upiError;
  String? contactPersonError;
  String? desigantionError;
  String? altMobError;
  String? teleError;
  String? mailError;
  String? addMoreDetailsError;

  // --- dropdown lists (populated from addCommonAccountView API) ---
  List<String> _accountTypes = [];
  List<States> _states = [];
  List<Districts> _districts = [];
  List<SubLocations> _subLocations = [];

  // selection holders
  String? _selectedAccountType;
  States? _selectedState;
  Districts? _selectedDistricts;
  SubLocations? _selectedSubLocations;

  // IDs / values (strings) used when sending API
  String? _selectedStateID;
  String? _selectedDistrictID;
  String? _selectedSubLocID;


  // responses from validation APIs
  ValidateGstNumResponse? gstResponse;
  ValidateBankAccountDetailsResponse? bankResponse;
  commonAddAccountsViewResponse? commonResponse;

  // loading & submit state
  bool _isLoading = false;
  bool _isSubmitting = false;
  String? updateErrorMessage;

  // getters
  bool get isLoading => _isLoading;
  bool get isSubmitting => _isSubmitting;

  List<States> get states => _states;
  List<Districts> get districts => _districts;
  List<SubLocations> get subLocations => _subLocations;

  String? get selectedAccountType => _selectedAccountType;
  States? get selectedState => _selectedState;
  Districts? get selectedDistricts => _selectedDistricts;
  SubLocations? get selectedSubLocations => _selectedSubLocations;

  String? get selectedStateID => _selectedStateID;
  String? get selectedDistrictId => _selectedDistrictID;
  String? get selectedSubLocID => _selectedSubLocID;

  bool _submitClicked = false;

  bool get submitClickced => _submitClicked;

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

  // --- setters that clear corresponding errors and notify ---
  set selectedAccountType(String? v) {
    _selectedAccountType = v;
    accountError = null;
    notifyListeners();
  }

  set selectedState(States? v) {
    _selectedState = v;
    _selectedStateID = v?.id;
    stateError = null;
    // clear dependent district/subLocation when state changes
    _districts.clear();
    _selectedDistricts = null;
    _selectedDistrictID = null;
    _subLocations.clear();
    _selectedSubLocations = null;
    _selectedSubLocID = null;
    notifyListeners();
  }

  set selectedDistricts(Districts? v) {
    _selectedDistricts = v;
    _selectedDistrictID = v?.id;
    districtError = null;
    _subLocations.clear();
    _selectedSubLocations = null;
    _selectedSubLocID = null;
    notifyListeners();
  }

  set selectedSubLocations(SubLocations? v) {
    _selectedSubLocations = v;
    _selectedSubLocID = v?.id;
    localityError = null;
    notifyListeners();
  }

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

  EditCommonAccFormDetailsResponse? detailsListResponse;



// LOAD ACCOUNT DETAILS + PREFILL ALL FIELDS
// ==========================================================
  Future<bool> loadAccountDetailsForEdit(
      BuildContext context,
      String accountId,
      ) async {
    try {
      isLoading = true;
      notifyListeners();

      final homeProv = Provider.of<HomescreenNotifier>(context, listen: false);

      final data = await ApiCalling.commonAccountDetailsListAPI(
        homeProv.empId,
        homeProv.session,
        accountId,
      );
      detailsListResponse =data;

      if (data == null || data.error != "0") {
        updateErrorMessage = data?.message ?? "Failed to load account details";
        isLoading = false;
        notifyListeners();
        return false;
      }

      // Expecting at least one account in the list; take the first.
      if (data.accountList == null || data.accountList!.isEmpty) {
        updateErrorMessage = "No account data returned";
        isLoading = false;
        notifyListeners();
        return false;
      }

      final acc = data.accountList!.first;


      // 1) PREFILL TEXT CONTROLLERS
      // ---------------------------
      nameController.text = acc.name ?? "";
      mobileController.text = acc.mob1 ?? "";
      addressController.text = acc.address ?? "";
      bankNameController.text = acc.bankName ?? "";
      branchNameController.text = acc.bankBranchName ?? "";
      bankIfscCotroller.text = acc.bankIfscCode ?? "";
      bankHolderNameController.text = acc.bankAccountHolderName ?? "";
      bankAcNumberController.text = acc.bankAccountNumber ?? "";
      bankUpiController.text = acc.bankUpiId ?? "";
      gstNumberController.text = acc.gstNumber ?? "";

      // contact person (if API has contact_name)
      contactPersonController.text = acc.contactName ?? "";
      // Other contact fields in API aren't present — keep empty or preserve existing

      contectPersonMailController.text = acc.email ?? "";


      // ---------------------------
      // 2) PREFILL ACCOUNT TYPE
      // ---------------------------
      selectedAccountType = acc.type;

      // ---------------------------
      // 3) LOAD DROPDOWNS (account types, states)
      // ---------------------------
      await addCommonAccountViewAPI(context);

      // ---------------------------
      // 4) SELECT STATE (by name)
      // ---------------------------
      if (acc.state != null && acc.state!.trim().isNotEmpty) {
        final matchState = _states.firstWhere(
              (s) => (s.name ?? "").toLowerCase() == acc.state!.trim().toLowerCase(),
          orElse: () => States(id: null, name: null),
        );

        if (matchState.id != null) {
          // use setter so it clears errors and resets dependent lists
          selectedState = matchState;
          _selectedStateID = matchState.id;

          // load districts for this state
          await getDistrictAPI(context, matchState.id);
        }
      }

      // ---------------------------
      // 5) SELECT DISTRICT (by name)
      // ---------------------------
      if (acc.district != null && acc.district!.trim().isNotEmpty && _districts.isNotEmpty) {
        final matchDist = _districts.firstWhere(
              (d) => (d.district ?? "").toLowerCase() == acc.district!.trim().toLowerCase(),
          orElse: () => Districts(id: null, district: null),
        );

        if (matchDist.id != null) {
          selectedDistricts = matchDist;
          _selectedDistrictID = matchDist.id;

          // load sub-localities for this district
          await getSubLocationAPI(context, matchDist.id);
        }
      }

      // ---------------------------
      // 6) SELECT SUB-LOCALITY (by name)
      // ---------------------------
      if (acc.subLocality != null && acc.subLocality!.trim().isNotEmpty && _subLocations.isNotEmpty) {
        final matchSub = _subLocations.firstWhere(
              (s) => (s.subLocality ?? "").toLowerCase() == acc.subLocality!.trim().toLowerCase(),
          orElse: () => SubLocations(id: null, subLocality: null),
        );

        if (matchSub.id != null) {
          selectedSubLocations = matchSub;
          _selectedSubLocID = matchSub.id;
        }
      }

      // everything loaded
      isLoading = false;
      notifyListeners();
      return true;
    } catch (e, s) {
      if (kDebugMode) debugPrint("loadAccountDetailsForEdit ERROR => $e\n$s");
      updateErrorMessage = e.toString();
      isLoading = false;
      notifyListeners();
      return false;
    }
  }


  Future<void> getDistrictAPI(context, stateID) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      _districts.clear();
      notifyListeners();
      final data = await ApiCalling.commonAddAccountViewDistrictAPI(
        homeProv.empId,
        homeProv.session,
        stateID,
      );
      if (data != null) {
        if (data.error == "0") {
          _districts = data.districts ?? [];
          notifyListeners();
        }
      }
    } catch (e) {
      if (kDebugMode) debugPrint('getDistrictAPI error: $e');
    }
  }

  Future<void> getSubLocationAPI(context, districtID) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      _subLocations.clear();
      notifyListeners();
      final data = await ApiCalling.commonAddAccountViewSubLocationAPI(
        homeProv.empId,
        homeProv.session,
        districtID,
      );
      if (data != null) {
        if (data.error == "0") {
          _subLocations = data.subLocations ?? [];
          notifyListeners();
        }
      }
    } catch (e) {
      if (kDebugMode) debugPrint('getSubLocationAPI error: $e');
    }
  }



  // --- API: load data needed to populate dropdowns (account types, states) ---
  Future<void> addCommonAccountViewAPI(BuildContext context) async {
    try {
      isLoading = true;
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.commonAddAccountViewAPI(homeProv.empId, homeProv.session);
      _accountTypes.clear();
      _states.clear();
      if (data != null && data.error == "0") {
        _accountTypes = data.accountTypes ?? [];
        _states = data.states ?? [];
        commonResponse = data;
      }
    } catch (e) {
      if (kDebugMode) debugPrint('addCommonAccountViewAPI error: $e');
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  // --- GST validation: calls API and sets gstResponse; returns true if valid ---
  Future<bool> validateGstNumber(String empId, String sessionId, String gstNumber) async {
    if (gstNumber.trim().isEmpty) {
      gstResponse = null;
      gstNumberError = null;
      notifyListeners();
      return false;
    }
    try {
      isLoading = true;
      final response = await ApiCalling.validateGstNumberApi(empId, sessionId, gstNumber.trim());
      gstResponse = response;
      if (response == null) {
        gstNumberError = "Failed to validate GST number";
        notifyListeners();
        return false;
      }
      if (response.error == "0") {
        gstNumberError = null;
        notifyListeners();
        return true;
      } else {
        gstNumberError = response.message ?? "Invalid GST number";
        notifyListeners();
        return false;
      }
    } catch (e) {
      gstNumberError = "Error validating GST: ${e.toString()}";
      if (kDebugMode) debugPrint('validateGstNumber error: $e');
      notifyListeners();
      return false;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  // --- Bank validation: requires both account number and IFSC ---
  Future<bool> validateBankDetails(String empId, String sessionId, String accountNumber) async {
    final ifsc = bankIfscCotroller.text.trim();
    final accList = detailsListResponse?.accountList!.first;
    if (accountNumber.trim().isEmpty || ifsc.isEmpty) {
      bankResponse = null;
      bankAcNumberError = null;
      bankIFSCError = null;
      bankNameController.text = "";
      branchNameController.text =  "";
      bankHolderNameController.text = "";
      bankNameController.text      = accList?.bankName ?? "";
      branchNameController.text = accList?.bankBranchName ?? "";
      bankHolderNameController.text = accList?.bankAccountHolderName ?? "";
      notifyListeners();
      return false;
    }

    if (bankAcNumberController.text.isEmpty || bankIfscCotroller.text.isEmpty) {
      bankNameController.text = "";
      branchNameController.text =  "";
      bankHolderNameController.text = "";
      bankNameController.text      = accList?.bankName ?? "";
      branchNameController.text = accList?.bankBranchName ?? "";
      bankHolderNameController.text = accList?.bankAccountHolderName ?? "";
      notifyListeners();
      return false;
    }



    final reg = RegExp(r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$');
    if (!reg.hasMatch(ifsc)) {
      bankIFSCError = "Invalid IFSC format";
      notifyListeners();
      return false;
    }

    try {
      isLoading = true;
      final response = await ApiCalling.validateBankAccountDetailsApi(empId, sessionId, accountNumber.trim(), ifsc);
      bankResponse = response;
      if (response == null) {
        bankAcNumberError = "Failed to validate bank account";
        notifyListeners();
        return false;
      }
      if (response.error == "0") {
        bankAcNumberError = null;
        bankIFSCError = null;
        notifyListeners();
        return true;
      } else {
        bankAcNumberError = response.message ?? "Invalid account details";
        notifyListeners();
        return false;
      }
    } catch (e) {
      bankAcNumberError = "Error validating account: ${e.toString()}";
      if (kDebugMode) debugPrint('validateBankDetails error: $e');
      notifyListeners();
      return false;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  // --- Combines validation and applies response (autofill) for GST ---
  Future<void> checkAndApplyGst(BuildContext context, String gstNumber) async {
    gstNumberError = null;
    notifyListeners();
    final trimmed = gstNumber.trim();
    if (trimmed.isEmpty) {
      gstResponse = null;
      gstNumberError = null;
      notifyListeners();
      return;
    }

    try {
      isLoading = true;
      final homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      final resp = await ApiCalling.validateGstNumberApi(homeProv.empId, homeProv.session, trimmed);
      gstResponse = resp;
      if (resp == null) {
        gstNumberError = "Failed to validate GST number";
        notifyListeners();
        return;
      }
      if (resp.error == "0") {
        // autofill address if available
        final apiAddress = (resp.address ?? "").trim();
        final apiName = (resp.legalNameOfBusiness ?? "").trim();
        if (apiAddress.isNotEmpty) {
          addressController.text = apiAddress;
        }
        // compare company name and set error if mismatch
        final enteredName = nameController.text.trim();
        if (apiName.isNotEmpty && enteredName.isNotEmpty) {
          if (apiName.toLowerCase() != enteredName.toLowerCase()) {
            nameError = "Name Does not match with GST Legal Name : ('$apiName').";
          } else {
            nameError = null;
          }
        }
        gstNumberError = null;
        notifyListeners();
        return;
      } else {
        _submitClicked = false;
        gstNumberError = resp.message ?? "Invalid GST number";
        notifyListeners();
        return;
      }
    } catch (e) {
      gstNumberError = "Error validating GST";
      if (kDebugMode) debugPrint("checkAndApplyGst error: $e");
      notifyListeners();
      return;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  // --- Combines validation and applies response (autofill) for Bank ---
  Future<void> checkAndApplyBank(BuildContext context, String accountNumber) async {
    bankAcNumberError = null;
    bankIFSCError = null;
    notifyListeners();

    final acc = accountNumber.trim();
    final ifsc = bankIfscCotroller.text.trim();

    if (acc.isEmpty && ifsc.isEmpty) {
      bankResponse = null;
      bankAcNumberError = null;
      bankIFSCError = null;
      notifyListeners();
      return;
    }

    // If account entered, IFSC required
    if (acc.isNotEmpty && ifsc.isEmpty) {
      bankIFSCError = "IFSC is required when account number is entered";
      notifyListeners();
      return;
    }

    // validate IFSC format
    final ifscReg = RegExp(r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$');
    if (ifsc.isNotEmpty && !ifscReg.hasMatch(ifsc)) {
      bankIFSCError = "Invalid IFSC format";
      notifyListeners();
      return;
    }

    if (acc.isNotEmpty && ifsc.isNotEmpty) {
      try {
        isLoading = true;
        final homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
        final resp = await ApiCalling.validateBankAccountDetailsApi(homeProv.empId, homeProv.session, acc, ifsc);
        bankResponse = resp;
        if (resp == null) {
          bankAcNumberError = "Failed to validate bank details";
          notifyListeners();
          return;
        }
        if (resp.error == "0") {
          // autofill bank fields from response
          bankNameController.text = resp.bankName ?? bankNameController.text;
          branchNameController.text = resp.branch ?? branchNameController.text;
          bankHolderNameController.text = resp.nameAtBank ?? bankHolderNameController.text;
          bankAcNumberError = null;
          bankIFSCError = null;
          banknameError = null;
          bankBranchError = null;
          bankHolderNameError = null;
          notifyListeners();
          return;
        } else {
          bankAcNumberError = resp.message ?? "Invalid account details";
          notifyListeners();
          return;
        }
      } catch (e) {
        bankAcNumberError = "Error validating bank: ${e.toString()}";
        if (kDebugMode) debugPrint("checkAndApplyBank error: $e");
        notifyListeners();
        return;
      } finally {
        isLoading = false;
        notifyListeners();
      }
    }
  }

  // --- Re-compare company name with GST (UI calls this on name change) ---
  void recheckNameWithGst() {
    if (gstResponse == null) return;
    final apiName = (gstResponse?.legalNameOfBusiness ?? "").trim();
    final enteredName = nameController.text.trim();
    if (apiName.isNotEmpty && enteredName.isNotEmpty) {
      if (apiName.toLowerCase() != enteredName.toLowerCase()) {
        nameError = "Name Does not match with GST Legal Name : ('$apiName').";
      } else {
        nameError = null;
      }
    }
    notifyListeners();
  }

  Future<void> checkInputsAPI(context, type, value) async {
    try {
      var homeProv = Provider.of<HomescreenNotifier>(context, listen: false);
      final data = await ApiCalling.commonAddAccountCheckInputsAPI(
        homeProv.empId,
        homeProv.session,
        type,
        value,
      );
      commonResponse =data;
      if (data != null) {
        if (data.error == "0") {
          nameError = null;
          mobileError = null;
          notifyListeners();
        } else if (data.error == "1") {
          if (data.message?.contains("name already exists") ?? false) {
            nameError = data.message ?? "";
          } else {
            mobileError = data.message ?? "";
          }
          notifyListeners();
        }
      }
    } catch (e) {
      if (kDebugMode) debugPrint('checkInputsAPI error: $e');
    }
  }

  // --- Submit (update) API function (calls your existing commonUpdateAccountDetailsAPI) ---
  Future<bool> updateAccountDetailsAPIFunction(
      BuildContext context, {
        required String accId,
        required String name,
        required String mob1,
        String? mob2,
        String? tel,
        String? email,
        String? designation,
        String? address,
        String? state,
        String? district,
        String? subLocality,
        String? bankName,
        String? branchName,
        String? bankIfscCode,
        String? accHolderName,
        String? bankAccNumber,
        String? bankUpiId,
      }) async {
    try {
      _isSubmitting = true;
      updateErrorMessage = null;
      notifyListeners();

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

      final data = await ApiCalling.commonUpdateAccountDetailsAPI(
        prov.empId,
        prov.session,
        accId,
        name,
        mob1,
        mob2 ?? '',
        tel ?? '',
        email ?? '',
        designation ?? '',
        address ?? '',
        state ?? '',
        district ?? '',
        subLocality ?? '',
        bankName ?? '',
        branchName ?? '',
        bankIfscCode ?? '',
        accHolderName ?? '',
        bankAccNumber ?? '',
        bankUpiId ?? '',
      );

      if (data == null) {
        updateErrorMessage = "No response from server";
        _isSubmitting = false;
        notifyListeners();
        return false;
      }

      if (data.error == "0" || data.error == 0) {
        toast(context, data.message ?? "Updated successfully");
        _isSubmitting = false;
        notifyListeners();
        return true;
      } else {
        updateErrorMessage = data.message ?? "Failed to update account";
        _isSubmitting = false;
        notifyListeners();
        return false;
      }
    } catch (e, s) {
      if (kDebugMode) debugPrint("updateAccountDetailsAPIFunction error: $e\n$s");
      updateErrorMessage = e.toString();
      _isSubmitting = false;
      notifyListeners();
      return false;
    }
  }

  bool _isGstValidFormat(String gst) {
    gst = gst.trim().toUpperCase();
    final reg = RegExp(r'^[0-3][0-9][A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$');
    return reg.hasMatch(gst);
  }

  // --- Simple validation (keeps same logic as your UI expects) ---
  bool validateStep1(BuildContext context) {
    accountError = null;
    nameError = null;
    mobileError = null;
    gstNumberError = null;
    contactPersonError = null;
    bool isValid = true;

    if (_selectedAccountType == null || _selectedAccountType!.isEmpty) {
      accountError = "Please select an Account";
      isValid = false;
    }
    if (nameController.text.trim().isEmpty) {
      nameError = "Please Enter a Name";
      isValid = false;
    }
    if(gstNumberController.text.trim().isNotEmpty){
      final gst = gstNumberController.text.trim();
      if (!_isGstValidFormat(gst)) {
        gstNumberError = "Invalid GST format";notifyListeners();
        isValid = false;
      }
    }

    if(gstNumberController.text.isEmpty){
      final accList = detailsListResponse?.accountList!.first;
      final gst = gstNumberController.text.trim();
      addressController.text = accList?.address ?? "";

    }

    if (nameError != null && nameError!.isNotEmpty) {
      isValid = false;
    }
    if (mobileController.text.trim().isNotEmpty && mobileController.text.length < 10) {
      mobileError = "Mobile Number should be 10 digits";
      isValid = false;
    }
    if (mobileController.text.trim().isEmpty) {
      mobileError = "Please Enter Mobile Number";
      isValid = false;
    }
    if (contactPersonController.text.trim().isEmpty) {
      contactPersonError = "Please Enter Contact Person Name";
      isValid = false;
    }

    // GST vs name check if gstResponse present
    if (gstResponse != null) {
      final apiName = (gstResponse?.legalNameOfBusiness ?? "").trim();
      final enteredName = nameController.text.trim();
      if (apiName.isNotEmpty && enteredName.isNotEmpty) {
        if (apiName.toLowerCase() != enteredName.toLowerCase()) {
          nameError = "Company name does not match GST record ('$apiName')";
          isValid = false;
        } else {
          nameError = null;
        }
      }
    }

    notifyListeners();
    return isValid;
  }

  bool validateStep() {
    final accList = detailsListResponse?.accountList!.first;
    if (gstNumberController.text.isEmpty) {
      final gst = gstNumberController.text.trim();
      addressController.text = accList?.address ?? "";
    }
    notifyListeners();
    return false;
  }
  bool validateStep3() {
    final accList = detailsListResponse?.accountList!.first;
    if (bankAcNumberController.text.isEmpty || bankIfscCotroller.text.isEmpty) {
      bankNameController.text = "";
      branchNameController.text =  "";
      bankHolderNameController.text = "";
      bankNameController.text      = accList?.bankName ?? "";
      branchNameController.text = accList?.bankBranchName ?? "";
      bankHolderNameController.text = accList?.bankAccountHolderName ?? "";
      notifyListeners();
      return false;
    }



    bool isValid = true;
    // optional step — you commented it optional. Keep commented validations deactivated.
    _submitClicked = false;
    notifyListeners();
    return isValid;
  }
  // Full form final validation before submit
  bool validatereceiptForm(BuildContext context) {
    // reset error holders
    accountError = null; nameError = null; mobileError = null;
    stateError = null; districtError = null; localityError = null; addressError = null;
    banknameError = null; gstNumberError = null; bankBranchError = null; bankIFSCError = null;
    bankHolderNameError = null; bankAcNumberError = null; upiError = null;
    contactPersonError = null; desigantionError = null; altMobError = null; teleError = null; mailError = null;
    bool isValid = true;

    if (_selectedAccountType == null || _selectedAccountType!.isEmpty) {
      accountError = "Please select an Account";
      isValid = false;
    }
    if (nameController.text.trim().isEmpty) {
      nameError = "Please Enter a Name";
      isValid = false;
    }
    if (mobileController.text.trim().isEmpty) {
      mobileError = "Please Enter Mobile Number";
      isValid = false;
    }
    if (contactPersonController.text.trim().isEmpty) {
      contactPersonError = "Please Enter Contact Person Name";
      isValid = false;
    }

    // GST check
    final apiName = (gstResponse?.legalNameOfBusiness ?? "").trim();
    final enteredName = nameController.text.trim();
    if (apiName.isNotEmpty && enteredName.isNotEmpty) {
      if (apiName.toLowerCase() != enteredName.toLowerCase()) {
        isValid = false;
        nameError = "Company name does not match GST record ('$apiName')";
      }
    }

    notifyListeners();
    return isValid;
  }

  // --- update helper setters to clear errors on edit ---
  void updateName(String value) {
    nameError = null;
    notifyListeners();
  }

  void updateMobile(String value) {
    mobileError = null;
    notifyListeners();
  }

  void updateAddress(String value) {
    addressError = null;
    notifyListeners();
  }

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

  void updateGSTNumber(String value) {
    gstNumberError = null;
    notifyListeners();
  }

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

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

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

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

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

  void updateContactPerson(String value) {
    contactPersonError = null;
    notifyListeners();
  }

  void updateDesignation(String value) {
    desigantionError = null;
    notifyListeners();
  }

  void updateAltMobile(String value) {
    altMobError = null;
    notifyListeners();
  }

  void updateTeleMobile(String value) {
    teleError = null;
    notifyListeners();
  }

  void updateMail(String value) {
    mailError = null;
    notifyListeners();
  }

  // --- Reset values used by Edit form (clears controllers + errors + selections) ---
  void resetValues() {
    _selectedAccountType = null;
    _selectedState = null;
    _selectedDistricts = null;
    _selectedSubLocations = null;
    _selectedStateID = null;
    _selectedDistrictID = null;
    _selectedSubLocID = null;

    gstResponse = null;
    bankResponse = null;
    commonResponse = null;
    updateErrorMessage = null;

    _isLoading = false;
    _isSubmitting = false;

    stateSearchController.clear();
    districtSearchController.clear();
    subLocSearchController.clear();

    nameController.clear();
    mobileController.clear();
    addressController.clear();
    bankNameController.clear();
    branchNameController.clear();
    bankIfscCotroller.clear();
    bankHolderNameController.clear();
    bankAcNumberController.clear();
    bankUpiController.clear();
    contactPersonController.clear();
    contectPersonMailController.clear();

    accountError = null;
    nameError = null;
    mobileError = null;
    stateError = null;
    districtError = null;
    localityError = null;
    addressError = null;
    banknameError = null;
    gstNumberError = null;
    bankBranchError = null;
    bankIFSCError = null;
    bankHolderNameError = null;
    bankAcNumberError = null;
    upiError = null;
    contactPersonError = null;
    desigantionError = null;
    altMobError = null;
    teleError = null;
    mailError = null;
    addMoreDetailsError = null;

    notifyListeners();
  }

  // dispose controllers when provider is disposed (optional)
  @override
  void dispose() {
    nameController.dispose();
    mobileController.dispose();
    addressController.dispose();
    bankNameController.dispose();
    branchNameController.dispose();
    bankIfscCotroller.dispose();
    bankHolderNameController.dispose();
    gstNumberController.dispose();
    bankAcNumberController.dispose();
    bankUpiController.dispose();
    contactPersonController.dispose();
    contectPersonMailController.dispose();
    stateSearchController.dispose();
    districtSearchController.dispose();
    subLocSearchController.dispose();
    super.dispose();
  }
}
