admob interstitial callback events only work once and not the second time

i made a simple setup. i have a main menu scene having a play button.
when i press it, it shows an interstitial ad. and when i close the ad, the callback events get fired correctly and the gameplay scene starts.
now when i loses, the game gets over and game over scene starts which have a replay button.
when i press the replay button, again an interstitial ad is shown, but when i close the ad, no callback events are fired and i remain on the game over scene.
if i press the reply button again, then nothing happens, not even the ad shows up.
I have used dontdestroyonload on my admanager script.
How do i make the callback events fire every time the ad displays ? Am i doing something wrong ? Is there any better way of coding an admob admanager script ?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using GoogleMobileAds.Api;
using UnityEngine.SceneManagement;
using TMPro;


public class AdManager : MonoBehaviour
{
    private BannerView bannerView;
    private InterstitialAd interstitial;
    private RewardedAd rewardAd;
    public static AdManager instance;
    //public TextMeshProUGUI testText;
    //bool adClosed = false;
    int bannerAdStatus = 0;
    int interstitialAdStatus = 0;
    int rewardAdStatus = 0;
    //bool destroyObject = false;
    float retryInterval = 1f;
    float initTime;
    bool mBound = false;
    //bool adFailed = false;

    public void Awake()
    {
        Debug.Log("AdManager..Awake");
        Debug.Log("AdManager.instance = "+ GetInstanceID());


        if (instance == null)
        {
            Debug.Log("AdManager..Awake..if" + GetInstanceID());

            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            if (instance != this)
            {
                Debug.Log("AdManager..Awake..else" + GetInstanceID());

                Debug.Log("More than one AdManager in scene");
                Destroy(this.gameObject);
                return;
            }
        }
        Debug.Log("AdManager.instance = " + GetInstanceID());


        /*if (instance == null)
        {
            instance = this;
        }*/
        // Initialize the Google Mobile Ads SDK.
        MobileAds.Initialize(initStatus => { });

        RequestAd();

    }

    void RequestAd()
    {
        Debug.Log("AdManager..RequestAd" + GetInstanceID());

        this.RequestBanner();
        this.RequestInterstitial();
        this.RequestRewardAd();
    }

    private void Update()
    {
        switch (bannerAdStatus)
        {
            case 0:
                break;
            case 1:
                break;

            case 2:
                if (Time.time - initTime >= retryInterval)
                {
                    RequestBanner();
                }
                break;

            case 3:
                break;

            case 4:
                //MainMenuUI.Play();
                bannerAdStatus = 0;
                RequestBanner();
                break;

            case 5:
                break;



            default:
                break;
        }
        switch (interstitialAdStatus)
        {
            case 0:
                break;
            case 1:
                break;

            case 2:
                if (Time.time - initTime >= retryInterval)
                {
                    RequestInterstitial();
                }
                break;

            case 3:
                break;

            case 4:                
                interstitialAdStatus = 0;
                RequestInterstitial();
                SceneManager.LoadScene(SceneIndexer.Gameplay);
                break;

            case 5:
                break;



            default:
                break;
        }
        switch (rewardAdStatus)
        {
            case 0:
                break;
            case 1:
                break;

            case 2:
            case 4:
                if (Time.time - initTime >= retryInterval)
                {
                    RequestRewardAd();
                }                
                break;

            case 3:
                break;

            case 5:
                rewardAdStatus = 0;
                RequestRewardAd();
                break;

            case 6:
                break;


            default:
                break;
        }
        
    }

    private void Start()
    {
        Debug.Log("AdManager..Start");
        Debug.Log("AdManager..Start..mBound = " + mBound + GetInstanceID());
        if (!mBound)
        {
            mBound = true;
            HandleBannerAdEvents(true);
            HandleInterstitialAdEvents(true);
            HandleRewardAdEvents(true);
        }
             
    }

    private void OnDestroy()
    {
        Debug.Log("AdManager..OnDestroy");
        Debug.Log("AdManager..OnDestroy..mBound = "+ mBound + GetInstanceID());
        interstitial.Destroy();
        
        if (mBound)
        {
            mBound = false;
            HandleBannerAdEvents(false);
            HandleInterstitialAdEvents(false);
            HandleRewardAdEvents(false);
        }

    }

    #region BannerAd
    private void RequestBanner()
    {
        Debug.Log("AdManager..RequestBanner" + GetInstanceID());

#if UNITY_EDITOR
        string adUnitId = "unused";
#elif UNITY_ANDROID
            string adUnitId = "ca-app-pub-3940256099942544/6300978111";
#elif UNITY_IPHONE
            string adUnitId = "ca-app-pub-3212738706492790/5381898163";
#else
            string adUnitId = "unexpected_platform";
#endif

        // Clean up banner ad before creating a new one.
        if (this.bannerView != null)
        {
            Debug.Log("AdManager..RequestBanner..if" + GetInstanceID());

            this.bannerView.Destroy();
        }

        AdSize adaptiveSize =
                AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(AdSize.FullWidth);

        this.bannerView = new BannerView(adUnitId, adaptiveSize, AdPosition.Bottom);



        /*AdRequest adRequest = new AdRequest.Builder()
            .AddTestDevice(AdRequest.TestDeviceSimulator)
            .AddTestDevice("0123456789ABCDEF0123456789ABCDEF")
            .Build();*/

        AdRequest adRequest = new AdRequest.Builder().Build();

        // Load a banner ad.
        this.bannerView.LoadAd(adRequest);
    }

    public void DisplayBanner()
    {
        Debug.Log("AdManager..DisplayBanner" + GetInstanceID());

        bannerView.Show();
    }

    public void HideBanner()
    {
        Debug.Log("AdManager..HideBanner" + GetInstanceID());

        bannerView.Hide();
    }

    void HandleBannerAdEvents(bool subscribe)
    {
        Debug.Log("AdManager..HandleBannerAdEvents" + GetInstanceID());
        Debug.Log("AdManager..HandleBannerAdEvents..subscribe = "+ subscribe + GetInstanceID());

        if (subscribe)
        {
            Debug.Log("AdManager..HandleBannerAdEvents..if" + GetInstanceID());

            // Register for ad events.
            this.bannerView.OnAdLoaded += this.HandleAdLoaded;
            this.bannerView.OnAdFailedToLoad += this.HandleAdFailedToLoad;
            this.bannerView.OnAdOpening += this.HandleAdOpened;
            this.bannerView.OnAdClosed += this.HandleAdClosed;
            this.bannerView.OnAdLeavingApplication += this.HandleAdLeftApplication;
        }
        else
        {
            Debug.Log("AdManager..HandleBannerAdEvents..else" + GetInstanceID());

            // Register for ad events.
            this.bannerView.OnAdLoaded -= this.HandleAdLoaded;
            this.bannerView.OnAdFailedToLoad -= this.HandleAdFailedToLoad;
            this.bannerView.OnAdOpening -= this.HandleAdOpened;
            this.bannerView.OnAdClosed -= this.HandleAdClosed;
            this.bannerView.OnAdLeavingApplication -= this.HandleAdLeftApplication;
        }
    }
    #region Banner Callback Methods
    public void HandleAdLoaded(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdLoaded event received" + GetInstanceID());
        MonoBehaviour.print(String.Format("Ad Height: {0}, width: {1}",
            this.bannerView.GetHeightInPixels(),
            this.bannerView.GetWidthInPixels()));
        bannerAdStatus = 1;
    }

    public void HandleAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
    {
        MonoBehaviour.print(
                "HandleFailedToReceiveAd event received with message: " + args.Message + GetInstanceID());
        bannerAdStatus = 2;

    }

    public void HandleAdOpened(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdOpened event received" + GetInstanceID());
        bannerAdStatus = 3;

    }

    public void HandleAdClosed(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdClosed event received" + GetInstanceID());
        bannerAdStatus = 4;

    }

    public void HandleAdLeftApplication(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdLeftApplication event received" + GetInstanceID());
        bannerAdStatus = 5;

    }
    #endregion

    #endregion

    #region InterstitialAd

    private void RequestInterstitial()
    {
        Debug.Log("AdManager..RequestInterstitial" + GetInstanceID());

#if UNITY_EDITOR
        string adUnitId = "unused";
#elif UNITY_ANDROID
            string adUnitId = "ca-app-pub-3940256099942544/1033173712";
#elif UNITY_IPHONE
            string adUnitId = "ca-app-pub-3940256099942544/4411468910";
#else
            string adUnitId = "unexpected_platform";
#endif
        // Initialize an InterstitialAd.
        this.interstitial = new InterstitialAd(adUnitId);



        // Create an empty ad request.
        AdRequest request = new AdRequest.Builder().Build();
        // Load the interstitial with the request.
        this.interstitial.LoadAd(request);
        //testText.text = "RequestingInterstitial";

    }

    public void DisplayInterstitial()
    {
        Debug.Log("AdManager..DisplayInterstitial" + GetInstanceID());
        if (interstitial.IsLoaded())
        {
            Debug.Log("AdManager..DisplayInterstitial..IsLoaded" + GetInstanceID());

            interstitial.Show();
        }
        else
        {
            Debug.Log("AdManager..DisplayInterstitial..NotLoaded" + GetInstanceID());

            SceneManager.LoadScene(SceneIndexer.Gameplay);

        }
    }

    void HandleInterstitialAdEvents(bool subscribe)
    {
        Debug.Log("AdManager..HandleInterstitialAdEvents" + GetInstanceID());

        if (subscribe)
        {
            Debug.Log("AdManager..HandleInterstitialAdEvents..if" + GetInstanceID());

            // Called when an ad request has successfully loaded.
            this.interstitial.OnAdLoaded += HandleOnAdLoaded;
            // Called when an ad request failed to load.
            this.interstitial.OnAdFailedToLoad += HandleOnAdFailedToLoad;
            // Called when an ad is shown.
            this.interstitial.OnAdOpening += HandleOnAdOpened;
            // Called when the ad is closed.
            this.interstitial.OnAdClosed += HandleOnAdClosed;
            // Called when the ad click caused the user to leave the application.
            this.interstitial.OnAdLeavingApplication += HandleOnAdLeavingApplication;
        }
        else
        {
            Debug.Log("AdManager..HandleInterstitialAdEvents..else" + GetInstanceID());

            // Called when an ad request has successfully loaded.
            this.interstitial.OnAdLoaded -= HandleOnAdLoaded;
            // Called when an ad request failed to load.
            this.interstitial.OnAdFailedToLoad -= HandleOnAdFailedToLoad;
            // Called when an ad is shown.
            this.interstitial.OnAdOpening -= HandleOnAdOpened;
            // Called when the ad is closed.
            this.interstitial.OnAdClosed -= HandleOnAdClosed;
            // Called when the ad click caused the user to leave the application.
            this.interstitial.OnAdLeavingApplication -= HandleOnAdLeavingApplication;
        }
    }

    #region Interstitial Callback Methods
    public void HandleOnAdLoaded(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdLoaded event received");
        Debug.Log("HandleAdLoaded event received in debug" + GetInstanceID());
        interstitialAdStatus = 1;
    }

    public void HandleOnAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
    {
        MonoBehaviour.print("HandleFailedToReceiveAd event received with message: "
                            + args.Message);
        Debug.Log("HandleOnAdFailedToLoad event received in debug" + GetInstanceID());

        initTime = Time.time;
        interstitialAdStatus = 2;
    }

    public void HandleOnAdOpened(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdOpened event received");
        Debug.Log("HandleOnAdOpened event received in debug" + GetInstanceID());

        interstitialAdStatus = 3;
    }

    public void HandleOnAdClosed(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdClosed event received");
        Debug.Log("HandleOnAdClosed event received in debug" + GetInstanceID());

        //interstitial.Destroy();
        interstitialAdStatus = 4;
    }

    public void HandleOnAdLeavingApplication(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleAdLeavingApplication event received");
        Debug.Log("HandleOnAdLeavingApplication event received in debug" + GetInstanceID());

        interstitialAdStatus = 5;


    }
    #endregion

    #endregion

    #region RewardAd
    private void RequestRewardAd()
    {
        Debug.Log("AdManager..RequestRewardAd");

#if UNITY_EDITOR
        string adUnitId = "unused";
#elif UNITY_ANDROID
            string adUnitId = "ca-app-pub-3940256099942544/5224354917";
#elif UNITY_IPHONE
            string adUnitId = "ca-app-pub-3940256099942544/1712485313";
#else
            string adUnitId = "unexpected_platform";
#endif

        this.rewardAd = new RewardedAd(adUnitId);
        

        // Create an empty ad request.
        AdRequest request = new AdRequest.Builder().Build();
        // Load the rewarded ad with the request.
        this.rewardAd.LoadAd(request);
    }

    public void DisplayRewardAd()
    {
        Debug.Log("AdManager..DisplayRewardAd");

        if (rewardAd.IsLoaded())
        {
            Debug.Log("AdManager..DisplayRewardAd..if");

            rewardAd.Show();
        }
    }

    void HandleRewardAdEvents(bool subscribe)
    {
        Debug.Log("AdManager..HandleRewardAdEvents");

        if (subscribe)
        {
            // Called when an ad request has successfully loaded.
            this.rewardAd.OnAdLoaded += HandleRewardedAdLoaded;
            // Called when an ad request failed to load.
            this.rewardAd.OnAdFailedToLoad += HandleRewardedAdFailedToLoad;
            // Called when an ad is shown.
            this.rewardAd.OnAdOpening += HandleRewardedAdOpening;
            // Called when an ad request failed to show.
            this.rewardAd.OnAdFailedToShow += HandleRewardedAdFailedToShow;
            // Called when the user should be rewarded for interacting with the ad.
            this.rewardAd.OnUserEarnedReward += HandleUserEarnedReward;
            // Called when the ad is closed.
            this.rewardAd.OnAdClosed += HandleRewardedAdClosed;

        }
        else
        {
            // Called when an ad request has successfully loaded.
            this.rewardAd.OnAdLoaded -= HandleRewardedAdLoaded;
            // Called when an ad request failed to load.
            this.rewardAd.OnAdFailedToLoad -= HandleRewardedAdFailedToLoad;
            // Called when an ad is shown.
            this.rewardAd.OnAdOpening -= HandleRewardedAdOpening;
            // Called when an ad request failed to show.
            this.rewardAd.OnAdFailedToShow -= HandleRewardedAdFailedToShow;
            // Called when the user should be rewarded for interacting with the ad.
            this.rewardAd.OnUserEarnedReward -= HandleUserEarnedReward;
            // Called when the ad is closed.
            this.rewardAd.OnAdClosed -= HandleRewardedAdClosed;

        }
    }

    #region RewardAd Callback Methods
    public void HandleRewardedAdLoaded(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleRewardedAdLoaded event received");
        rewardAdStatus = 1;
    }

    public void HandleRewardedAdFailedToLoad(object sender, AdErrorEventArgs args)
    {
        MonoBehaviour.print(
            "HandleRewardedAdFailedToLoad event received with message: "
                             + args.Message);
        rewardAdStatus = 2;

    }

    public void HandleRewardedAdOpening(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleRewardedAdOpening event received");
        rewardAdStatus = 3;

    }

    public void HandleRewardedAdFailedToShow(object sender, AdErrorEventArgs args)
    {
        MonoBehaviour.print(
            "HandleRewardedAdFailedToShow event received with message: "
                             + args.Message);
        rewardAdStatus = 4;

    }

    public void HandleRewardedAdClosed(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleRewardedAdClosed event received");
        rewardAdStatus = 5;

        //RequestRewardAd();

    }

    public void HandleUserEarnedReward(object sender, Reward args)
    {
        string type = args.Type;
        double amount = args.Amount;
        MonoBehaviour.print(
            "HandleRewardedAdRewarded event received for "
                        + amount.ToString() + " " + type);
        rewardAdStatus = 6;

    }
    #endregion

    #endregion
}

you need to destroy your pointer to InterstitialAd on OnAdClose event, after that before requesting new ad you need to register all callback methods again @shubhamjindal27