//
//  AccountDetailView.swift
//  B24PaymentSdk
//
//  Created by visal ny on 22/12/24.
//

import UIKit
import Alamofire

private func debugLogAccountTransactions(_ transactions: [DWalletTransaction], context: String) {
    print("========== \(context) ==========")
    let encoder = JSONEncoder()
    encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
    for (index, transaction) in transactions.enumerated() {
        if let data = try? encoder.encode(transaction),
           let json = String(data: data, encoding: .utf8) {
            print("[\(index)] \(json)")
        } else {
            print("[\(index)] unable to encode transaction: \(transaction.tranID)")
        }
    }
    print("================================")
}

class AccountDetailView: UIViewController, UIGestureRecognizerDelegate, TransactionsViewDelegate {
    
    
    @IBOutlet weak var transactionCollectionView: UICollectionView!
    @IBOutlet weak var containerHeader: UIView!
    @IBOutlet weak var bgLogo: UIView!
    @IBOutlet weak var lblTitle: UILabel!
    @IBOutlet weak var iconEdit: UIImageView!
    @IBOutlet weak var logo: UIImageView!
    @IBOutlet weak var contentContainer: UIView!
    @IBOutlet weak var accountNoText: UILabel!
    @IBOutlet weak var accountNameText: UILabel!
    @IBOutlet weak var currencyText: UILabel!
    @IBOutlet weak var accountNoValue: UILabel!
    @IBOutlet weak var accountNameValue: UILabel!
    @IBOutlet weak var currencyValue: UILabel!
    @IBOutlet weak var setDefaultButtonContainer: UIView!
    @IBOutlet weak var setDefaultIcon: UIImageView!
    @IBOutlet weak var setDefaultLabel: UILabel!
    @IBOutlet weak var disableContainer: UIView!
    @IBOutlet weak var disableIcon: UIImageView!
    @IBOutlet weak var disableLabel: UILabel!
    @IBOutlet weak var topupButton: UIButton!
    
    @IBOutlet weak var inactiveLabel: UILabel!
    @IBOutlet weak var bgInactive: UIView!
    @IBOutlet weak var accNoDotView: UILabel!
    
    @IBOutlet weak var accNameDotView: UILabel!
    
    @IBOutlet weak var progressIndicatorMain: UIActivityIndicatorView!
    @IBOutlet weak var progressContainer: UIView!
    @IBOutlet weak var currencyDotView: UILabel!
    
    @IBOutlet weak var emptyLabel: UILabel!

    @IBOutlet weak var toolbarLine: UIView!
    @IBOutlet weak var emptyImage: UIImageView!
    var dataAccountDetail = DataAccountDetail()
    var accountId: String = ""
    var paymentMethodId:String = ""
    var language:String = "km"
    
    var isDefault:Bool = false
    var isInactive:Bool = false
    var isWalletTopup:Bool = false
    
    var accountNo:String = "..."
    var paymentMethodCount:Int = 1
    
    // Constraint for topup button spacing adjustment
    private var setDefaultButtonTopConstraint: NSLayoutConstraint?
    private var disableButtonTopConstraint: NSLayoutConstraint?
    private var legacyContentHeightConstraint: NSLayoutConstraint?
    private var recentTransactionTopConstraint: NSLayoutConstraint?
    
    // Configuration property to control outside tap dismissal
    var shouldDismissOnOutsideTap: Bool = false

    let emptyIconName = "exclamationmark.circle.fill"

    var minHeight:Double = 0.0

    // Gradient card header properties
    private var cardGradientLayer: CAGradientLayer?
    private var hexagonLarge: CAShapeLayer?
    private var hexagonSmall: CAShapeLayer?

    // MARK: - Scroll Layout
    private let mainScrollView = UIScrollView()
    private let scrollContentView = UIView()
    private var hasConfiguredScrollableLayout = false

    // MARK: - Recent Transaction Section
    private let recentTransactionContainer = UIView()
    private let recentTransactionHeader = UIView()
    private let recentTransactionLabel = UILabel()
    private let viewAllButton = UIButton(type: .system)
    private let recentTransactionPreview = UIStackView()
    private let recentTransactionLoader = UIActivityIndicatorView(style: .medium)
    private var loaderHeightConstraint: NSLayoutConstraint?
    private var recentTransactions: [DWalletTransaction] = []
    private weak var transactionDetailView: TransactionDetailView?

    // MARK: - Pull-to-Refresh
    private let refreshControl = UIRefreshControl()

    // MARK: - Network Monitoring
    private var isWaitingForConnection: Bool = false

    // MARK: - Transaction Polling
    private var pollingTimer: Timer?
    private var isPolling: Bool = false
    private var isFetchingTransactions: Bool = false
    private var isFetchingBalance: Bool = false

    private func currentDisplayedAccountName() -> String {
        if let cardNameLabel = containerHeader.viewWithTag(2010) as? UILabel,
           let text = cardNameLabel.text?.trimmingCharacters(in: .whitespacesAndNewlines),
           !text.isEmpty {
            return text
        }

        let fallbackText = lblTitle.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        return fallbackText.isEmpty ? dataAccountDetail.accountName : fallbackText
    }
    private let pollingInterval: TimeInterval = 10.0
    private var pollingRetryCount: Int = 0
    private let maxPollingRetries: Int = 30

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = DefaultAppearance.shared.screenBgColor
        toolbarLine.isHidden = true
        
        
        getSharePref()
        setupScrollableLayout()
        setupRefreshControl()
        setupRecentTransactionUI()

        applyToolBar()
        
        B24PaymentSdkHelper.getCurrentLanguage(language: language)
       
        accountDetail()
        setupModifyName()
       
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        guard let gradientView = containerHeader.viewWithTag(2003) else { return }
        let bounds = gradientView.bounds
        guard bounds.width > 0 else { return }

        cardGradientLayer?.frame = bounds

        // Large hexagon: 120×120, top-right, partially off-card
        let largeSize: CGFloat = 120
        let largeRect = CGRect(
            x: bounds.width - largeSize + 30,
            y: -30,
            width: largeSize,
            height: largeSize
        )
        hexagonLarge?.path = hexagonPath(in: largeRect).cgPath

        // Small hexagon: 80×80, bottom-right area
        let smallSize: CGFloat = 80
        let smallRect = CGRect(
            x: bounds.width - smallSize - 40,
            y: bounds.height - smallSize + 20,
            width: smallSize,
            height: smallSize
        )
        hexagonSmall?.path = hexagonPath(in: smallRect).cgPath
    }

    private func hexagonPath(in rect: CGRect) -> UIBezierPath {
        let path = UIBezierPath()
        path.move(to:    CGPoint(x: rect.midX,        y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX,        y: rect.minY + rect.height * 0.25))
        path.addLine(to: CGPoint(x: rect.maxX,        y: rect.minY + rect.height * 0.75))
        path.addLine(to: CGPoint(x: rect.midX,        y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.minX,        y: rect.minY + rect.height * 0.75))
        path.addLine(to: CGPoint(x: rect.minX,        y: rect.minY + rect.height * 0.25))
        path.close()
        return path
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setupNetworkMonitoring()
        NetworkMonitor.shared.startMonitoring()
        accountDetail()
        fetchRecentTransaction()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        stopPolling()
        NetworkMonitor.shared.stopMonitoring()
        NetworkMonitor.shared.onConnectionStatusChanged = nil
    }

    deinit {
        pollingTimer?.invalidate()
    }

    private func setupScrollableLayout() {
        guard !hasConfiguredScrollableLayout else { return }
        hasConfiguredScrollableLayout = true

        mainScrollView.translatesAutoresizingMaskIntoConstraints = false
        mainScrollView.showsVerticalScrollIndicator = true
        mainScrollView.showsHorizontalScrollIndicator = false
        mainScrollView.backgroundColor = DefaultAppearance.shared.screenBgColor
        mainScrollView.delaysContentTouches = false

        scrollContentView.translatesAutoresizingMaskIntoConstraints = false

        [containerHeader, setDefaultButtonContainer, disableContainer, topupButton].forEach {
            $0?.removeFromSuperview()
        }

        view.addSubview(mainScrollView)
        mainScrollView.addSubview(scrollContentView)
        scrollContentView.addSubview(containerHeader)
        scrollContentView.addSubview(setDefaultButtonContainer)
        scrollContentView.addSubview(disableContainer)
        scrollContentView.addSubview(topupButton)
        scrollContentView.addSubview(recentTransactionContainer)

        [containerHeader, setDefaultButtonContainer, disableContainer, recentTransactionContainer, topupButton].forEach {
            $0?.translatesAutoresizingMaskIntoConstraints = false
        }

        NSLayoutConstraint.activate([
            topupButton.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor, constant: 20),
            topupButton.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor, constant: -20),
            topupButton.heightAnchor.constraint(equalToConstant: 50),

            mainScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            mainScrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            mainScrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            mainScrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),

            scrollContentView.topAnchor.constraint(equalTo: mainScrollView.contentLayoutGuide.topAnchor),
            scrollContentView.leadingAnchor.constraint(equalTo: mainScrollView.contentLayoutGuide.leadingAnchor),
            scrollContentView.trailingAnchor.constraint(equalTo: mainScrollView.contentLayoutGuide.trailingAnchor),
            scrollContentView.bottomAnchor.constraint(equalTo: mainScrollView.contentLayoutGuide.bottomAnchor),
            scrollContentView.widthAnchor.constraint(equalTo: mainScrollView.frameLayoutGuide.widthAnchor),

            containerHeader.topAnchor.constraint(equalTo: scrollContentView.topAnchor, constant: 30),
            containerHeader.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor, constant: 20),
            containerHeader.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor, constant: -20),

            setDefaultButtonContainer.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor, constant: 30),
            disableContainer.leadingAnchor.constraint(equalTo: setDefaultButtonContainer.trailingAnchor, constant: 34),
            disableContainer.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor, constant: -30),
            setDefaultButtonContainer.widthAnchor.constraint(equalTo: disableContainer.widthAnchor),
            setDefaultButtonContainer.heightAnchor.constraint(equalToConstant: 55),
            disableContainer.heightAnchor.constraint(equalToConstant: 55),

            recentTransactionContainer.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor, constant: 20),
            recentTransactionContainer.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor, constant: -20),
            recentTransactionContainer.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor, constant: -20)
        ])

        contentContainer.isHidden = true
        view.bringSubviewToFront(progressContainer)
        view.bringSubviewToFront(toolbarLine)
    }

    // MARK: - Pull-to-Refresh Setup
    private func setupRefreshControl() {
        refreshControl.tintColor = DefaultAppearance.shared.primaryColor
        refreshControl.addTarget(self, action: #selector(refreshAccountDetail), for: .valueChanged)
        mainScrollView.refreshControl = refreshControl
    }

    @objc private func refreshAccountDetail() {
        accountDetail()
    }

    // MARK: - Network Monitoring Setup
    private func setupNetworkMonitoring() {
        NetworkMonitor.shared.onConnectionStatusChanged = { [weak self] isConnected in
            guard let self = self else { return }

            if isConnected {
                guard self.isWaitingForConnection else { return }

                self.isWaitingForConnection = false

                B24PaymentSdkHelper.hideNoInternetPopup(from: self)
                // Auto-refresh account details when connection is restored
                self.accountDetail()
            }
        }
    }

    private func setupRecentTransactionUI() {
        recentTransactionContainer.translatesAutoresizingMaskIntoConstraints = false
        recentTransactionContainer.isHidden = true

        recentTransactionHeader.translatesAutoresizingMaskIntoConstraints = false
        recentTransactionContainer.addSubview(recentTransactionHeader)

        recentTransactionLabel.text = B24PaymentSdkHelper.localized(TransactionDetailLocalizedKeys.tran_recent.rawValue)
        recentTransactionLabel.font = FontManager.shared.mediumFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.contentText)
        recentTransactionLabel.textColor = DefaultAppearance.shared.primaryLabelColor
        recentTransactionLabel.translatesAutoresizingMaskIntoConstraints = false
        recentTransactionHeader.addSubview(recentTransactionLabel)

        let viewAllTitle = NSAttributedString(
            string: B24PaymentSdkHelper.localized(AddWalletLocalizedKeys.view_all.rawValue),
            attributes: [
                .font: FontManager.shared.mediumFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.contentText),
                .foregroundColor: DefaultAppearance.shared.primaryColor
            ]
        )
        viewAllButton.setAttributedTitle(viewAllTitle, for: .normal)
        viewAllButton.translatesAutoresizingMaskIntoConstraints = false
        viewAllButton.addTarget(self, action: #selector(transactionButtonTapped), for: .touchUpInside)
        recentTransactionHeader.addSubview(viewAllButton)

        recentTransactionLoader.translatesAutoresizingMaskIntoConstraints = false
        recentTransactionLoader.hidesWhenStopped = true
        recentTransactionLoader.color = DefaultAppearance.shared.primaryColor
        recentTransactionContainer.addSubview(recentTransactionLoader)
        recentTransactionContainer.bringSubviewToFront(recentTransactionLoader)

        recentTransactionPreview.axis = .vertical
        recentTransactionPreview.spacing = 10
        recentTransactionPreview.alignment = .fill
        recentTransactionPreview.distribution = .fill
        recentTransactionPreview.translatesAutoresizingMaskIntoConstraints = false
        recentTransactionContainer.addSubview(recentTransactionPreview)

        NSLayoutConstraint.activate([
            recentTransactionHeader.topAnchor.constraint(equalTo: recentTransactionContainer.topAnchor),
            recentTransactionHeader.leadingAnchor.constraint(equalTo: recentTransactionContainer.leadingAnchor),
            recentTransactionHeader.trailingAnchor.constraint(equalTo: recentTransactionContainer.trailingAnchor),
            recentTransactionHeader.heightAnchor.constraint(equalToConstant: 30),

            recentTransactionLabel.leadingAnchor.constraint(equalTo: recentTransactionHeader.leadingAnchor),
            recentTransactionLabel.centerYAnchor.constraint(equalTo: recentTransactionHeader.centerYAnchor),

            viewAllButton.trailingAnchor.constraint(equalTo: recentTransactionHeader.trailingAnchor),
            viewAllButton.centerYAnchor.constraint(equalTo: recentTransactionHeader.centerYAnchor),

            recentTransactionPreview.topAnchor.constraint(equalTo: recentTransactionHeader.bottomAnchor, constant: 10),
            recentTransactionPreview.leadingAnchor.constraint(equalTo: recentTransactionContainer.leadingAnchor),
            recentTransactionPreview.trailingAnchor.constraint(equalTo: recentTransactionContainer.trailingAnchor),
            recentTransactionPreview.bottomAnchor.constraint(equalTo: recentTransactionContainer.bottomAnchor),

            recentTransactionLoader.centerXAnchor.constraint(equalTo: recentTransactionPreview.centerXAnchor),
            recentTransactionLoader.centerYAnchor.constraint(equalTo: recentTransactionPreview.centerYAnchor)
        ])

        loaderHeightConstraint = recentTransactionPreview.heightAnchor.constraint(equalToConstant: 120)
    }
    
     
    @IBAction func topUpButtonAction(_ sender: Any) {
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()
                
                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }

        if isInactive{
            let dialog = WarningAlertView()
            dialog.showWarningTopupAlert(from: self) {
             self.updateAccountStatus(inactive: false)
            } cancelHandler: {

            }

        }else{
            let storyboard = UIStoryboard(name: "InstantPaymentMethodView", bundle: B24PaymentSdkHelper.frameworkBundle())
            if let topUpVC = storyboard.instantiateViewController(withIdentifier: "TopUpView") as? TopUpView {
                // Pass the currency from the current account detail
                topUpVC.currency = self.dataAccountDetail.currency
                topUpVC.walletId = self.dataAccountDetail.id
                topUpVC.walletName = self.dataAccountDetail.accountName
                topUpVC.wallet = self.dataAccountDetail.accountNo
                topUpVC.balance = self.dataAccountDetail.amountDisplay
                topUpVC.currencyCode=self.dataAccountDetail.currencyCode
                topUpVC.currencySymbol=self.dataAccountDetail.currencySymbol

                navigationController?.pushViewController(topUpVC, animated: true)
            }
            
        }
    }

    @objc func transactionButtonTapped() {
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()

                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }

        showBottomSheet()
    }

    @objc func navigateToBill24Url() {
        B24PaymentSdkHelper.openDeeplink(deepLinkUrl: APIManager.openBill24Website(), view: self.view)
    }
    
    private func applyToolBar(){
        // Configure navigation bar appearance for consistency
        if #available(iOS 13.0, *) {
            let appearance = UINavigationBarAppearance()
            appearance.configureWithOpaqueBackground()
            appearance.backgroundColor = DefaultAppearance.shared.screenBgColor
            appearance.shadowColor = DefaultAppearance.shared.primaryLabelColor.withAlphaComponent(0.3)
            
            navigationController?.navigationBar.standardAppearance = appearance
            navigationController?.navigationBar.scrollEdgeAppearance = appearance
            navigationController?.navigationBar.compactAppearance = appearance
        } else {
            navigationController?.navigationBar.barTintColor = DefaultAppearance.shared.screenBgColor
            navigationController?.navigationBar.isTranslucent = false
        }
        
        let customButton = UIButton(type: .system)
        customButton.translatesAutoresizingMaskIntoConstraints = false
        // Image
        let imageView = UIImageView(image: UIImage(systemName: "chevron.backward"))
        imageView.tintColor = DefaultAppearance.shared.primaryLabelColor
        imageView.contentMode = .scaleAspectFit
        imageView.translatesAutoresizingMaskIntoConstraints = false
        customButton.addSubview(imageView)
        
        let titleLabel = UILabel()
        
        let toolbarTitle:String = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.title.rawValue)
        
        titleLabel.text = toolbarTitle + accountNo
        
        titleLabel.textColor = DefaultAppearance.shared.primaryLabelColor
        titleLabel.font = FontManager.shared.mediumFont(forLanguage: language,fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.toolbarTitle)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        customButton.addSubview(titleLabel)

        // Add constraints to position the image and title properly
        NSLayoutConstraint.activate([
            // imageView.leadingAnchor.constraint(equalTo: customButton.leadingAnchor,constant: 10),
            imageView.leadingAnchor.constraint(equalTo: customButton.leadingAnchor),
            imageView.centerYAnchor.constraint(equalTo: customButton.centerYAnchor),
            //  imageView.widthAnchor.constraint(equalToConstant: 24), // Set desired width
            imageView.widthAnchor.constraint(equalToConstant: 20),
            imageView.heightAnchor.constraint(equalToConstant: 24),
                        
                        
            //            titleLabel.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 8),
            titleLabel.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 4),
            titleLabel.centerYAnchor.constraint(equalTo: customButton.centerYAnchor),
            //            titleLabel.trailingAnchor.constraint(equalTo: customButton.trailingAnchor,constant: -10)
            titleLabel.trailingAnchor.constraint(equalTo: customButton.trailingAnchor, constant: -5),
        ])

        // Add action to the button
        customButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)

        // Create a UIBarButtonItem with the custom button
        let backButton = UIBarButtonItem(customView: customButton)
        navigationItem.leftBarButtonItem = backButton
    }
    
    // Back button action
    @objc func backButtonTapped() {
      //  navigationController?.popViewController(animated: true)
//        if let navigationController = self.navigationController, navigationController.viewControllers.count > 1 {
//                // There's a navigation controller and more than one view controller in the stack, so we can pop
//            if(isWalletTopup){
//                dismissAll()
//            }else{
//                navigationController.popViewController(animated: true)
//            }
//                
//        } else {
//                // No navigation controller or no previous view controller in the stack
//            print("Cannot pop view controller. Either no navigation controller or at root view.")
//        }
        
        if let navigationController = navigationController {
            if navigationController.viewControllers.count > 1 {
                // Pop if not the root view controller
                if(isWalletTopup){
                    dismissAll()
                }else{
                    navigationController.popViewController(animated: true)
                }
                //navigationController.popViewController(animated: true)
            } else {
                // Dismiss if this is the root view controller
                dismiss(animated: true, completion: nil)
            }
        } else {
            // Dismiss if not in a navigation controller
            dismiss(animated: true, completion: nil)
        }
        
        
    }
    
    func dismissAll(){
        var presentingVC = presentingViewController
        while let parent = presentingVC?.presentingViewController {
            presentingVC = parent
        }
        presentingVC?.dismiss(animated: true) {
            print("Dismissal completed")
        }
    }
    
    
    private func startLoading() {
       DispatchQueue.main.async {
           self.mainScrollView.isHidden = true
           self.emptyImage.isHidden = true
           self.emptyLabel.isHidden = true
           self.progressContainer.isHidden = false
           self.progressContainer.backgroundColor = DefaultAppearance.shared.cardColor
           self.progressIndicatorMain.hidesWhenStopped = true
           self.progressIndicatorMain.color = DefaultAppearance.shared.primaryColor
           self.progressContainer.backgroundColor = DefaultAppearance.shared.screenBgColor
           self.progressIndicatorMain.startAnimating()
       }
    }
    
    private func stopLoading() {
        DispatchQueue.main.async {
            self.progressIndicatorMain.stopAnimating()
            self.progressContainer.isHidden = true
            self.progressIndicatorMain.isHidden = true
            self.mainScrollView.isHidden = false
        }
    }
    
    
    private func getSharePref(){
        if let languageCode = SharedPreferenceManager.getString(forKey: SharePrefKey.lanuageCode.rawValue){
            language = languageCode
        }else{
            language = "km"
        }
        
        if let id = SharedPreferenceManager.getString(forKey: SharePrefKey.paymentMethodId.rawValue){
            paymentMethodId = id
        }else{
            paymentMethodId = ""
        }
        
        isWalletTopup = SharedPreferenceManager.getBool(forKey: SharePrefKey.isWalletTopup.rawValue)
    }
    
    private func headerAppearance(data:DataAccountDetail){
        containerHeader.backgroundColor = .clear
        containerHeader.addCardShadow(cornerRadius: 16)
        containerHeader.roundCorners(cornerRadius: 16)

        // Remove the storyboard fixed height constraint so the card can grow to fit content
        if let superview = containerHeader.superview {
            for constraint in superview.constraints {
                let involvesHeader = (constraint.firstItem as? UIView) === containerHeader || (constraint.secondItem as? UIView) === containerHeader
                if involvesHeader && (constraint.firstAttribute == .height || constraint.secondAttribute == .height) {
                    constraint.isActive = false
                }
            }
            // Also update leading/trailing to add side margins for card appearance
            for constraint in superview.constraints {
                if (constraint.firstItem as? UIView) === containerHeader && constraint.firstAttribute == .leading {
                    constraint.constant = 20
                }
                if (constraint.secondItem as? UIView) === containerHeader && constraint.secondAttribute == .trailing {
                    constraint.constant = 20
                }
                if (constraint.firstItem as? UIView) === containerHeader && constraint.firstAttribute == .trailing {
                    constraint.constant = -20
                }
                // Also check reverse direction trailing
                if let secondItem = constraint.secondItem as? UIView, secondItem === containerHeader && constraint.firstAttribute == .trailing {
                    constraint.constant = 20
                }
            }
        }

        // Hide storyboard elements — replaced by programmatic card
        bgLogo.isHidden = true
        logo.isHidden = true
        lblTitle.isHidden = true
        iconEdit.isHidden = true
        bgInactive.isHidden = true
        inactiveLabel.isHidden = true

        // --- Gradient background (tag 2003, added once) ---
        if containerHeader.viewWithTag(2003) == nil {
            let gradientView = UIView()
            gradientView.tag = 2003
            gradientView.translatesAutoresizingMaskIntoConstraints = false
            gradientView.layer.cornerRadius = 16
            gradientView.clipsToBounds = true
            containerHeader.insertSubview(gradientView, at: 0)
            NSLayoutConstraint.activate([
                gradientView.topAnchor.constraint(equalTo: containerHeader.topAnchor),
                gradientView.leadingAnchor.constraint(equalTo: containerHeader.leadingAnchor),
                gradientView.trailingAnchor.constraint(equalTo: containerHeader.trailingAnchor),
                gradientView.bottomAnchor.constraint(equalTo: containerHeader.bottomAnchor)
            ])
            let gradient = CAGradientLayer()
            gradient.colors = [
                DefaultAppearance.shared.walletCardColor.blended(with: .white, ratio: 0.08).cgColor,
                DefaultAppearance.shared.walletCardColor.cgColor,
                DefaultAppearance.shared.walletCardColor.blended(with: .black, ratio: 0.22).cgColor
            ]
            gradient.locations = [0.0, 0.6, 1.0]
            gradient.startPoint = CGPoint(x: 0.1, y: 0.0)
            gradient.endPoint = CGPoint(x: 0.9, y: 1.0)
            gradientView.layer.addSublayer(gradient)
            cardGradientLayer = gradient

            // Large hexagon
            let large = CAShapeLayer()
            large.fillColor = UIColor(hex: "#54A6DB").withAlphaComponent(0.08).cgColor
            large.strokeColor = UIColor.clear.cgColor
            gradientView.layer.addSublayer(large)
            hexagonLarge = large

            // Small hexagon
            let small = CAShapeLayer()
            small.fillColor = UIColor(hex: "#54A6DB").withAlphaComponent(0.05).cgColor
            small.strokeColor = UIColor.clear.cgColor
            gradientView.layer.addSublayer(small)
            hexagonSmall = small
        }

        cardGradientLayer?.colors = [
            DefaultAppearance.shared.walletCardColor.blended(with: .white, ratio: 0.08).cgColor,
            DefaultAppearance.shared.walletCardColor.cgColor,
            DefaultAppearance.shared.walletCardColor.blended(with: .black, ratio: 0.22).cgColor
        ]

        // --- Wallet icon badge (tag 2001, top-right) ---
        if containerHeader.viewWithTag(2001) == nil {
            let logoBackgroundView = UIView()
            logoBackgroundView.tag = 2001
            logoBackgroundView.backgroundColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.15)
            logoBackgroundView.layer.cornerRadius = 8
            logoBackgroundView.layer.borderColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.2).cgColor
            logoBackgroundView.layer.borderWidth = 1
            logoBackgroundView.translatesAutoresizingMaskIntoConstraints = false
            containerHeader.addSubview(logoBackgroundView)

            let logoImageView = UIImageView()
            logoImageView.image = UIImage(named: "wallet", in: B24PaymentSdkHelper.frameworkBundle(), compatibleWith: nil)?.withRenderingMode(.alwaysTemplate)
            logoImageView.tintColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.8)
            logoImageView.contentMode = .scaleAspectFit
            logoImageView.translatesAutoresizingMaskIntoConstraints = false
            logoBackgroundView.addSubview(logoImageView)

            NSLayoutConstraint.activate([
                logoBackgroundView.topAnchor.constraint(equalTo: containerHeader.topAnchor, constant: 20),
                logoBackgroundView.trailingAnchor.constraint(equalTo: containerHeader.trailingAnchor, constant: -20),
                logoBackgroundView.widthAnchor.constraint(equalToConstant: 40),
                logoBackgroundView.heightAnchor.constraint(equalToConstant: 40),

                logoImageView.centerXAnchor.constraint(equalTo: logoBackgroundView.centerXAnchor),
                logoImageView.centerYAnchor.constraint(equalTo: logoBackgroundView.centerYAnchor),
                logoImageView.widthAnchor.constraint(equalToConstant: 20),
                logoImageView.heightAnchor.constraint(equalToConstant: 20)
            ])
        }

        // --- Account name label (tag 2010) ---
        containerHeader.viewWithTag(2010)?.removeFromSuperview()
        let nameLabel = UILabel()
        nameLabel.tag = 2010
        nameLabel.text = data.accountName
        nameLabel.textColor = DefaultAppearance.shared.onPrimaryColor
        nameLabel.font = FontManager.shared.boldFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.toolbarTitle)
        nameLabel.numberOfLines = 1
        nameLabel.lineBreakMode = .byTruncatingTail
        nameLabel.adjustsFontSizeToFitWidth = false
        nameLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        nameLabel.setContentHuggingPriority(.required, for: .vertical)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        containerHeader.addSubview(nameLabel)

        // --- Edit icon (tag 2011, next to name) ---
        containerHeader.viewWithTag(2011)?.removeFromSuperview()
        let editIconContainer = UIView()
        editIconContainer.tag = 2011
        editIconContainer.translatesAutoresizingMaskIntoConstraints = false
        editIconContainer.backgroundColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.15)
        editIconContainer.layer.cornerRadius = 10
        editIconContainer.isUserInteractionEnabled = true

        let editIcon = UIImageView()
        editIcon.image = UIImage(systemName: "pencil")
        editIcon.tintColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.85)
        editIcon.contentMode = .scaleAspectFit
        editIcon.translatesAutoresizingMaskIntoConstraints = false
        let editTap = UITapGestureRecognizer(target: self, action: #selector(modifyNameTapped))
        editIconContainer.addGestureRecognizer(editTap)
        editIconContainer.addSubview(editIcon)
        containerHeader.addSubview(editIconContainer)

        NSLayoutConstraint.activate([
            editIcon.centerXAnchor.constraint(equalTo: editIconContainer.centerXAnchor),
            editIcon.centerYAnchor.constraint(equalTo: editIconContainer.centerYAnchor),
            editIcon.widthAnchor.constraint(equalToConstant: 16),
            editIcon.heightAnchor.constraint(equalToConstant: 16)
        ])

        // --- Default / Inactive badge (tag 2012) ---
        containerHeader.viewWithTag(2012)?.removeFromSuperview()
        if isInactive || isDefault {
            let badgeContainer = UIView()
            badgeContainer.tag = 2012
            badgeContainer.translatesAutoresizingMaskIntoConstraints = false
            badgeContainer.layer.cornerRadius = 4

            let badgeLabel = UILabel()
            badgeLabel.translatesAutoresizingMaskIntoConstraints = false
            badgeLabel.font = FontManager.shared.regularFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: 11)

            if isInactive {
                badgeContainer.backgroundColor = DefaultAppearance.shared.dangerColor.withAlphaComponent(0.25)
                badgeLabel.textColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.85)
                badgeLabel.text = B24PaymentSdkHelper.localized(PaymentMethodWalletLocalizedKeys.inActive.rawValue)
            } else {
                badgeContainer.backgroundColor = DefaultAppearance.shared.primaryColor
                badgeLabel.textColor = DefaultAppearance.shared.onPrimaryColor
                badgeLabel.text = B24PaymentSdkHelper.localized(PaymentMethodWalletLocalizedKeys.DefaultACC.rawValue)
            }

            badgeContainer.addSubview(badgeLabel)
            containerHeader.addSubview(badgeContainer)

            NSLayoutConstraint.activate([
                badgeLabel.topAnchor.constraint(equalTo: badgeContainer.topAnchor, constant: 3),
                badgeLabel.bottomAnchor.constraint(equalTo: badgeContainer.bottomAnchor, constant: -3),
                badgeLabel.leadingAnchor.constraint(equalTo: badgeContainer.leadingAnchor, constant: 8),
                badgeLabel.trailingAnchor.constraint(equalTo: badgeContainer.trailingAnchor, constant: -8),
            ])
        }

        // --- Account number label (tag 2013) ---
        containerHeader.viewWithTag(2013)?.removeFromSuperview()
        let accNoLabel = UILabel()
        accNoLabel.tag = 2013
        accNoLabel.text = data.accountNo
        accNoLabel.textColor = DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.5)
        accNoLabel.font = FontManager.shared.regularFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.tranTypeText)
        accNoLabel.numberOfLines = 0
        accNoLabel.lineBreakMode = .byWordWrapping
        accNoLabel.adjustsFontSizeToFitWidth = false
        accNoLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        accNoLabel.setContentHuggingPriority(.required, for: .vertical)
        accNoLabel.translatesAutoresizingMaskIntoConstraints = false
        containerHeader.addSubview(accNoLabel)

        // --- Balance label (tag 2014) ---
        containerHeader.viewWithTag(2014)?.removeFromSuperview()
        let balLabel = UILabel()
        balLabel.tag = 2014
        balLabel.translatesAutoresizingMaskIntoConstraints = false
        let balanceText: String
        if data.type == AvailablePMType.wallet.rawValue {
            balanceText = B24PaymentSdkHelper.localized(AddWalletLocalizedKeys.balance.rawValue).uppercased()
        } else {
            balanceText = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_currency.rawValue).uppercased()
        }
        balLabel.attributedText = NSAttributedString(string: balanceText, attributes: [
            .kern: 0.6,
            .font: FontManager.shared.mediumFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.walletBalanceLabel),
            .foregroundColor: DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.6)
        ])
        balLabel.numberOfLines = 0
        balLabel.lineBreakMode = .byWordWrapping
        balLabel.adjustsFontSizeToFitWidth = false
        balLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        balLabel.setContentHuggingPriority(.required, for: .vertical)
        containerHeader.addSubview(balLabel)

        // --- Amount label (tag 2015) ---
        containerHeader.viewWithTag(2015)?.removeFromSuperview()
        let amtLabel = UILabel()
        amtLabel.tag = 2015
        amtLabel.translatesAutoresizingMaskIntoConstraints = false

        if data.type == AvailablePMType.wallet.rawValue {
            let cleanBalance = data.amountDisplay
                .replacingOccurrences(of: data.currency, with: "", options: .caseInsensitive)
                .trimmingCharacters(in: .whitespaces)
            let currText = data.currency.trimmingCharacters(in: .whitespacesAndNewlines)
            let amountAttr = NSMutableAttributedString(string: cleanBalance, attributes: [
                .font: FontManager.shared.boldFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.walletBalance),
                .foregroundColor: DefaultAppearance.shared.onPrimaryColor
            ])
            amountAttr.append(NSAttributedString(string: "  \(currText)", attributes: [
                .font: FontManager.shared.regularFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.cardSubTitle),
                .foregroundColor: DefaultAppearance.shared.onPrimaryColor
            ]))
            amtLabel.attributedText = amountAttr
        } else {
            amtLabel.attributedText = NSAttributedString(string: data.currency, attributes: [
                .font: FontManager.shared.boldFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.walletBalance),
                .foregroundColor: DefaultAppearance.shared.onPrimaryColor
            ])
        }
        let isKhmerHeader = language.lowercased() == "km"
        amtLabel.numberOfLines = 0
        amtLabel.lineBreakMode = .byWordWrapping
        amtLabel.adjustsFontSizeToFitWidth = !isKhmerHeader
        amtLabel.minimumScaleFactor = 0.6
        amtLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        amtLabel.setContentHuggingPriority(.required, for: .vertical)
        containerHeader.addSubview(amtLabel)

        // --- Powered by Bill24 (tag 2016) ---
        containerHeader.viewWithTag(2016)?.removeFromSuperview()
        let poweredByLabel = UILabel()
        poweredByLabel.tag = 2016
        poweredByLabel.translatesAutoresizingMaskIntoConstraints = false
        poweredByLabel.textAlignment = .right
        let poweredAttr = NSMutableAttributedString(
            string: "Powered by ",
            attributes: [
                .font: UIFont.italicSystemFont(ofSize: FixFontSize.poweredByText),
                .foregroundColor: DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.4)
            ]
        )
        poweredAttr.append(NSAttributedString(
            string: "Bill24",
            attributes: [
                .font: FontManager.shared.boldFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.walletBalanceLabel),
                .foregroundColor: DefaultAppearance.shared.onPrimaryColor.withAlphaComponent(0.7)
            ]
        ))
        poweredByLabel.attributedText = poweredAttr
        poweredByLabel.isUserInteractionEnabled = true
        poweredByLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(navigateToBill24Url)))
        containerHeader.addSubview(poweredByLabel)

        // --- Layout constraints ---
        var constraints: [NSLayoutConstraint] = [
            // Name
            nameLabel.topAnchor.constraint(equalTo: containerHeader.topAnchor, constant: 20),
            nameLabel.leadingAnchor.constraint(equalTo: containerHeader.leadingAnchor, constant: 20),
            nameLabel.widthAnchor.constraint(lessThanOrEqualToConstant: 180),

            // Edit icon
            editIconContainer.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor),
            editIconContainer.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: 8),
            editIconContainer.widthAnchor.constraint(equalToConstant: 24),
            editIconContainer.heightAnchor.constraint(equalToConstant: 24),
        ]

        // Badge constraints (if visible)
        if let badgeView = containerHeader.viewWithTag(2012) {
            constraints.append(contentsOf: [
                badgeView.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor),
                badgeView.leadingAnchor.constraint(equalTo: editIconContainer.trailingAnchor, constant: 8),
            ])
        }

        constraints.append(contentsOf: [
            // Account number
            accNoLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 2),
            accNoLabel.leadingAnchor.constraint(equalTo: containerHeader.leadingAnchor, constant: 20),

            // Balance label
            balLabel.topAnchor.constraint(equalTo: accNoLabel.bottomAnchor, constant: 16),
            balLabel.leadingAnchor.constraint(equalTo: containerHeader.leadingAnchor, constant: 20),

            // Amount
            amtLabel.topAnchor.constraint(equalTo: balLabel.bottomAnchor, constant: 4),
            amtLabel.leadingAnchor.constraint(equalTo: containerHeader.leadingAnchor, constant: 20),
            amtLabel.trailingAnchor.constraint(lessThanOrEqualTo: containerHeader.trailingAnchor, constant: -20),

            // Powered by
            poweredByLabel.topAnchor.constraint(equalTo: amtLabel.bottomAnchor, constant: 14),
            poweredByLabel.trailingAnchor.constraint(equalTo: containerHeader.trailingAnchor, constant: -20),
            poweredByLabel.bottomAnchor.constraint(equalTo: containerHeader.bottomAnchor, constant: -20)
        ])

        NSLayoutConstraint.activate(constraints)
    }
    
    private func contentAppearance(data:DataAccountDetail){
        hideLegacySummarySection()
    }
    
    func buttonAppearance(data:DataAccountDetail){
        updateActionSectionLayout(showActionCards: paymentMethodCount != 1)
        
        // Hide buttons and adjust spacing if paymentMethodCount == 1
        if paymentMethodCount == 1 {
            setDefaultButtonContainer.isHidden = true
            disableContainer.isHidden = true
            
            // Remove existing constraints and set new constraint for topupButton
            adjustTopupButtonSpacing()
            return
        }
        
        setDefaultButtonContainer.isHidden = false
        disableContainer.isHidden = false
        
        // Reset topup button spacing for normal case
        resetTopupButtonSpacing()
        
        setDefaultButtonContainer.backgroundColor = DefaultAppearance.shared.cardColor
        setDefaultButtonContainer.layer.cornerRadius = 8
        
        disableContainer.backgroundColor = DefaultAppearance.shared.cardColor
        disableContainer.layer.cornerRadius = 8
        
        //size
        setDefaultLabel.text = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_set_default.rawValue)
        setDefaultLabel.font = FontManager.shared.regularFont(forLanguage: language ,fontFromconfig: DefaultAppearance.shared.fontEnglish, size: language == "km" ? 14 : FixFontSize.buttonText)
        disableLabel.font = FontManager.shared.regularFont(forLanguage: language ,fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.buttonText)

        if isDefault{
            setDefaultIcon.tintColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
            setDefaultLabel.textColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
            disableIcon.tintColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
            disableLabel.textColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
//            disableIcon.image = UIImage(systemName: "circle.slash.fill")
            disableLabel.text = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_disable.rawValue)
           
            
            setupSetDefualtButtonEvent(clickable: false)
            setupDisableAccountEvent(clickable: false)
            
        }else{
           
            if(isInactive){
                
                //default icon
                setDefaultIcon.tintColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
                setDefaultLabel.textColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
                disableIcon.tintColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
                disableLabel.textColor = DefaultAppearance.shared.secondaryLabelColor.withAlphaComponent(0.3)
//                disableIcon.image = UIImage(systemName: "circle.slash.fill")
                disableLabel.text = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_disable.rawValue)
                
                
                disableIcon.tintColor = DefaultAppearance.shared.primaryColor
                disableIcon.image = UIImage(systemName: "checkmark.circle.fill")
                disableLabel.text = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_enable.rawValue)
                disableLabel.textColor = DefaultAppearance.shared.primaryColor
                //action to enable
                setupEnableAccountEvent()
                
                
                // action on set default
                setupSetDefualtButtonEvent(clickable: false)
                
                
            }else{
                
                setDefaultLabel.textColor = DefaultAppearance.shared.primaryColor
                setDefaultIcon.tintColor = DefaultAppearance.shared.primaryColor
                
                // action on set default
                setupSetDefualtButtonEvent(clickable: true)
                
                
                disableIcon.tintColor = DefaultAppearance.shared.dangerColor
//                disableIcon.image = UIImage(systemName: "circle.slash.fill")
                disableLabel.text = B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_disable.rawValue)
                disableLabel.textColor = DefaultAppearance.shared.dangerColor
                //action to inactive
                setupDisableAccountEvent(clickable: true)
                
            }
        }
    }
    
    // MARK: - Constraint Adjustment Methods
    private func adjustTopupButtonSpacing() {
        updateActionSectionLayout(showActionCards: false)
    }
    
    private func resetTopupButtonSpacing() {
        updateActionSectionLayout(showActionCards: true)
    }

    private func hideLegacySummarySection() {
        contentContainer.isHidden = true

        if legacyContentHeightConstraint == nil {
            legacyContentHeightConstraint = contentContainer.heightAnchor.constraint(equalToConstant: 0)
        }
        legacyContentHeightConstraint?.isActive = true

        if let superview = contentContainer.superview {
            let constraintsToDeactivate = superview.constraints.filter { constraint in
                let firstView = constraint.firstItem as? UIView
                let secondView = constraint.secondItem as? UIView
                let involvesContent = firstView === contentContainer || secondView === contentContainer
                let isPositioningConstraint = constraint.firstAttribute == .top || constraint.secondAttribute == .top
                return involvesContent && isPositioningConstraint
            }
            NSLayoutConstraint.deactivate(constraintsToDeactivate)
        }
    }

    private func updateActionSectionLayout(showActionCards: Bool) {
        let actionCards = [setDefaultButtonContainer, disableContainer]

        actionCards.forEach { actionView in
            actionView?.translatesAutoresizingMaskIntoConstraints = false
        }

        [setDefaultButtonTopConstraint, disableButtonTopConstraint, recentTransactionTopConstraint].forEach {
            $0?.isActive = false
        }

        setDefaultButtonTopConstraint = nil
        disableButtonTopConstraint = nil
        recentTransactionTopConstraint = nil

        if let superview = recentTransactionContainer.superview {
            let constraintsToDeactivate = superview.constraints.filter { constraint in
                let firstView = constraint.firstItem as? UIView
                let secondView = constraint.secondItem as? UIView
                let trackedViews = [recentTransactionContainer, setDefaultButtonContainer, disableContainer, topupButton]
                let involvesTrackedView = trackedViews.contains { view in
                    firstView === view || secondView === view
                }
                let isTopConstraint = constraint.firstAttribute == .top || constraint.secondAttribute == .top
                return involvesTrackedView && isTopConstraint
            }
            NSLayoutConstraint.deactivate(constraintsToDeactivate)
        }

        if showActionCards {
            setDefaultButtonTopConstraint = setDefaultButtonContainer.topAnchor.constraint(
                equalTo: containerHeader.bottomAnchor,
                constant: 20
            )
            disableButtonTopConstraint = disableContainer.topAnchor.constraint(
                equalTo: containerHeader.bottomAnchor,
                constant: 20
            )
            let topupButtonTopConstraint = topupButton.topAnchor.constraint(
                equalTo: setDefaultButtonContainer.bottomAnchor,
                constant: 20
            )
            recentTransactionTopConstraint = recentTransactionContainer.topAnchor.constraint(
                equalTo: topupButton.bottomAnchor,
                constant: 20
            )

            setDefaultButtonTopConstraint?.isActive = true
            disableButtonTopConstraint?.isActive = true
            topupButtonTopConstraint.isActive = true
        } else {
            let topupButtonTopConstraint = topupButton.topAnchor.constraint(
                equalTo: containerHeader.bottomAnchor,
                constant: 20
            )
            recentTransactionTopConstraint = recentTransactionContainer.topAnchor.constraint(
                equalTo: topupButton.bottomAnchor,
                constant: 20
            )
            topupButtonTopConstraint.isActive = true
        }

        recentTransactionTopConstraint?.isActive = true

        view.setNeedsLayout()
        view.layoutIfNeeded()
    }
    
    func topUpButtonAppearance(){
        topupButton.tintColor = DefaultAppearance.shared.primaryColor
//        topupButton.setTitleColor(DefaultAppearance.shared.onPrimaryColor, for: .normal)
//        topupButton.setTitle(B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_top_up.rawValue), for: .normal)
//        topupButton.titleLabel?.font = FontManager.shared.boldFont(forLanguage: language , size: FixFontSize.buttonText)
        
        let topupAttributedTitle = NSAttributedString(
            string: B24PaymentSdkHelper.localized(AccountDetailLocalizedKeys.detail_top_up.rawValue),
                    attributes: [
                        .font: FontManager.shared.regularFont(forLanguage: self.language,fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.buttonText),
                        .foregroundColor: DefaultAppearance.shared.onPrimaryColor
                    ]
                )
        self.topupButton.setAttributedTitle(topupAttributedTitle, for: .normal)
    }
    
    // MARK: - Post-Payment Refresh
    func refreshAfterPayment() {
        print("[AccountDetail Polling] refreshAfterPayment — refreshing balance & transactions")
        accountDetail()
    }

    // MARK: - Recent Transactions
    private func fetchRecentTransaction() {
        guard !paymentMethodId.isEmpty else { return }
        guard !isFetchingTransactions else { return }

        isFetchingTransactions = true

        recentTransactionPreview.arrangedSubviews.forEach { $0.removeFromSuperview() }

        guard NetworkMonitor.shared.isConnected else {
            isFetchingTransactions = false
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()
            }
            showRecentTransactionEmptyState(message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error_connect_server.rawValue))
            return
        }

        let url = APIManager.merchantApiUrl().appendingPathComponent("instantpaymentsdk/payment_method/transactions")
        let parameters: [String: Any] = [
            "id": paymentMethodId,
            "pagination": [
                "current_page": 1,
                "page_size": 5
            ]
        ]
        print("AccountDetailView recent transactions request -> url: \(url.absoluteString), payload: \(parameters)")

        recentTransactionContainer.isHidden = false
        loaderHeightConstraint?.isActive = true
        DispatchQueue.main.async {
            self.recentTransactionLoader.startAnimating()
        }

        AF.request(
            url,
            method: .post,
            parameters: parameters,
            encoding: JSONEncoding.default,
            headers: APIManager.initHeader()
        )
        .validate()
        .responseDecodable(of: DWalletTransactionResponseModel.self) { [weak self] response in
            guard let self = self else { return }
            self.isFetchingTransactions = false

            self.loaderHeightConstraint?.isActive = false
            DispatchQueue.main.async {
                self.recentTransactionLoader.stopAnimating()
            }

            switch response.result {
            case .success(let responseModel):
                if responseModel.code == StatusCode.succcess.rawValue {
                    let transactions = responseModel.data.transactions
                    debugLogAccountTransactions(transactions, context: "AccountDetailView recent transactions response")
                    self.recentTransactions = transactions
                    if !transactions.isEmpty {
                        self.updateRecentTransactionUI(with: transactions)
                    } else {
                        self.recentTransactionContainer.isHidden = true
                    }
                    self.evaluatePolling(transactions: transactions)
                } else {
                    let message = self.language.lowercased() == "en" ? responseModel.message : responseModel.messageKh
                    self.showRecentTransactionEmptyState(message: message)
                }
            case .failure(let error):
                if error.isSessionTaskError {
                    if !self.isWaitingForConnection {
                        self.isWaitingForConnection = true
                        self.setupNetworkMonitoring()
                        NetworkMonitor.shared.startMonitoring()
                    }
                    self.showRecentTransactionEmptyState(message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error_connect_server.rawValue))
                } else {
                    self.showRecentTransactionEmptyState()
                }
            }
        }
    }

    private func showRecentTransactionEmptyState(message: String? = nil) {
        recentTransactions = []
        recentTransactionPreview.arrangedSubviews.forEach { $0.removeFromSuperview() }
        recentTransactionContainer.isHidden = true
    }

    // MARK: - Transaction Polling Control

    private func evaluatePolling(transactions: [DWalletTransaction]) {
        let processingTopUps = transactions.filter {
            $0.tranType == TransactionType.walletTopup.rawValue && $0.status == "processing"
        }

        if !processingTopUps.isEmpty {
            print("[AccountDetail Polling] Found \(processingTopUps.count) processing top-up(s): \(processingTopUps.map { $0.tranID })")
            startPollingIfNeeded()
        } else {
            if isPolling {
                print("[AccountDetail Polling] No more processing top-ups — stopping polling & fetching balance")
                stopPolling()
                silentFetchBalance()
            }
        }
    }

    private func startPollingIfNeeded() {
        guard !isPolling else { return }
        guard pollingRetryCount < maxPollingRetries else {
            print("[AccountDetail Polling] Max retries (\(maxPollingRetries)) reached — stopping")
            stopPolling()
            return
        }
        isPolling = true
        print("[AccountDetail Polling] START polling (interval: \(pollingInterval)s)")
        pollingTimer = Timer.scheduledTimer(
            timeInterval: pollingInterval,
            target: self,
            selector: #selector(pollingTick),
            userInfo: nil,
            repeats: true
        )
    }

    @objc private func pollingTick() {
        pollingRetryCount += 1
        print("[AccountDetail Polling] Tick #\(pollingRetryCount)/\(maxPollingRetries)")
        if pollingRetryCount >= maxPollingRetries {
            print("[AccountDetail Polling] Max retries reached — stopping")
            stopPolling()
            return
        }
        guard !isFetchingTransactions else {
            print("[AccountDetail Polling] Skipping tick — fetch still in-flight")
            return
        }
        silentFetchRecentTransaction()
    }

    private func stopPolling() {
        let wasPolling = isPolling
        pollingTimer?.invalidate()
        pollingTimer = nil
        isPolling = false
        pollingRetryCount = 0
        if wasPolling {
            print("[AccountDetail Polling] STOPPED")
        }
    }

    // MARK: - Silent Fetches (polling only — no loaders)

    private func silentFetchRecentTransaction() {
        guard !isFetchingTransactions else { return }
        guard !paymentMethodId.isEmpty else { return }
        guard NetworkMonitor.shared.isConnected else {
            print("[AccountDetail Polling] Silent fetch skipped — no network")
            return
        }

        isFetchingTransactions = true
        print("[AccountDetail Polling] Silent fetching transactions...")

        let url = APIManager.merchantApiUrl()
            .appendingPathComponent("instantpaymentsdk/payment_method/transactions")
        let parameters: [String: Any] = [
            "id": paymentMethodId,
            "pagination": ["current_page": 1, "page_size": 5]
        ]

        AF.request(url, method: .post, parameters: parameters,
                   encoding: JSONEncoding.default, headers: APIManager.initHeader())
            .validate()
            .responseDecodable(of: DWalletTransactionResponseModel.self) { [weak self] response in
                guard let self = self else { return }
                self.isFetchingTransactions = false

                if case .success(let responseModel) = response.result,
                   responseModel.code == StatusCode.succcess.rawValue {
                    let transactions = responseModel.data.transactions
                    print("[AccountDetail Polling] Silent fetch got \(transactions.count) transactions")
                    self.recentTransactions = transactions
                    if !transactions.isEmpty {
                        self.updateRecentTransactionUI(with: transactions)
                    }
                    self.evaluatePolling(transactions: transactions)
                } else {
                    print("[AccountDetail Polling] Silent fetch failed — will retry next tick")
                }
            }
    }

    private func silentFetchBalance() {
        guard !isFetchingBalance else { return }
        guard !paymentMethodId.isEmpty else { return }
        guard NetworkMonitor.shared.isConnected else { return }

        isFetchingBalance = true
        print("[AccountDetail Polling] Silent fetching balance...")

        AF.request(WalletRouter.instantPaymentMethodDetail(id: paymentMethodId))
            .validate().responseData { [weak self] response in
                guard let self = self else { return }
                self.isFetchingBalance = false

                if case .success(let data) = response.result,
                   let decoded = try? JSONDecoder().decode(
                       ApiResponse<DataAccountDetail>.self, from: data),
                   decoded.code == StatusCode.succcess.rawValue {
                    self.dataAccountDetail = decoded.data
                    SharedPreferenceManager.set(
                        value: decoded.data.amountDisplay,
                        forKey: SharePrefKey.balance.rawValue)
                    print("[AccountDetail Polling] Balance updated: \(decoded.data.amountDisplay)")
                    DispatchQueue.main.async {
                        self.headerAppearance(data: decoded.data)
                    }
                } else {
                    print("[AccountDetail Polling] Silent balance fetch failed")
                }
            }
    }

    private func updateRecentTransactionUI(with transactions: [DWalletTransaction]) {
        recentTransactionPreview.arrangedSubviews.forEach { $0.removeFromSuperview() }

        let maxCount = min(transactions.count, 5)
        for index in 0..<maxCount {
            let transaction = transactions[index]
            let row = createTransactionRow(from: transaction)
            row.tag = index
            row.isUserInteractionEnabled = true
            row.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(recentTransactionTapped(_:))))
            recentTransactionPreview.addArrangedSubview(row)
            NSLayoutConstraint.activate([
                row.heightAnchor.constraint(equalToConstant: 70)
            ])
        }

        recentTransactionContainer.isHidden = false
        view.layoutIfNeeded()
    }

    @objc private func recentTransactionTapped(_ sender: UITapGestureRecognizer) {
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()

                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }

        guard let row = sender.view, row.tag < recentTransactions.count else { return }
        let selectedTransaction = recentTransactions[row.tag]

        let storyboard = UIStoryboard(name: "InstantPaymentMethodView", bundle: B24PaymentSdkHelper.frameworkBundle())
        guard let transactionDetailVC = storyboard.instantiateViewController(withIdentifier: "TransactionDetailView") as? TransactionDetailView else { return }

        transactionDetailVC.tranID = selectedTransaction.tranID
        self.transactionDetailView = transactionDetailVC
        transactionDetailVC.modalPresentationStyle = .overFullScreen
        self.present(transactionDetailVC, animated: false) {
            self.transactionDetailView?.handleConnectionChange(isConnected: NetworkMonitor.shared.isConnected)
        }
    }

    private func createTransactionRow(from transaction: DWalletTransaction) -> UIView {
        let row = UIView()
        row.translatesAutoresizingMaskIntoConstraints = false
        row.backgroundColor = DefaultAppearance.shared.cardColor
        row.layer.cornerRadius = 12

        let logoBg = UIView()
        let isTopup = transaction.tranType == TransactionType.walletTopup.rawValue
        logoBg.backgroundColor = isTopup ? DefaultAppearance.shared.successColor.withAlphaComponent(0.1) : DefaultAppearance.shared.dangerColor.withAlphaComponent(0.1)
        logoBg.layer.cornerRadius = 20
        logoBg.clipsToBounds = true
        logoBg.translatesAutoresizingMaskIntoConstraints = false
        row.addSubview(logoBg)

        let logo = UIImageView()
        logo.translatesAutoresizingMaskIntoConstraints = false
        logoBg.addSubview(logo)

        var logoConstraints: [NSLayoutConstraint] = []
        func setLogoFill(_ fill: Bool) {
            NSLayoutConstraint.deactivate(logoConstraints)
            logoConstraints.removeAll()

            if fill {
                logoConstraints = [
                    logo.topAnchor.constraint(equalTo: logoBg.topAnchor),
                    logo.bottomAnchor.constraint(equalTo: logoBg.bottomAnchor),
                    logo.leadingAnchor.constraint(equalTo: logoBg.leadingAnchor),
                    logo.trailingAnchor.constraint(equalTo: logoBg.trailingAnchor)
                ]
                logo.contentMode = .scaleAspectFill
            } else {
                logoConstraints = [
                    logo.centerXAnchor.constraint(equalTo: logoBg.centerXAnchor),
                    logo.centerYAnchor.constraint(equalTo: logoBg.centerYAnchor),
                    logo.widthAnchor.constraint(equalTo: logoBg.widthAnchor, multiplier: 0.4),
                    logo.heightAnchor.constraint(equalTo: logoBg.heightAnchor, multiplier: 0.4)
                ]
                logo.contentMode = .scaleAspectFit
            }
            NSLayoutConstraint.activate(logoConstraints)
        }

        let isKhmer = language.lowercased() == "km"

        let titleLabel = UILabel()
        titleLabel.font = isKhmer
            ? FontManager.shared.regularFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.tranText)
            : FontManager.shared.mediumFont(forLanguage: language, fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.tranText)
        titleLabel.textColor = DefaultAppearance.shared.secondaryLabelColor
        titleLabel.numberOfLines = 0
        titleLabel.lineBreakMode = .byWordWrapping
        titleLabel.adjustsFontSizeToFitWidth = false
        titleLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        titleLabel.setContentHuggingPriority(.required, for: .vertical)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false

        let detailLabel = UILabel()
        detailLabel.font = FontManager.shared.regularFont(
            forLanguage: language,
            fontFromconfig: DefaultAppearance.shared.fontEnglish,
            size: FixFontSize.tranTypeText
        )
        detailLabel.textColor = DefaultAppearance.shared.primaryLabelColor.withAlphaComponent(0.4)
        detailLabel.numberOfLines = 0
        detailLabel.lineBreakMode = .byWordWrapping
        detailLabel.adjustsFontSizeToFitWidth = false
        detailLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        detailLabel.setContentHuggingPriority(.required, for: .vertical)
        detailLabel.translatesAutoresizingMaskIntoConstraints = false

        let labelStack = UIStackView(arrangedSubviews: [titleLabel, detailLabel])
        labelStack.axis = .vertical
        labelStack.spacing = 2
        labelStack.alignment = .leading
        labelStack.translatesAutoresizingMaskIntoConstraints = false
        row.addSubview(labelStack)

        let amountLabel = UILabel()
        amountLabel.font = FontManager.shared.mediumFont(forLanguage: "en", fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.buttonText)
        amountLabel.textAlignment = .right
        amountLabel.translatesAutoresizingMaskIntoConstraints = false
        row.addSubview(amountLabel)

        if isTopup {
            let value = (transaction.paidFrom?.isEmpty == false) ? transaction.paidFrom! : "N/A"
            titleLabel.text = value

            let descEn = transaction.descriptionEn.trimmingCharacters(in: .whitespacesAndNewlines)
            let descKm = transaction.descriptionKm.trimmingCharacters(in: .whitespacesAndNewlines)
            if language.lowercased() == "en" {
                detailLabel.text = descEn.isEmpty ? B24PaymentSdkHelper.localized(TopupLocalizedKeys.topup.rawValue) : descEn
            } else {
                detailLabel.text = descKm.isEmpty ? B24PaymentSdkHelper.localized(TopupLocalizedKeys.topup.rawValue) : descKm
            }

            setLogoFill(false)
            let placeholder = UIImage(systemName: "arrow.down.backward")
            logo.loadImage(from: transaction.logo, placeholder: placeholder) { success in
                if success {
                    setLogoFill(true)
                }
            }
            logo.tintColor = nil
            amountLabel.textColor = DefaultAppearance.shared.successColor
        } else {
            let value = (transaction.paidTo?.isEmpty == false) ? transaction.paidTo! : "N/A"
            titleLabel.text = value
            detailLabel.text = language.lowercased() == "en" ? transaction.descriptionEn : transaction.descriptionKm

            setLogoFill(false)
            logo.image = UIImage(systemName: "arrow.up.left")
            logo.tintColor = DefaultAppearance.shared.dangerColor
            amountLabel.textColor = DefaultAppearance.shared.dangerColor
        }

        amountLabel.text = transaction.totalAmountDisplay

        NSLayoutConstraint.activate([
            logoBg.leadingAnchor.constraint(equalTo: row.leadingAnchor, constant: 12),
            logoBg.centerYAnchor.constraint(equalTo: row.centerYAnchor),
            logoBg.widthAnchor.constraint(equalToConstant: 40),
            logoBg.heightAnchor.constraint(equalToConstant: 40),

            labelStack.leadingAnchor.constraint(equalTo: logoBg.trailingAnchor, constant: 12),
            labelStack.centerYAnchor.constraint(equalTo: row.centerYAnchor),

            amountLabel.trailingAnchor.constraint(equalTo: row.trailingAnchor, constant: -12),
            amountLabel.centerYAnchor.constraint(equalTo: row.centerYAnchor),
            amountLabel.leadingAnchor.constraint(greaterThanOrEqualTo: labelStack.trailingAnchor, constant: 10)
        ])

        return row
    }

    // MARK: - Bottom Sheet Properties
    var transactionBottomSheet: TransactionsView?
    private var initialBottomSheetY: CGFloat = 0
    private var currentDetentState: BottomSheetDetent = .medium
    private var isHandlingBottomSheetGesture: Bool = false
    private var lastHapticDetentState: BottomSheetDetent?
    private var startedOnGrip = false
    
    enum BottomSheetDetent {
        case medium
        case large
        
        func height(for screenHeight: CGFloat) -> CGFloat {
            switch self {
            case .medium:
                return screenHeight * 0.50
            case .large:
                return screenHeight * 0.90
            }
        }
        
        func yPosition(for screenHeight: CGFloat) -> CGFloat {
            return screenHeight - height(for: screenHeight)
        }
    }
    
//    func showBottomSheet() {
//        // Instantiate your BottomSheetViewController
//        let storyboard = UIStoryboard(name: "InstantPaymentMethodView", bundle: B24PaymentSdkHelper.frameworkBundle())
//            guard let bottomSheetVC = storyboard.instantiateViewController(withIdentifier: "TransactionsView") as? TransactionsView else { return }
//        presentLegacyBottomSheet(bottomSheetVC)
//
//    }

    func showBottomSheet() {
        if transactionBottomSheet != nil { return }
        
        dismissBottomSheet()
        
        let storyboard = UIStoryboard(name: "InstantPaymentMethodView", bundle: B24PaymentSdkHelper.frameworkBundle())
        guard let bottomSheetVC = storyboard.instantiateViewController(withIdentifier: "TransactionsView") as? TransactionsView else { return }
    
        transactionBottomSheet = bottomSheetVC

        // Pass the account ID
        transactionBottomSheet?.accountId = self.paymentMethodId
        
        // Set delegate for Android-like scroll-to-collapse behavior
        transactionBottomSheet?.delegate = self
    
        presentDraggableBottomSheet(transactionBottomSheet!)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
            self?.transactionBottomSheet?.refreshInsets()
        }
        addDimBackground()
            
    }
    
    func dismissBottomSheet(){
        removeDimBackground()
        // If there's a bottom sheet and it's currently presented, dismiss it
        guard let bottomSheet = transactionBottomSheet,
              bottomSheet.isViewLoaded,
              bottomSheet.view.superview != nil else { return }

        // Capture locally so the completion doesn't clobber a newer sheet
        // that may be assigned to transactionBottomSheet before the animation ends
        let sheetToRemove = bottomSheet

        UIView.animate(withDuration: 0.3, animations: {
            sheetToRemove.view.frame.origin.y = self.view.bounds.height
        }, completion: { _ in
            sheetToRemove.view.removeFromSuperview()
            sheetToRemove.removeFromParent()
            // Only clear the reference if it still points to the sheet we just removed
            if self.transactionBottomSheet === sheetToRemove {
                self.transactionBottomSheet = nil
            }
        })
    }

    @objc private func handleBackgroundTap() {
        dismissBottomSheet()
    }

    private func addDimBackground() {
        guard let windowScene = UIApplication.shared.connectedScenes
            .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene,
            let window = windowScene.windows.first(where: { $0.isKeyWindow }) else {
            return
        }
        if window.viewWithTag(999) != nil { return }

        let dimView = UIView()
        dimView.tag = 999
        dimView.backgroundColor = UIColor.black.withAlphaComponent(0.35)
        dimView.translatesAutoresizingMaskIntoConstraints = false
        dimView.alpha = 0
        let tap = UITapGestureRecognizer(target: self, action: #selector(handleBackgroundTap))
        dimView.addGestureRecognizer(tap)

        guard let sheetView = transactionBottomSheet?.view else { return }
        window.insertSubview(dimView, belowSubview: sheetView)

        NSLayoutConstraint.activate([
            dimView.topAnchor.constraint(equalTo: window.topAnchor),
            dimView.leadingAnchor.constraint(equalTo: window.leadingAnchor),
            dimView.trailingAnchor.constraint(equalTo: window.trailingAnchor),
            dimView.bottomAnchor.constraint(equalTo: window.bottomAnchor)
        ])

        UIView.animate(withDuration: 0.25) {
            dimView.alpha = 1
        }
    }

    private func removeDimBackground() {
        guard let windowScene = UIApplication.shared.connectedScenes
            .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene,
              let window = windowScene.windows.first(where: { $0.isKeyWindow }),
              let dimView = window.viewWithTag(999) else {
            return
        }

        UIView.animate(withDuration: 0.2, animations: {
            dimView.alpha = 0
        }) { _ in
            dimView.removeFromSuperview()
        }
    }
    
   
    
    
    private func presentDraggableBottomSheet(_ bottomSheetVC: TransactionsView) {
        guard let windowScene = UIApplication.shared.connectedScenes
            .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene,
              let window = windowScene.windows.first(where: { $0.isKeyWindow }) else {
            return
        }

        let screenHeight = view.bounds.height
        let largeHeight = BottomSheetDetent.large.height(for: screenHeight)
        
        bottomSheetVC.view.frame = CGRect(
            x: 0,
            y: screenHeight,
            width: view.bounds.width,
            height: largeHeight
        )
        
        bottomSheetVC.view.layer.cornerRadius = 16
        bottomSheetVC.view.layer.masksToBounds = true
        bottomSheetVC.view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
        
        window.addSubview(bottomSheetVC.view)
        bottomSheetVC.didMove(toParent: self)
        
        setupBottomSheetGestures(for: bottomSheetVC.view)
        
        currentDetentState = .large
        animateToDetent(.large, animated: true)
        
        transactionBottomSheet?.setBottomSheetState(collapsed: false)
    }

    // MARK: - Gesture Handling

    @objc private func handleBottomSheetPan(_ gesture: UIPanGestureRecognizer) {
        guard let bottomSheetView = gesture.view else { return }
        
        let screenHeight = view.bounds.height
        let translation = gesture.translation(in: view)
        let velocity = gesture.velocity(in: view)
        
        // Check if we should handle this gesture or let the collection view handle it
        let shouldHandle = shouldHandleBottomSheetGesture(gesture: gesture, translation: translation)
        
        switch gesture.state {
        case .began:
            let location = gesture.location(in: bottomSheetView)
            startedOnGrip = location.y <= 60
            
            isHandlingBottomSheetGesture = shouldHandle
            if isHandlingBottomSheetGesture {
                initialBottomSheetY = bottomSheetView.frame.origin.y
                lastHapticDetentState = currentDetentState
            }
            
        case .changed:
            // Only continue handling if we decided to handle it at the beginning
            if !isHandlingBottomSheetGesture {
                return
            }
            
            let newY = initialBottomSheetY + translation.y
            let minY = BottomSheetDetent.large.yPosition(for: screenHeight)
            
            // Match TopUpView: allow pull-down from large to dismiss, but only
            // rubber-band upward when the drag starts from the grip area.
            let constrainedY: CGFloat
            if newY < minY {
                if startedOnGrip {
                    constrainedY = rubberBandClamp(value: newY, minValue: minY, maxValue: screenHeight)
                } else {
                    constrainedY = minY
                }
            } else {
                constrainedY = newY
            }
            let newHeight = screenHeight - constrainedY
            
            // Use CATransaction to disable implicit animations for smoother dragging
            CATransaction.begin()
            CATransaction.setDisableActions(true)
            
            bottomSheetView.frame = CGRect(
                x: 0,
                y: constrainedY,
                width: view.bounds.width,
                height: newHeight
            )
            
            CATransaction.commit()
            
            // Update grip appearance based on expansion
            updateGripAppearance(for: constrainedY, screenHeight: screenHeight)
            
            // Android-like haptic feedback when crossing detent thresholds
            checkAndTriggerHapticFeedback(for: constrainedY, screenHeight: screenHeight)
            
        case .ended:
            if isHandlingBottomSheetGesture {
                // Update insets once when gesture ends for final layout adjustment
                DispatchQueue.main.async {
                    self.transactionBottomSheet?.refreshInsets()
                }
                // Use enhanced velocity calculation for more natural physics
                let naturalVelocity = calculateNaturalVelocity(from: gesture)
                handlePanGestureEnded(velocity: naturalVelocity, currentY: bottomSheetView.frame.origin.y)
            }
            isHandlingBottomSheetGesture = false
            lastHapticDetentState = nil
            
        case .cancelled, .failed:
            isHandlingBottomSheetGesture = false
            lastHapticDetentState = nil
            
        default:
            break
        }
    }
    
    // MARK: - Haptic Feedback
    private func checkAndTriggerHapticFeedback(for yPosition: CGFloat, screenHeight: CGFloat) {
        let largeY = BottomSheetDetent.large.yPosition(for: screenHeight)

        if abs(yPosition - largeY) < 5 && lastHapticDetentState != .large {
            triggerHapticFeedback()
            lastHapticDetentState = .large
            transactionBottomSheet?.setBottomSheetState(collapsed: false)
        } else if yPosition > largeY + 50 && lastHapticDetentState == .large {
            lastHapticDetentState = nil
        }
    }
    
    private func triggerHapticFeedback() {
        // Android-like subtle haptic feedback
        if #available(iOS 13.0, *) {
            let impactFeedback = UIImpactFeedbackGenerator(style: .soft)
            impactFeedback.impactOccurred(intensity: 0.6)
        } else {
            let impactFeedback = UIImpactFeedbackGenerator(style: .light)
            impactFeedback.impactOccurred()
        }
    }
    
    private func shouldHandleBottomSheetGesture(gesture: UIPanGestureRecognizer, translation: CGPoint) -> Bool {
        guard let bottomSheetView = transactionBottomSheet?.view,
              let collectionView = transactionBottomSheet?.transactionCollectionView else {
            return true
        }
        
        let location = gesture.location(in: bottomSheetView)
        let gripAreaHeight: CGFloat = 60

        if location.y <= gripAreaHeight {
            return true
        }

        let contentOffset = collectionView.contentOffset.y
        if contentOffset <= 15 { return true }

        let contentHeight = collectionView.contentSize.height
        let frameHeight = collectionView.frame.height
        if translation.y < 0 && (contentOffset + frameHeight >= contentHeight - 15) {
            return true
        }

        return false
    }
    
    private func setupBottomSheetGestures(for bottomSheetView: UIView) {
        // Pan gesture for dragging
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handleBottomSheetPan(_:)))
        panGesture.delegate = self
        bottomSheetView.addGestureRecognizer(panGesture)
    }
    
    private func handlePanGestureEnded(velocity: CGFloat, currentY: CGFloat) {
        let screenHeight = view.bounds.height
        let largeY = BottomSheetDetent.large.yPosition(for: screenHeight)

        let dismissThreshold = largeY + (screenHeight * 0.25)

        if currentY > dismissThreshold || velocity > 1200 {
            dismissBottomSheet()
        } else {
            currentDetentState = .large
            animateToDetent(.large, animated: true)
        }
    }
    
    private func animateToDetent(_ detent: BottomSheetDetent, animated: Bool = true) {
        animateToDetentWithVelocity(detent, initialVelocity: 0, animated: animated)
    }
    
    private func animateToDetentWithVelocity(_ detent: BottomSheetDetent, initialVelocity: CGFloat = 0, animated: Bool = true) {
        guard let bottomSheetView = transactionBottomSheet?.view else { return }
        
        let screenHeight = view.bounds.height
        let targetY = detent.yPosition(for: screenHeight)
        let targetHeight = detent.height(for: screenHeight)
        
        let animations = {
            bottomSheetView.frame = CGRect(
                x: 0,
                y: targetY,
                width: self.view.bounds.width,
                height: targetHeight
            )
            self.updateGripAppearance(for: targetY, screenHeight: screenHeight)
        }
        
        let completion: (Bool) -> Void = { _ in
            self.transactionBottomSheet?.refreshInsets()
            let isCollapsed = (detent == .medium)
            self.transactionBottomSheet?.setBottomSheetState(collapsed: isCollapsed)
        }
        
        if animated {
            let currentY = bottomSheetView.frame.origin.y
            let distance = abs(targetY - currentY)
            let baseVelocity: CGFloat = max(abs(initialVelocity), 300.0)
            let duration = min(max(distance / baseVelocity, 0.25), 0.8)
            
            let dampingRatio: CGFloat = detent == .large ? 0.82 : 0.88
            let springAnimator = UIViewPropertyAnimator(duration: TimeInterval(duration), dampingRatio: dampingRatio) {
                animations()
            }
            springAnimator.addCompletion { _ in
                completion(true)
            }
            
            springAnimator.startAnimation()
        } else {
            animations()
            completion(true)
        }
    }
    
    private func rubberBandClamp(value: CGFloat, minValue: CGFloat, maxValue: CGFloat) -> CGFloat {
        // Android-like rubber band effect with progressive resistance
        if value < minValue {
            let diff = minValue - value
            let maxOverscroll: CGFloat = 100.0 // Maximum allowed overscroll upward
            let normalizedDiff = min(diff, maxOverscroll) / maxOverscroll
            
            // Progressive resistance curve - stronger resistance as you pull further
            let resistance = CGFloat(1.0 - pow(Double(normalizedDiff), 0.6))
            let rubberBandedDiff = diff * resistance * 0.25
            
            return minValue - rubberBandedDiff
        } else if value > maxValue {
            let diff = value - maxValue
            // Reduced overscroll when pulling down to prevent impression of dismissal
            let maxOverscroll: CGFloat = 80.0 // Reduced from 150 to prevent dismiss impression
            let normalizedDiff = min(diff, maxOverscroll) / maxOverscroll
            
            // Stronger resistance when pulling down to discourage excessive dragging
            let resistance = CGFloat(1.0 - pow(Double(normalizedDiff), 0.8)) // Increased from 0.7
            let rubberBandedDiff = diff * resistance * 0.3 // Reduced from 0.4
            
            return maxValue + rubberBandedDiff
        }
        return value
    }
    
    // MARK: - Enhanced Physics Simulation
    private func calculateNaturalVelocity(from gesture: UIPanGestureRecognizer) -> CGFloat {
        let velocity = gesture.velocity(in: view).y
        
        // Apply velocity decay based on distance from bounds for more natural feel
        guard let bottomSheetView = transactionBottomSheet?.view else { return velocity }
        
        let screenHeight = view.bounds.height
        let currentY = bottomSheetView.frame.origin.y
        let minY = BottomSheetDetent.large.yPosition(for: screenHeight)
        let maxY = screenHeight
        
        // Reduce velocity when near rubber band zones for smoother transitions
        if currentY < minY {
            let overscrollRatio = (minY - currentY) / 100.0
            let dampingFactor = max(0.3 as CGFloat, 1.0 - overscrollRatio * 0.7)
            return velocity * dampingFactor
        } else if currentY > maxY {
            let overscrollRatio = (currentY - maxY) / 150.0
            let dampingFactor = max(0.4 as CGFloat, 1.0 - overscrollRatio * 0.6)
            return velocity * dampingFactor
        }
        
        return velocity
    }
    
    private func updateGripAppearance(for yPosition: CGFloat, screenHeight: CGFloat) {
        let mediumHeight = BottomSheetDetent.medium.height(for: screenHeight)
        let largeHeight = BottomSheetDetent.large.height(for: screenHeight)
        let currentHeight = screenHeight - yPosition
        
        let expansionFraction = (currentHeight - mediumHeight) / (largeHeight - mediumHeight)
        let clampedFraction = max(0.0 as CGFloat, min(1.0 as CGFloat, expansionFraction))
        
        transactionBottomSheet?.updateGripAppearance(progress: clampedFraction)
    }
    
    
    // MARK:request detail
    
    private func accountDetail(){
        guard NetworkMonitor.shared.isConnected else {
            refreshControl.endRefreshing()
            if !isWaitingForConnection {
                isWaitingForConnection = true
                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }
    
        if !refreshControl.isRefreshing {
            startLoading()
        }

        AF.request(WalletRouter.instantPaymentMethodDetail(id: paymentMethodId))
            .validate().responseData{
                [self](response) in
                self.refreshControl.endRefreshing()
                switch response.result{
                case .success(let data):
                   
                    do{
                        let decodeData = try JSONDecoder().decode(ApiResponse<DataAccountDetail>.self,from: data)
                        if decodeData.code == StatusCode.succcess.rawValue{
                            
                            emptyImage.isHidden = true
                            emptyLabel.isHidden = true
                        
                            stopLoading()
                            
                            minHeight = 0.4
                            
                            dataAccountDetail = decodeData.data
                            paymentMethodId = dataAccountDetail.id
                            
                            isDefault = dataAccountDetail.isDefault
                            isInactive = dataAccountDetail.inactive
                            accountNo = dataAccountDetail.accountNo
                            DispatchQueue.main.async {
                                self.applyToolBar()
                            }
                            headerAppearance(data: dataAccountDetail)
                            contentAppearance(data: dataAccountDetail)
    
                            buttonAppearance(data: dataAccountDetail)
                            
                            topUpButtonAppearance()
                            fetchRecentTransaction()
                
                            
                            //set share Preference
                            setSharePref(pmId: dataAccountDetail.id, walletName: dataAccountDetail.accountName, walletNo: dataAccountDetail.accountNo, amount: dataAccountDetail.amountDisplay, currency: dataAccountDetail.currency)
                            
                        }else{
                            stopLoading()
                            mainScrollView.isHidden = true
                            
                            emptyImage.isHidden = false
                            emptyLabel.isHidden = false
                            
                            emptyImage.image = UIImage(systemName: emptyIconName)
                            emptyImage.tintColor = DefaultAppearance.shared.warningColor
                            emptyLabel.text = B24PaymentSdkHelper.localized(PaymentMethodWalletLocalizedKeys.emptyText.rawValue)
                            emptyLabel.textColor = DefaultAppearance.shared.primaryLabelColor
                            emptyLabel.font = FontManager.shared.regularFont(forLanguage: language ,fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.contentText)
                            
                            
                            let message = language == "en" ? decodeData.message : decodeData.messageKh
                            
                            B24PaymentSdkHelper.errorSnackbar(view: view,
                                                              message: message )
                        }
                        
                    }catch{
                        print("Decode Error: \(error)")
                    }
                case .failure(let error):
                   
                    
                    print("==>\(error)")
                    
                    stopLoading()
                    mainScrollView.isHidden = true
                    
                    if !self.isWaitingForConnection {
                        self.isWaitingForConnection = true
                        B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                            guard let self = self else { return }
                            self.isWaitingForConnection = false
                            B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                        }
                    } else {
                        emptyImage.isHidden = false
                        emptyLabel.isHidden = false
                        
                        
                        emptyImage.image = UIImage(systemName: emptyIconName)
                        emptyImage.tintColor = DefaultAppearance.shared.warningColor
                        emptyLabel.text = B24PaymentSdkHelper.localized(PaymentMethodWalletLocalizedKeys.emptyText.rawValue)
                        emptyLabel.textColor = DefaultAppearance.shared.primaryLabelColor
                        emptyLabel.font = FontManager.shared.regularFont(forLanguage: language ,fontFromconfig: DefaultAppearance.shared.fontEnglish, size: FixFontSize.contentText)
                        
                        B24PaymentSdkHelper.errorSnackbar(
                                        view: view,
                                        message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error.rawValue),
                                                            forBottomSheet: false
                                                    )
                    }
                    
                }
            }
        
    }
    
    // MARK: Set Account Default
    func setAccountDefult(){
        let payload = SetDefaultPayload(
            id: paymentMethodId)
        
        do {
            let jsonData = try JSONEncoder().encode(payload)
            guard let jsonString = String(data: jsonData, encoding: .utf8) else {
                print( "Failed to create payload")
                return
            }

            let encryptedText = try EncryptionHelper.encryptHMACAES(
                plainText: jsonString,
                secretKey: SDKVariableSetting.walletSecretKey
            )
           
            sendSetDetaultAccount(encrypt: encryptedText)

        } catch {
            print("Encryption failed: \(error.localizedDescription)")
        }
    }
    // MARK: request set detautl account
    func sendSetDetaultAccount(encrypt: String){
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }
     
        let progressDiglog = LoadingView.show(in: self)
        
        AF.request(WalletRouter.setDetault(encrypted: encrypt))
            .validate().responseData{
               response in
                switch response.result{
                    case .success(let data):
                    progressDiglog.dismiss()
                        do{
                            let decodedData = try JSONDecoder().decode(ApiResponse<WalletResponseData>.self, from: data)
                            
                            if decodedData.code == StatusCode.succcess.rawValue{
                                DispatchQueue.main.async {
                                    self.isDefault = !self.isDefault

                                    self.headerAppearance(data: self.dataAccountDetail)
                                    self.buttonAppearance(data: self.dataAccountDetail)
                                }
                            
                            }else{
                                let message = self.language == "en" ? decodedData.message : decodedData.messageKh
                                
                                B24PaymentSdkHelper.errorSnackbar(view: self.view,
                                                                  message: message )
                            }
                            
                            print("===========>\(decodedData)")
                        }catch{
                            print("Decode Error: \(error)")
                       
                        }
                    
                    case.failure(let error):
                        progressDiglog.dismiss()
                        
                        if !self.isWaitingForConnection {
                            self.isWaitingForConnection = true
                            B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                                guard let self = self else { return }
                                self.isWaitingForConnection = false
                                B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                            }
                        } else {
                            B24PaymentSdkHelper.errorSnackbar(
                                view:self.view,
                                            message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error.rawValue),
                                                                forBottomSheet: false
                                                        )
                        }
                        print("ERROR \(error)")
                }
            }
    }
    
    
    func setupSetDefualtButtonEvent(clickable:Bool){
        setDefaultButtonContainer.isUserInteractionEnabled = clickable
        let tabAction = UITapGestureRecognizer(target: self, action: #selector(setDefaultTap))
        setDefaultButtonContainer.addGestureRecognizer(tabAction)
    }
    
    @objc func setDefaultTap(){
        
        let dialog = CustomAlertView()
        
        dialog.showCustomAlert(from: self, isDefaultIcon: true, message: B24PaymentSdkHelper.localized(DialogLocalizedKeys.set_default.rawValue)) {
            self.setAccountDefult()
        } cancelHandler: {
            
        }

    }
    
    func setupDisableAccountEvent(clickable:Bool){
        
        disableContainer.isUserInteractionEnabled = clickable
        let tabAction = UITapGestureRecognizer(target: self, action: #selector(disableAccount))
        disableContainer.addGestureRecognizer(tabAction)
    }
    
    
    @objc func disableAccount(){
        
        let dialog = WarningAlertView()
        dialog.showWarningAlert(from: self) {
            self.updateAccountStatus(inactive: true)
        } cancelHandler: {
            
        }

        
    }
    
    func setupEnableAccountEvent(){
        
        disableContainer.isUserInteractionEnabled = true
        let tabAction = UITapGestureRecognizer(target: self, action: #selector(enableAccount))
        disableContainer.addGestureRecognizer(tabAction)
    }
    
    
    @objc func enableAccount(){
       let dialog = CustomAlertView()
        dialog.showCustomAlert(from: self, isDefaultIcon: false, message: B24PaymentSdkHelper.localized(DialogLocalizedKeys.enable.rawValue)) {
            self.updateAccountStatus(inactive: false)
        } cancelHandler: {
            
        }

        
    }
    
    func updateAccountStatus(inactive:Bool){
        let payload = UpdateStatus(
            id: paymentMethodId,
            inactive: inactive)
        
        do {
            let jsonData = try JSONEncoder().encode(payload)
            guard let jsonString = String(data: jsonData, encoding: .utf8) else {
                print("Failed to create payload")
                return
            }

            let encryptedText = try EncryptionHelper.encryptHMACAES(
                plainText: jsonString,
                secretKey: SDKVariableSetting.walletSecretKey
            )
           
            sendUpdateStatus(encrypt: encryptedText,inactive: inactive)

        } catch {
            print("Encryption failed: \(error.localizedDescription)")
        }
        
        
    }
    
    //MARK: request update status
    func sendUpdateStatus(encrypt:String,inactive:Bool){
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }
        let progressDiglog = LoadingView.show(in: self)
        
        AF.request(WalletRouter.updateStatus(encrypted: encrypt))
            .validate().responseData{
               response in
                switch response.result{
                    case .success(let data):
                    progressDiglog.dismiss()
                        do{
                            let decodedData = try JSONDecoder().decode(ApiResponse<WalletResponseData>.self, from: data)
                            
                            if decodedData.code == StatusCode.succcess.rawValue{
                                DispatchQueue.main.async {
                                    //self.isDefault = false
                                    self.isInactive = inactive
                                    
                                    self.headerAppearance(data: self.dataAccountDetail)
                                    self.buttonAppearance(data: self.dataAccountDetail)
                                }
                            }else{
                                let message = self.language == "en" ? decodedData.message : decodedData.messageKh
                                
                                B24PaymentSdkHelper.errorSnackbar(view: self.view,
                                                                  message: message )
                            }
                            
                
                        }catch{
                            print("Decode Error: \(error)")
                       
                        }
                    
                    case.failure(let error):
                        progressDiglog.dismiss()
                        
                        if !self.isWaitingForConnection {
                            self.isWaitingForConnection = true
                            B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                                guard let self = self else { return }
                                self.isWaitingForConnection = false
                                B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                            }
                        } else {
                            B24PaymentSdkHelper.errorSnackbar(
                                view:self.view,
                                            message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error.rawValue),
                                                                forBottomSheet: false
                                                        )
                        }
                        print("ERROR \(error)")
                }
            }
    }
    
    
    
    func setupModifyName(){
        iconEdit.isUserInteractionEnabled = true
        let tabAction = UITapGestureRecognizer(target: self, action: #selector(modifyNameTapped))
        iconEdit.addGestureRecognizer(tabAction)
    }
    
    @objc func modifyNameTapped(){
        
        if isInactive{
            let dialog = WarningAlertView()
            dialog.showWarningTopupAlert(from: self) {
                self.updateAccountStatus(inactive: false)
            } cancelHandler: {
                
            }

        }else{
//            let dialog = EditDialog()
//            dialog.showEditDialog(from: self) { inputText in
//                self.modifyName(name: inputText)
//            } cancelHandler: {
//                
//            }

            let dialog = EditDialog()
              dialog.showEditDialog(
                  from: self,
                  defaultText: self.currentDisplayedAccountName()
              ) { inputText in
                  self.modifyName(name: inputText)
              } cancelHandler: {

              }
        }
    }
    
    func modifyName(name:String){
        
        
        let payload = ModifyNamePayload(id: paymentMethodId, name: name)
        
        do {
            let jsonData = try JSONEncoder().encode(payload)
            guard let jsonString = String(data: jsonData, encoding: .utf8) else {
               print("Failed to create payload")
                return
            }

            let encryptedText = try EncryptionHelper.encryptHMACAES(
                plainText: jsonString,
                secretKey: SDKVariableSetting.walletSecretKey
            )
           
            sendModifyRequest(encrypt: encryptedText,name: name)

        } catch {
            print( "Encryption failed: \(error.localizedDescription)")
        }
    }
    
    //MARK: requst modify name
    func sendModifyRequest(encrypt:String,name:String){
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                    guard let self = self else { return }
                    self.isWaitingForConnection = false
                    B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                }
            }
            return
        }
        let progressDiglog = LoadingView.show(in: self)
        
        AF.request(WalletRouter.modifyWalletName(encrypted: encrypt))
            .validate().responseData{
               response in
                switch response.result{
                    case .success(let data):
                    progressDiglog.dismiss()
                        do{
                            let decodedData = try JSONDecoder().decode(ApiResponse<WalletResponseData>.self, from: data)
                            
                            if decodedData.code == StatusCode.succcess.rawValue{
                                self.lblTitle.text = name
                                // Also update programmatic card name label
                                if let cardNameLabel = self.containerHeader.viewWithTag(2010) as? UILabel {
                                    cardNameLabel.text = name
                                }
                            }else{
                                let message = self.language == "en" ? decodedData.message : decodedData.messageKh
                                
                                B24PaymentSdkHelper.errorSnackbar(view: self.view,
                                                                  message: message )
                            }
                            
                            print("===========>\(decodedData)")
                        }catch{
                            print("Decode Error: \(error)")
                       
                        }
                    
                    case.failure(let error):
                        progressDiglog.dismiss()
                        
                        if !self.isWaitingForConnection {
                            self.isWaitingForConnection = true
                            B24PaymentSdkHelper.showNoInternetPopup(on: self) { [weak self] in
                                guard let self = self else { return }
                                self.isWaitingForConnection = false
                                B24PaymentSdkHelper.hideNoInternetPopup(from: self, showSuccess: false)
                            }
                        } else {
                            B24PaymentSdkHelper.errorSnackbar(
                                view: self.view,
                                            message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error.rawValue),
                                                                forBottomSheet: false
                                                        )
                        }
                        print("ERROR \(error)")
                }
            }
    }
   
    
    private func setSharePref(pmId:String,walletName:String,walletNo:String,amount:String,currency:String){
        SharedPreferenceManager.set(value: pmId, forKey: SharePrefKey.paymentMethodId.rawValue)
        SharedPreferenceManager.set(value: walletName, forKey: SharePrefKey.walletName.rawValue)
        SharedPreferenceManager.set(value: walletNo, forKey: SharePrefKey.walletNo.rawValue)
        SharedPreferenceManager.set(value: amount, forKey: SharePrefKey.balance.rawValue)
        SharedPreferenceManager.set(value: currency, forKey: SharePrefKey.currency.rawValue)

    }
    
}


// MARK: - Account Detail View Extension
//extension AccountDetailView {
//
//    // MARK: - Setup Methods
//    private func setupLoadingIndicator() {
//        view.addSubview(loadingIndicator)
//        NSLayoutConstraint.activate([
//            loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
//            loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor)
//        ])
//    }
//
//    private func updateLoadingState() {
//        DispatchQueue.main.async {
//            if self.isLoading {
//                self.loadingIndicator.startAnimating()
//                self.contentContainer.isHidden = true
//            } else {
//                self.loadingIndicator.stopAnimating()
//                self.contentContainer.isHidden = false
//            }
//        }
//    }
    

    // MARK: - API Methods
//    func fetchAccountDetail(accountId: String) {
//        isLoading = true
//
//        let url = APIManager.merchantApiUrl().appendingPathComponent("instantpaymentsdk/payment_method/detail")
//        let parameters: [String: Any] = ["id": accountId]
//
//        AF.request(
//            url,
//            method: .post,
//            parameters: parameters,
//            encoding: JSONEncoding.default,
//            headers: APIManager.initHeader()
//        )
//        .validate()
//        .responseDecodable(of: ApiResponse<DataAccountDetail>.self) { [weak self] response in
//            guard let self = self else { return }
//            self.isLoading = false
//
//            switch response.result {
//            case .success(let apiResponse):
//                self.handleSuccessResponse(apiResponse)
//            case .failure(let error):
//                self.handleError(error)
//            }
//        }
//    }

    // MARK: - Response Handlers
//    private func handleSuccessResponse(_ apiResponse: ApiResponse<DataAccountDetail>) {
//        if apiResponse.code == "SUCCESS" {
//            DispatchQueue.main.async {
//                self.updateUI(with: apiResponse.data)
//            }
//        } else {
//            showError(message: apiResponse.message)
//        }
//    }

//    private func handleError(_ error: AFError) {
//        let errorMessage: String
//        switch error {
//        case .responseValidationFailed(let reason):
//            errorMessage = "Validation failed: \(reason)"
//        case .responseSerializationFailed(let reason):
//            errorMessage = "Failed to process response: \(reason)"
//        case .sessionTaskFailed(let error):
//            errorMessage = "Network error: \(error.localizedDescription)"
//        default:
//            errorMessage = "An unexpected error occurred"
//        }
//        showError(message: errorMessage)
//    }

    // MARK: - UI Updates
//    private func updateUI(with data: DataAccountDetail) {
//        self.dataAccountDetail = data
//
//        headerAppearance(data: data)
//        contentAppearance(data: data)
//        buttonAppearance(data: data)
//
//        // Update logo if available
//        if !data.logo.isEmpty {
//            loadLogo(from: data.logo)
//        }
//    }

//    private func loadLogo(from urlString: String) {
//        guard let url = URL(string: urlString) else { return }
//
//        DispatchQueue.global().async {
//            if let data = try? Data(contentsOf: url),
//               let image = UIImage(data: data) {
//                DispatchQueue.main.async {
//                    self.logo.image = image
//                }
//            }
//        }
//    }

    // MARK: - Error Handling
//    private func showError(message: String) {
//        DispatchQueue.main.async {
//            let alert = UIAlertController(
//                title: "Error",
//                message: message,
//                preferredStyle: .alert
//            )
//            alert.addAction(UIAlertAction(title: "OK", style: .default))
//            self.present(alert, animated: true)
//        }
//    }
//}

// MARK: - View Controller Lifecycle
//extension AccountDetailView {
//    private func setupInitialUI() {
//        view.backgroundColor = DefaultAppearance.shared.screenBgColor
//        getSharePref()
//        B24PaymentSdkHelper.getCurrentLanguage(language: language)
//        showBottomSheet()
//
//        // Setup initial state with default data
//        headerAppearance(data: dataAccountDetail)
//        contentAppearance(data: dataAccountDetail)
//        buttonAppearance(data: dataAccountDetail)
//        topUpButtonAppearance()
//    }
//}

// MARK: - UIGestureRecognizerDelegate
extension AccountDetailView {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        // Additional touch filtering for better gesture handling
        if gestureRecognizer is UIPanGestureRecognizer {
            let location = touch.location(in: view)
            
            // If touch is outside bottom sheet, don't handle it
            if let bottomSheetView = transactionBottomSheet?.view {
                let sheetFrame = bottomSheetView.frame
                if !sheetFrame.contains(location) {
                    return false
                }
            }
        }
        
        // For tap gestures, only handle if it's the background tap
        if gestureRecognizer is UITapGestureRecognizer {
            // Don't handle tap if it's inside the bottom sheet
            if let bottomSheetView = transactionBottomSheet?.view {
                let location = touch.location(in: view)
                return !bottomSheetView.frame.contains(location)
            }
        }
        
        return true
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        // Be more selective about simultaneous recognition to avoid conflicts
        
        // If this is a pan gesture from the bottom sheet
        if gestureRecognizer is UIPanGestureRecognizer && gestureRecognizer.view == transactionBottomSheet?.view {
            // Only allow simultaneous recognition with scroll views when they're different types of gestures
            // or when we're in specific scroll conditions
            if let scrollView = otherGestureRecognizer.view as? UIScrollView {
                let panGesture = gestureRecognizer as! UIPanGestureRecognizer
                let translation = panGesture.translation(in: view)
                
                // Allow simultaneous recognition only if our custom logic says we should handle the gesture
                return shouldHandleBottomSheetGesture(gesture: panGesture, translation: translation)
            }
            return false
        }
        
        // For other gestures, allow simultaneous recognition
        return true
    }
}

// MARK: - TransactionsViewDelegate
extension AccountDetailView {
    func shouldCollapseBottomSheet() {
        dismissBottomSheet()
    }
    
    func shouldExpandBottomSheet() {
        guard currentDetentState == .medium else { return }
        currentDetentState = .large
        animateToDetent(.large, animated: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            self.transactionBottomSheet?.setBottomSheetState(collapsed: false)
        }
        triggerHapticFeedback()
    }
}
