<?php

namespace Webkul\DamBundle\Filter;

use Oro\Bundle\FilterBundle\Datasource\FilterDatasourceAdapterInterface;
use Oro\Bundle\FilterBundle\Filter\FilterUtility;
use Oro\Bundle\FilterBundle\Filter\NumberFilter;
use Symfony\Component\Form\FormFactoryInterface;
use Webkul\DamBundle\Listener\ClassDefinationForCompatibility;

$versionCompatiblility = new ClassDefinationForCompatibility();
$versionCompatiblility->createClassAliases();
/**
 * Category filter
 */
class CategoryFilter extends \BaseFilter
{
    /**
     * {@inheritdoc}
     */
    public function apply(FilterDatasourceAdapterInterface $ds, $data)
    {
        $data = $this->parseData($data);
        if (!$data) {
            return false;
        }

        if ($data['categoryId'] === self::ALL_CATEGORY) {
            return $this->applyFilterByAll($ds, $data);
        } elseif ($data['categoryId'] === self::UNCLASSIFIED_CATEGORY) {
            return $this->applyFilterByUnclassified($ds, $data);
        } else {
            return $this->applyFilterByCategory($ds, $data);
        }

        return false;
    }

    /**
     * @param mixed $data
     *
     * @return array|bool
     */
    public function parseData($data)
    {
        if (!is_array($data) || !array_key_exists('value', $data) || !is_array($data['value'])) {
            return false;
        }

        return [
            'includeSub' => isset($data['type'])                ? (bool) $data['type']               : true,
            'treeId'     => isset($data['value']['treeId'])     ? (int) $data['value']['treeId']     : null,
            'categoryId' => isset($data['value']['categoryId']) ? (int) $data['value']['categoryId'] : null
        ];
    }

    /**
     * Add filter to display all products
     *
     * @param FilterDatasourceAdapterInterface $ds
     * @param array                            $data
     *
     * @return bool has been applied
     */
    protected function applyFilterByAll(FilterDatasourceAdapterInterface $ds, $data)
    {
        return true;
    }

    /**
     * Add filter to display unclassified products
     *
     * @param FilterDatasourceAdapterInterface $ds
     * @param array                            $data
     *
     * @return bool has been applied
     */
    protected function applyFilterByUnclassified(FilterDatasourceAdapterInterface $ds, $data)
    {
        $tree = $this->categoryRepo->find($data['treeId']);
        if ($tree) {
            $this->util->applyFilter($ds, 'categories', 'NOT IN CHILDREN', [$tree->getCode()]);

            return true;
        }

        return false;
    }

    /**
     * Add filter to display categorized products
     *
     * @param FilterDatasourceAdapterInterface $ds
     * @param array                            $data
     *
     * @return bool has been applied
     */
    protected function applyFilterByCategory(FilterDatasourceAdapterInterface $ds, $data)
    {
        $category = $this->categoryRepo->find($data['categoryId']);

        if (!$category) {
            $category = $this->categoryRepo->find($data['treeId']);
        }

        if ($category) {
            if ($data['includeSub']) {
                $this->util->applyFilter($ds, 'categories', 'IN CHILDREN', [$category->getCode()]);
            } else {
                $this->util->applyFilter($ds, 'categories', 'IN', [$category->getCode()]);
            }

            return true;
        }

        return false;
    }

    /**
     * Get children category codes
     *
     * @param CategoryInterface $category
     * @return string[]
     *
     * @deprecated Not used anymore internally. If needed, use directly the categoryRepo service
     */
    protected function getAllChildrenCodes(\CategoryInterface $category)
    {
        return $this->categoryRepo->getAllChildrenCodes($category);
    }

    /**
     * {@inheritdoc}
     */
    protected function getFormType()
    {
        if (class_exists("Akeneo\Platform\CommunityVersion")) {
            return "Oro\Bundle\PimFilterBundle\Form\Type\Filter\CategoryFilterType";
        } else {
            return "Pim\Bundle\FilterBundle\Form\Type\Filter\CategoryFilterType";
        }
    }
}
