//
//  KHQRView.swift
//  Bill24OnlinePaymentSdk
//
//  Created by MacbookPro on 23/10/23.
//

import Foundation
import UIKit
import Alamofire

public class KHQRView : UIView{
    @IBOutlet weak var khqrView: UIView!
    @IBOutlet weak var khqrContainer: UIView!
    @IBOutlet weak var khqrHeaderContainer: UIView!
    @IBOutlet weak var downloadButton: UIView!
    @IBOutlet weak var shareButton: UIView!
    @IBOutlet weak var countDownLabel: UILabel!
    @IBOutlet weak var orLabel: UILabel!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    @IBOutlet weak var orViewLabel: UIView!
    @IBOutlet weak var dotLineView: DottedLineView!
    @IBOutlet weak var downloadLabel: UILabel!
    @IBOutlet weak var shareLabel: UILabel!
    
    @IBOutlet weak var shareIcon: UIImageView!
    @IBOutlet weak var downloadIcon: UIImageView!
    @IBOutlet weak var scanToPayLabel: UILabel!
    @IBOutlet weak var displayAccountBillerName: UILabel!
    @IBOutlet weak var currencyLabel: UILabel!
    @IBOutlet weak var totalAmountDisplay: UILabel!
    @IBOutlet weak var currencyIcon: UIImageView!
    @IBOutlet weak var khqrImageView: UIImageView!
    private let countdownManager = CountdownManager()
    private var expireDateResponse: ExtendExpireDateResponse?
    private var khqrMainView: UIView!
    private var  centerLoading = UIActivityIndicatorView(style: .large)
    private var stackView : UIStackView!
    private var dismissButton: UIButton!
    private var retryButton: UIButton!
    private var backButton: UIButton!
    private var errorLabel: UILabel!
    
    var transactionId: String = ""
    var controller: UIViewController!
    var transactionData: Transaction?
    private var bottomSheetController: BottomSheetViewController?
    private var alreadyCalledVerify = false
    private var isWaitingForConnection: Bool = false
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initSubviews()
    }
    
    init(frame: CGRect, transactionId: String, controller: UIViewController, transactionData: Transaction, bottomSheetController: BottomSheetViewController) {
        self.transactionId = transactionId
        self.controller = controller
        self.transactionData = transactionData
        self.bottomSheetController = bottomSheetController
        super.init(frame: frame)
        initSubviews()
    }
    
    private func initSubviews() {
        registerView()
        setUpDataToKhqrView()
        setUpConstraintAndStyle()
        setUpFont()
        setUpTheme()
        setUpTranslate()
        extendExpiredTransactionApi()
        
        downloadButton.isUserInteractionEnabled = true
        downloadButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(downloadImage)))
        
        shareButton.isUserInteractionEnabled = true
        shareButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(shareImage)))
        
        // Set up dismiss button
        setupDismissButton()
    }
    
    private func registerView(){
        let nib = UINib(
            nibName: "KHQRView",
            bundle: B24PaymentSdkHelper.frameworkBundle()
        )
        
        guard let view = nib.instantiate(withOwner: self, options: nil).first as?
                UIView else {fatalError("Unable to convert nib")}
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        khqrMainView = view
        addSubview(view)
        
        // Configure the activity indicator
        centerLoading.translatesAutoresizingMaskIntoConstraints = false
        centerLoading.hidesWhenStopped = true
        centerLoading.color = UIColor.systemBlue
        view.addSubview(centerLoading)
        
        NSLayoutConstraint.activate([
            centerLoading.centerXAnchor.constraint(equalTo: khqrView.centerXAnchor),
            centerLoading.centerYAnchor.constraint(equalTo: khqrView.centerYAnchor)
        ])
        
        // Config Error View for Extend Expire Endpoint
        // Create UIImageView for the image
        let imageView = UIImageView(image: UIImage(named: "expire_icon",  in: B24PaymentSdkHelper.frameworkBundle(),compatibleWith: nil))
        imageView.contentMode = .center
        imageView.widthAnchor.constraint(equalToConstant: 60).isActive = true
        imageView.heightAnchor.constraint(equalToConstant: 60).isActive = true

        // Create UILabel for the text
        errorLabel = UILabel()
        errorLabel.text = B24PaymentSdkHelper.localized("error")
        errorLabel.textAlignment = .center
        errorLabel.font =  FontManager.shared.regularFont(forLanguage: SDKVariableSetting.currentLanguage, size: 15.0)
        errorLabel.textColor = UIColor(hex: Themes.Property.secondaryTextColor)
        errorLabel.numberOfLines = 0

        // Create Retry Button
        retryButton = UIButton(type: .system)
        retryButton.setTitle(B24PaymentSdkHelper.localized("retry"), for: .normal)
        retryButton.titleLabel?.font = FontManager.shared.mediumFont(forLanguage: SDKVariableSetting.currentLanguage, size: 14.0)
        retryButton.setTitleColor(UIColor(hex: Themes.Property.actionButtonTextColor), for: .normal)
        retryButton.backgroundColor = UIColor(hex: Themes.Property.actionButtonBackgroundColor)
        retryButton.layer.cornerRadius = 8
        retryButton.contentEdgeInsets = UIEdgeInsets(top: 8, left: 24, bottom: 8, right: 24)
        retryButton.addTarget(self, action: #selector(retryAction), for: .touchUpInside)


        // Create Button Stack
        let buttonStack = UIStackView(arrangedSubviews: [retryButton])
        buttonStack.axis = .horizontal
        buttonStack.alignment = .center
        buttonStack.distribution = .fill
        buttonStack.spacing = 12

        // Create UIStackView
        stackView = UIStackView(arrangedSubviews: [imageView, errorLabel, buttonStack])
        stackView.axis = .vertical
        stackView.alignment = .center
        stackView.distribution = .fill
        stackView.spacing = 16

        // Add the stack view to your main view or another container view
        view.addSubview(stackView)

        // Set constraints for the stack view
        stackView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: khqrView.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: khqrView.centerYAnchor),
        ])
        
        // Set up buttons 
        setupBackButton()
        
        self.layoutIfNeeded()
       
        self.showCenterLoading()
        self.backgroundColor = UIColor(hex: Themes.Property.secondaryBackgroundColor)

        print("*** Load KHQR View ***")
    }
    
    // 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

                // Auto-retry the last failed action (extend API or verify API)
                self.retryAction()
            }
        }
    }
    
    private func setupDismissButton() {
        // Create dismiss button
        dismissButton = UIButton(type: .system)
        let config = UIImage.SymbolConfiguration(pointSize: 14, weight: .bold)
        dismissButton.setImage(UIImage(systemName: "xmark", withConfiguration: config), for: .normal)
        dismissButton.layer.cornerRadius = 14
        dismissButton.layer.borderWidth = 1
        dismissButton.clipsToBounds = true
        dismissButton.translatesAutoresizingMaskIntoConstraints = false
        dismissButton.addTarget(self, action: #selector(dismissBottomSheet), for: .touchUpInside)
        
        // Add button to the main view
        khqrMainView.addSubview(dismissButton)
        
        // Set up constraints
        NSLayoutConstraint.activate([
            dismissButton.centerYAnchor.constraint(equalTo: countDownLabel.centerYAnchor),
            dismissButton.trailingAnchor.constraint(equalTo: khqrMainView.trailingAnchor, constant: -14),
            dismissButton.widthAnchor.constraint(equalToConstant: 28),
            dismissButton.heightAnchor.constraint(equalToConstant: 28)
        ])

        applyNavigationButtonTheme(dismissButton)
    }
    
    @objc private func dismissBottomSheet() {
        bottomSheetController?.dismissBottomSheet()
    }
    
    private func setupBackButton() {
        // Create back button
        backButton = UIButton(type: .system)
        backButton.translatesAutoresizingMaskIntoConstraints = false
        backButton.layer.cornerRadius = 14
        backButton.layer.borderWidth = 1
        backButton.clipsToBounds = true
        
        // Image
        let config = UIImage.SymbolConfiguration(pointSize: 12, weight: .bold)
        backButton.setImage(UIImage(systemName: "chevron.backward", withConfiguration: config), for: .normal)
        backButton.addTarget(self, action: #selector(backAction), for: .touchUpInside)

        // Add button to the main view
        khqrMainView.addSubview(backButton)
        
        // Set up constraints to position it at the top left, aligned with dismiss button
        NSLayoutConstraint.activate([
            backButton.centerYAnchor.constraint(equalTo: countDownLabel.centerYAnchor),
            backButton.leadingAnchor.constraint(equalTo: khqrMainView.leadingAnchor, constant: 14),
            backButton.widthAnchor.constraint(equalToConstant: 28),
            backButton.heightAnchor.constraint(equalToConstant: 28)
        ])

        applyNavigationButtonTheme(backButton)
    }

    private func applyNavigationButtonTheme(_ button: UIButton) {
        let backgroundColor = SDKVariableSetting.isDarkMode ? UIColor(hex: "#2C2C2E") : UIColor(hex: "#F3F4F6")
        let borderColor = SDKVariableSetting.isDarkMode ? UIColor(hex: "#3A3A3C") : UIColor(hex: "#E5E7EB")

        button.backgroundColor = backgroundColor
        button.layer.borderColor = borderColor.cgColor
        button.tintColor = UIColor(hex: Themes.Property.labelTextColor)
    }
    
    private func setUpTranslate(){
        scanToPayLabel.text = B24PaymentSdkHelper.localized(KhqrLocalizedKeys.scanToPay.rawValue)
        downloadLabel.text = B24PaymentSdkHelper.localized(LocalizedKeys.download.rawValue)
        shareLabel.text = B24PaymentSdkHelper.localized(LocalizedKeys.share.rawValue)
        orLabel.text = B24PaymentSdkHelper.localized(KhqrLocalizedKeys.or.rawValue)
    }
    
    private func setUpTheme(){
        scanToPayLabel.textColor = UIColor(hex: Themes.Property.primaryTextColor)
        orLabel.textColor =  UIColor(hex: Themes.Property.primaryTextColor)
        dotLineView.tintColor = UIColor(hex: Themes.Property.indicatorColor)
        downloadLabel.textColor = UIColor(hex: Themes.Property.primaryTextColor)
        shareLabel.textColor = UIColor(hex: Themes.Property.primaryTextColor)
        downloadButton.backgroundColor = UIColor(hex: Themes.Property.actionButtonBackgroundColor)
        downloadIcon.tintColor = UIColor(hex: Themes.Property.actionButtonTextColor)
        shareIcon.tintColor = UIColor(hex: Themes.Property.actionButtonTextColor)
        shareButton.backgroundColor = UIColor(hex: Themes.Property.actionButtonBackgroundColor)
        countDownLabel.textColor = UIColor(hex: Themes.Property.primaryTextColor)
        activityIndicator.color = UIColor(hex: Themes.Property.indicatorColor)
        orViewLabel.backgroundColor = UIColor(hex: Themes.Property.secondaryBackgroundColor)
        khqrMainView.backgroundColor = UIColor(hex: Themes.Property.secondaryBackgroundColor)
        self.backgroundColor = UIColor(hex: Themes.Property.secondaryBackgroundColor)
        currencyLabel.textColor =  UIColor(named: "text_primary_color", in: B24PaymentSdkHelper.frameworkBundle(), compatibleWith: nil)
        displayAccountBillerName.textColor =  UIColor(named: "text_primary_color", in: B24PaymentSdkHelper.frameworkBundle(), compatibleWith: nil)
        totalAmountDisplay.textColor = UIColor(named: "text_primary_color", in: B24PaymentSdkHelper.frameworkBundle(), compatibleWith: nil)

        // Apply theme to buttons if they exist
        if dismissButton != nil {
            applyNavigationButtonTheme(dismissButton)
        }
        if backButton != nil {
            applyNavigationButtonTheme(backButton)
        }
    }
    
    private func setUpFont(){
        // Surrounding UI — language-dependent (Battambang for km, Roboto for en)
        countDownLabel.font = FontManager.shared.regularFont(forLanguage: SDKVariableSetting.currentLanguage, size: 13.0)
        scanToPayLabel.font = FontManager.shared.regularFont(forLanguage: SDKVariableSetting.currentLanguage, size: 15.0)
        orLabel.font = FontManager.shared.regularFont(forLanguage: SDKVariableSetting.currentLanguage, size: 13.0)
        downloadLabel.font = FontManager.shared.regularFont(forLanguage: SDKVariableSetting.currentLanguage, size: 13.0)
        shareLabel.font = FontManager.shared.regularFont(forLanguage: SDKVariableSetting.currentLanguage, size: 13.0)

        // KHQR card — NunitoSans hardcoded, language-independent
        // Fallback to system font with matching weight if custom font fails to load
        displayAccountBillerName.font = B24PaymentSdkHelper.setFontKhqr(named: "NunitoSans_7pt-SemiBold", ofSize: 9.0)
            ?? UIFont.systemFont(ofSize: 9.0, weight: .semibold)
        currencyLabel.font = B24PaymentSdkHelper.setFontKhqr(named: "NunitoSans_7pt-SemiBold", ofSize: 8.0)
            ?? UIFont.systemFont(ofSize: 8.0, weight: .medium)
        totalAmountDisplay.font = B24PaymentSdkHelper.setFontKhqr(named: "NunitoSans_7pt-ExtraBold", ofSize: 17.0)
            ?? UIFont.systemFont(ofSize: 17.0, weight: .bold)
    }
    
    private func showCenterLoading(){
        stackView.isHidden = true
        startLoading(view: self)
        khqrView.isHidden = true
        scanToPayLabel.isHidden = true
        downloadButton.isHidden = true
        shareButton.isHidden = true
        downloadLabel.isHidden = true
        shareLabel.isHidden = true
        activityIndicator.isHidden = true
        countDownLabel.isHidden = true
        orViewLabel.isHidden = true
        dotLineView.isHidden = true
        dismissButton?.isHidden = true
    }
    
    private func hideCenterLoading(){
        stopLoading(view: self)
        khqrView.isHidden = false
        scanToPayLabel.isHidden = false
        downloadButton.isHidden = false
        shareButton.isHidden = false
        downloadLabel.isHidden = false
        shareLabel.isHidden = false
        activityIndicator.isHidden = false
        countDownLabel.isHidden = false
        orViewLabel.isHidden = false
        dotLineView.isHidden = false
        dismissButton?.isHidden = false
        backButton?.isHidden = false
    }
    
    private func startLoading(view: UIView) {
        centerLoading.startAnimating()
    }
    private func stopLoading(view: UIView) {
        centerLoading.stopAnimating()
    }
    
    private func showErrorUI(message: String? = nil) {
        stopLoading(view: self)
        stackView.isHidden = false
        
        if let msg = message {
            errorLabel.text = msg
        } else {
            errorLabel.text = B24PaymentSdkHelper.localized("error")
        }
        
        khqrView.isHidden = true
        scanToPayLabel.isHidden = true
        downloadButton.isHidden = true
        shareButton.isHidden = true
        downloadLabel.isHidden = true
        shareLabel.isHidden = true
        activityIndicator.isHidden = true
        countDownLabel.isHidden = true
        orViewLabel.isHidden = true
        dotLineView.isHidden = true
        dismissButton?.isHidden = false
        backButton?.isHidden = false
    }
    
    private func hideErrorUI() {
        stackView.isHidden = true
    }
    
    @objc func shareImage(){
        let image = khqrView.saveAsImage()
        let billerNameDisplay = (transactionData?.data?.biller.billerName) ?? (transactionData?.data?.biller.billerNameKh)
        let amountDisplay = (transactionData?.data?.transInfo.totalAmountDisplay) ?? ""
        let currencyDisplay = (transactionData?.data?.transInfo.currency) ?? ""
        let imageName = "\(billerNameDisplay ?? "")-\(amountDisplay) \(currencyDisplay).png"
        // Get the URL for the documents directory
        if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
            // Append the custom image name to the documents directory URL
            let fileURL = documentsDirectory.appendingPathComponent(imageName)
            
            // Save the image to the specified URL
            if let data = image.pngData() {
                do {
                    try data.write(to: fileURL)
                    let items: [Any] = [imageName,image]
                    let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
                    activityViewController.popoverPresentationController?.sourceView = self
                    activityViewController.popoverPresentationController?.sourceRect = CGRect(x: self.bounds.midX, y: self.bounds.midY, width: 0, height: 0)
                    if let viewController = self.getViewController() {
                        viewController.present(activityViewController, animated: true, completion: nil)
                    }
                } catch {
                    print("Error saving image: \(error)")
                }
            }
        }
    }
    
    private func getViewController() -> UIViewController? {
        var responder: UIResponder? = self
        while let nextResponder = responder?.next {
            if let viewController = nextResponder as? UIViewController {
                return viewController
            }
            responder = nextResponder
        }
        return nil
    }
    
    @objc func downloadImage(){
        let image = khqrView.saveAsImage()
        saveImageToPhotoLibrary(image: image)
    }
    
    private func saveImageToPhotoLibrary(image: UIImage) {
        UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
    }
    
    @objc func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
        if let error = error {
            print(error)
            B24PaymentSdkHelper.errorSnackbar(
                view: self,
                message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.error.rawValue),
                forBottomSheet: true
            )
        } else {
            B24PaymentSdkHelper.successSnackbar(
                view: self,
                message: B24PaymentSdkHelper.localized(SnackBarLocalizedKeys.saveKhqr.rawValue),
                forBottomSheet: true
            )
        }
    }
    
    private func setUpDataToKhqrView(){
        let data = transactionData?.data
        khqrImageView.loadQRImage(from: data?.transInfo.khqrString.data(using: .utf8))
        displayAccountBillerName.text = data?.biller.billerDisplayName
        totalAmountDisplay.text = data?.transInfo.totalAmountDisplay
        currencyLabel.text = data?.transInfo.currency
     
        // Display KHQR Currency base on currency
        if(data?.transInfo.currency.lowercased() == "khr"){
            currencyIcon.image = UIImage(named: "khr_currency" ,in: B24PaymentSdkHelper.frameworkBundle(), compatibleWith: nil)
        }else{
            currencyIcon.image = UIImage(named: "usd_currency" ,in: B24PaymentSdkHelper.frameworkBundle(), compatibleWith: nil)
        }
        
       
    }
    
    @objc private func retryAction() {
        // Check Network Connection
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()
            }
            showErrorUI(message: B24PaymentSdkHelper.localized("msg_error_connect"))
            return
        }
        
        hideErrorUI()
        isWaitingForConnection = false
        showCenterLoading()
        extendExpiredTransactionApi()
    }
    
    @objc private func backAction() {
        // Directly swap back to PaymentMethodView without dismissing the bottom sheet
        guard let bottomSheet = bottomSheetController else { return }
        
        // Remove current KHQR view from container
        self.removeFromSuperview()
        
        // Create PaymentMethodView
        let paymentView = PaymentMethodView(
            frame: controller.view.frame,
            controller: controller,
            transactionId: transactionId,
            bottomSheetController: bottomSheet,
            transaction: transactionData
        )
        
        // Add PaymentMethodView to the same bottom sheet container
        bottomSheet.bottomSheetContainerView.addSubview(paymentView)
        
        // Notify bottom sheet about the stationary view
        bottomSheet.notifyStationaryViewAdded()
        
        // Update view type and animate the height change
        bottomSheet.viewType = .ninetyPercent
        UIView.animate(withDuration: 0.3) {
            bottomSheet.updateViewConstraints()
            bottomSheet.view.layoutIfNeeded()
        }
    }
    
    private func extendExpiredTransactionApi(){
        // Check Network Connection
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()
            }
            showErrorUI(message: B24PaymentSdkHelper.localized("msg_error_connect"))
            return
        }

        AF.request(CheckoutRouter.updateTransactionExpire(transactionId: transactionId)).validate().responseData{
            [self] response in
            switch response.result{
            case .success(let data):
                expireDateResponse = try? JSONDecoder().decode(ExtendExpireDateResponse.self, from: data)
                if(expireDateResponse?.code == "SUCCESS"){
                    // Call requestVeriftyTransaction to verify and setup KHQR
                    self.requestVeriftyTransaction()
                }else{
                    showErrorUI()
                }
            case .failure(let error):
                print(error)
                if error.isSessionTaskError {
                    if !isWaitingForConnection {
                        isWaitingForConnection = true
                        setupNetworkMonitoring()
                        NetworkMonitor.shared.startMonitoring()
                    }
                    showErrorUI(message: B24PaymentSdkHelper.localized("msg_error_connect"))
                } else {
                    showErrorUI()
                }
            }
        }
    }
    
    // Removed SharedPreference approach - now using TopUpView.isTopUpTransaction static variable 
    private func requestVeriftyTransaction() {
        // Check Network Connection
        guard NetworkMonitor.shared.isConnected else {
            if !isWaitingForConnection {
                isWaitingForConnection = true
                setupNetworkMonitoring()
                NetworkMonitor.shared.startMonitoring()
            }
            showErrorUI(message: B24PaymentSdkHelper.localized("msg_error_connect"))
            return
        }

        AF.request(CheckoutRouter.checkoutDetail(transactionId: transactionId)).validate().responseData { response in
            switch response.result {
            case .success(let data):
                let transaction = try? JSONDecoder().decode(Transaction.self, from: data)
                
                if transaction?.code == "SUCCESS" {                        
                    // Update transaction data with new KHQR information
                    self.transactionData = transaction
                    
                    // Update KHQR display with new data
                    self.setUpDataToKhqrView()
                    
                    // Setup KHQR with countdown
                    let secondRemainingTime = self.calculateSessionExpire(expireDate: (transaction?.data?.transInfo.expiredDate)!)
                    if(secondRemainingTime > 3600){
                        // second grater than 1 hour
                        self.countDownLabel.isHidden = true
                        self.activityIndicator.isHidden = true
                        self.dismissButton?.isHidden = false // Keep dismiss button visible even when countdown is hidden
                    }else{
                        self.countDownLabel.isHidden = false
                        self.activityIndicator.isHidden = false
                        self.dismissButton?.isHidden = false
                        self.updateCountdown(seconds: secondRemainingTime)
                    }
                    self.hideCenterLoading()
                } else {
                    let message = (transaction?.code == "UNABLE_CONNECT") ? B24PaymentSdkHelper.localized("msg_error_connect") : (SDKVariableSetting.currentLanguage.lowercased() == "en" ? transaction?.message : transaction?.messageKh)
                    
                    self.showErrorUI(message: message)
                    
                    // Show snackbar on the superview (bottomSheetContainerView) to ensure visibility
                    if let parentView = self.superview {
                        B24PaymentSdkHelper.errorSnackbar(
                            view: parentView,
                            message: message ?? B24PaymentSdkHelper.localized("error"),
                            forBottomSheet: false
                        )
                    }
                }
                
            case .failure(let error):
                print(error)
                if error.isSessionTaskError {
                    if !self.isWaitingForConnection {
                        self.isWaitingForConnection = true
                        self.setupNetworkMonitoring()
                        NetworkMonitor.shared.startMonitoring()
                    }
                    self.showErrorUI(message: B24PaymentSdkHelper.localized("msg_error_connect"))
                } else {
                    self.showErrorUI()
                    
                    // Show snackbar on the superview (bottomSheetContainerView) to ensure visibility
                    if let parentView = self.superview {
                        B24PaymentSdkHelper.errorSnackbar(
                            view: parentView,
                            message: B24PaymentSdkHelper.localized("error"),
                            forBottomSheet: false
                        )
                    }
                }
            }
        }
    }

    private func calculateSessionExpire(expireDate: String) -> Int {
        var secondRemain: Int = 0
        if let expireDate = B24PaymentSdkHelper.formateStringToDate(expireDate, format: "yyyy-MM-dd HH:mm:ss") {
            let currentDate = Date()
            secondRemain = Int(expireDate.timeIntervalSince(currentDate))
        } else {
            print("Invalid date string")
        }
        
        return secondRemain
    }
    
    private func updateCountdown(seconds: Int) {
        countdownManager.startCountdown(seconds: seconds, updateLabel: { [weak self] timeString in
            self?.countDownLabel.text = timeString
            self?.activityIndicator.startAnimating()
        }, completion: {
            self.navigateToExpire()
        })
    }
    
    func navigateToExpire(){
        if(countdownManager.secondsRemaining == 0){
            self.removeFromSuperview()
            let expireView = ExpireView(
                frame: controller.view.frame,
                transactionId: transactionId,
                controller: controller,
                transactionData: transactionData!,
                bottomSheetController: bottomSheetController!
            )
            bottomSheetController!.bottomSheetContainerView.addSubview(expireView)
            bottomSheetController!.viewType = .thirtyPercent
            bottomSheetController!.updateViewConstraints()
            
            // Note: We no longer call disableKHQRBehavior() here because ExpireView 
            // should also be stationary (similar to KHQR behavior).
        }
    }
    
    public override func removeFromSuperview() {
        super.removeFromSuperview()
        countdownManager.stopCountdown()
        NetworkMonitor.shared.stopMonitoring()
        NetworkMonitor.shared.onConnectionStatusChanged = nil
        isWaitingForConnection = false
    }
    
    public func completed() {
        if(countdownManager.secondsRemaining > 0){
            countdownManager.stopCountdown()
        }
    }
    
    private func setUpConstraintAndStyle(){
        khqrContainer.layer.cornerRadius = 30
        let shadowColor =  UIColor(red: 0, green: 0, blue: 0)
        khqrContainer.layer.shadowColor = shadowColor.cgColor
        khqrContainer.layer.shadowOffset = CGSize(width: 0, height: 0)
        khqrContainer.layer.shadowOpacity = 0.10
        khqrContainer.layer.shadowRadius = 8
        khqrContainer.layer.masksToBounds = false
        
        khqrHeaderContainer.roundCorners(corners: [.topLeft, .topRight], radius: 30.0)
        downloadButton.layer.cornerRadius = 10
        shareButton.layer.cornerRadius = 10
        
        downloadButton.backgroundColor =  UIColor(hex: "#0476FB2B")
        shareButton.backgroundColor = UIColor(hex: "#0476FB2B")
    }
}

