magento2.3 – Plugin to add custom product giving incorrect results

When a customer adds a product with specific custom options, I need to add a separate product to the cart. To achieve this I have the following afterSave plugin for MagentoCheckoutModelCart which works for the first time I add a product with the specific options (I get the extra product (an additional set up fee)).

The issue I’m having, after adding the “correct” product and getting the set up fee, I add a generic product with no options and something is duplicating my custom option from the correct product to the generic product triggering my code to add the set up fee product again, then adds the “correct” product a second time with no custom options. This leads me to having one correct product in cart, one generic product with the same custom options in cart, one “correct” product in cart but with no options, and a product in cart with the wrong quantity (2 instead of 1, although technically correct as there are, now, 2 products with the options).

Why is the code affecting the cart in this way, and what changes need to be done to make it work as intended?

namespace <Vendor><Module>PluginFrontendMagentoCheckoutModel;

use MagentoFrameworkSerializeSerializerInterface;
use MagentoFrameworkAppRequestInterface;

class Cart
{

    protected $serializer;
    protected $productRepository;
    protected $logger;
    protected $registry;
    protected $request;
    
    
    public function __construct(
        MagentoFrameworkRegistry $registry,
        SerializerInterface $serializer,
        MagentoCatalogApiProductRepositoryInterface $productRepository,
        RequestInterface $request,
        PsrLogLoggerInterface $logger
    )
    {
        $this->registry = $registry;
        $this->serializer = $serializer;
        $this->productRepository = $productRepository;
        $this->request = $request;
        $this->logger = $logger;
    }
    
    

    /**
     * When user adds, updates or removes item from cart, check if cart
     *  contains personalisation product and add/remove virtual product "One off fee"
     * @param MagentoCheckoutModelCart $subject
     * @param MagentoCheckoutModelCart $cart
     * @return MagentoCheckoutModelCart
     */
    public function afterSave(
        MagentoCheckoutModelCart $subject,
        $cart
    ) {
        //Stop this code from running again when we call $cart::save, below.
        $registryKey = 'one_off_fee_observer';
        if($this->registry->registry($registryKey) == true) {
            return $cart;
        }
        $this->registry->register($registryKey, true);
        
        
        $sku = 'One off setup fee'; //"One off setup fee" virtual product sku.
        $update = false;
        
        /** @var int $personalisedProductCount Number of personalised products in cart */
        $personalisedProductCount = 0;
        //check if there is a personalised product in cart.
        $items = $cart->getItems();
        //Id of cart item of existing one off fee product.
        $itemId = null;
        
        foreach($items as $item) {
           
            //Does cart already contain a set up free product?
            if($item->getSku() == $sku){
                $itemId = $item->getId();
            }
        
            try {
                //Is this a personalised product?
                $options = $item->getOptionByCode('additional_options');
                if (!is_null($options)) {
                    $options = $this->serializer->unserialize($options->getValue());
                    foreach($options as $option) {
                        if($option('label') == 'Personalize Total') {
                            $personalisedProductCount++;
                        }
                    }
                }
            }
            catch (Exception $e) {
                $this->logger->critical($e->getMessage());
            }
        }
        
        
        //If personalised rows found, add appropriate number of 1 off fees.
        if($personalisedProductCount > 0) {
            
            //if fee already in cart, update it, otherwise add it.
            if(!is_null($itemId)) {
                $cart->updateItem($itemId, $personalisedProductCount);
                $update = true;
            }
            else {
            
                $product = $this->productRepository->get($sku);
                $params = (
                    'product' => $product->getId(), 
                    'qty' => $personalisedProductCount,
                    'price' => $product->getFinalPrice(),
                );
                
                try {
                    $cart->addProduct($product, $params);
                    $update = true;
                }
                catch (Exception $e) {
                    $this->logger->critical(sprintf('Failed to add one off fee: "%s"', $e->getMessage()));
                }

            }
        }
        //No personalisation found. Remove fee.
        else {
            if(!is_null($itemId)) {
                try {
                    $cart->removeItem($itemId);
                    $update = true;
                }
                catch (Exception $e) {
                    $this->logger->critical(sprintf('Failed to remove one off fee: "%s"', $e->getMessage()));
                }
            }
        }
        //We've a) Added fee, b) removed fee, c) altered quantity of fee. Need to re-save the cart.
        if($update) {
            $cart->save();
        }
        
        return $cart;
    }
}