<?php

namespace Autogedal\Labels\Observer\Adminhtml;

use Autogedal\Labels\Model\LabelFactory;
use Autogedal\Labels\Model\ResourceModel\Label as LabelResource;
use Autogedal\Labels\Model\ResourceModel\Label\CollectionFactory;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class ProductLabelSync implements ObserverInterface
{
    private $request;
    private $collectionFactory;
    private $labelFactory;
    private $labelResource;

    public function __construct(
        RequestInterface $request,
        CollectionFactory $collectionFactory,
        LabelFactory $labelFactory,
        LabelResource $labelResource
    ) {
        $this->request = $request;
        $this->collectionFactory = $collectionFactory;
        $this->labelFactory = $labelFactory;
        $this->labelResource = $labelResource;
    }

    public function execute(Observer $observer)
    {
        $product = $observer->getEvent()->getProduct();
        if (!$product || !$product->getId()) {
            return $this;
        }

        $productData = (array)$this->request->getParam('product', []);
        $requestValue = $productData['autogedal_label_ids'] ?? null;
        if ($requestValue === null) {
            return $this;
        }

        $selectedIds = array_map('strval', (array)$requestValue);
        $sku = trim((string)$product->getSku());
        if ($sku === '') {
            return $this;
        }
        $originalSku = trim((string)$product->getOrigData('sku'));

        $collection = $this->collectionFactory->create();
        $collection->addFieldToFilter('include_type', ['neq' => 1]);
        $collection->addFieldToFilter('is_active', 1);

        foreach ($collection as $labelModel) {
            $labelId = (string)$labelModel->getId();
            $includeSku = array_values(array_filter(array_map('trim', explode(',', (string)$labelModel->getData('include_sku')))));
            if ($originalSku !== '' && $originalSku !== $sku) {
                $includeSku = array_values(array_filter($includeSku, static function ($value) use ($originalSku) {
                    return $value !== $originalSku;
                }));
            }

            $hasSku = in_array($sku, $includeSku, true);
            $shouldHaveSku = in_array($labelId, $selectedIds, true);

            if ($shouldHaveSku && !$hasSku) {
                $includeSku[] = $sku;
            } elseif (!$shouldHaveSku && $hasSku) {
                $includeSku = array_values(array_filter($includeSku, static function ($value) use ($sku) {
                    return $value !== $sku;
                }));
            } else {
                continue;
            }

            $label = $this->labelFactory->create();
            $this->labelResource->load($label, (int)$labelId);
            if (!$label->getId()) {
                continue;
            }
            $label->setData('include_sku', implode(',', $includeSku));
            $this->labelResource->save($label);
        }

        return $this;
    }
}
