<?php

declare(strict_types=1);

namespace FiloBlu\Flow\Model\Actions\From;

use Exception;
use FiloBlu\Flow\Helper\CategoryHelper;
use FiloBlu\Flow\Helper\Product as ProductHelper;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\CategoryLinkRepository;
use Magento\Catalog\Model\Product;

/**
 * Class Removetocategory
 * @package FiloBlu\Flow\Model\Actions\From
 */
class Removetocategory
{
    /**
     * @var array
     */
    protected $categoryLookup = [];

    /**
     * @var array
     */
    protected $excludedCategories = [];

    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var ProductHelper
     */
    protected $productHelper;

    /**
     * @var CategoryHelper
     */
    protected $categoryHelper;

    /**
     * @var CategoryLinkRepository
     */
    protected $categoryLinkRepository;

    /**
     * Removetocategory constructor.
     * @param ProductRepositoryInterface $productRepository
     * @param CategoryHelper $categoryHelper
     * @param ProductHelper $productHelper
     * @param CategoryLinkRepository $categoryLinkRepository
     */
    public function __construct(
        ProductRepositoryInterface $productRepository,
        CategoryHelper             $categoryHelper,
        ProductHelper              $productHelper,
        CategoryLinkRepository     $categoryLinkRepository
    ) {
        $this->productRepository = $productRepository;
        $this->productHelper = $productHelper;
        $this->categoryHelper = $categoryHelper;
        $this->categoryLinkRepository = $categoryLinkRepository;
    }

    /**
     * @param string|null|int $categoriesString single number (58) single string (parka) path of strings (woman/jacket/parka) path of number (2/5/9) separated by |
     * @param Product|ProductInterface $product
     * @param $storeId
     * @throws Exception
     */
    public function process($product, $categoriesString, $storeId)
    {
        if (trim($categoriesString) === '##all##') {
            // TODO implement logic to delete all categories.
            // first attempt cycling categories and using categoryLinkRepository->deleteByIds didn't work in case the product is not enabled on website
            $connection = $this->productHelper->getConnection();
            $connection->delete('catalog_category_product', ['product_id = ?' => $product->getEntityId()]);

            return;
        }

        $categories = $this->getCategoriesToRemove($categoriesString);
        $existingCategories = $product->getCategoryIds();
        $categoriesToRemove = array_intersect($categories, $existingCategories);

        if (empty($categoriesToRemove)) {
            return;
        }

        foreach ($categoriesToRemove as $cat) {
            $this->categoryLinkRepository->deleteByIds($cat, $product->getSku());
        }
    }

    /**
     * @param $categoriesString
     * @return array
     */
    public function getCategoriesToRemove($categoriesString)
    {
        if (!$categoriesString) {
            return [];
        }

        $categories = explode(',', trim(str_replace('|', ',', $categoriesString), ',') ?? '');
        return array_map('trim', $categories ?? []);
    }

}
