<?php
/**
 * Mageplaza
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Mageplaza.com license that is
 * available through the world-wide-web at this URL:
 * https://www.mageplaza.com/LICENSE.txt
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade this extension to newer
 * version in the future.
 *
 * @category    Mageplaza
 * @package     Mageplaza_Faqs
 * @copyright   Copyright (c) Mageplaza (http://www.mageplaza.com/)
 * @license     https://www.mageplaza.com/LICENSE.txt
 */

namespace Mageplaza\Faqs\Model\Export;

use Exception;
use Magento\Framework\Data\Collection as DataCollection;
use Zend_Db_Expr;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Model\AbstractModel;
use Magento\ImportExport\Model\Export;
use Magento\ImportExport\Model\Export\AbstractEntity;
use Magento\ImportExport\Model\Export\Factory;
use Magento\ImportExport\Model\ResourceModel\CollectionByPagesIteratorFactory;
use Magento\Store\Model\StoreManagerInterface;
use Mageplaza\Faqs\Model\ResourceModel\Category\Collection;

/**
 * Class Category
 * @package Mageplaza\Faqs\Model\Export
 */
class Category extends AbstractEntity
{

    /**
     * Permanent entity columns
     *
     * @var string[]
     */
    protected $_permanentAttributes = [
        CategoryAttributeCollection::CATEGORY_ID,
        CategoryAttributeCollection::NAME,
        CategoryAttributeCollection::DESCRIPTION,
        CategoryAttributeCollection::VIEWS,
        CategoryAttributeCollection::STORE_ID,
        CategoryAttributeCollection::ARTICLES,
        CategoryAttributeCollection::URL_KEY,
        CategoryAttributeCollection::ICON_TYPE,
        CategoryAttributeCollection::ICON,
        CategoryAttributeCollection::ICON_CUSTOM_PATH,
        CategoryAttributeCollection::ICON_CUSTOM_WIDTH,
        CategoryAttributeCollection::ICON_CUSTOM_HEIGHT,
        CategoryAttributeCollection::ENABLED,
        CategoryAttributeCollection::META_TITLE,
        CategoryAttributeCollection::META_DESCRIPTION,
        CategoryAttributeCollection::META_KEYWORDS,
        CategoryAttributeCollection::META_ROBOTS,
        CategoryAttributeCollection::POSITION
    ];

    protected $_filterAttributes = [
        CategoryAttributeCollection::NAME,
        CategoryAttributeCollection::DESCRIPTION,
        CategoryAttributeCollection::STORE_ID,
        CategoryAttributeCollection::ENABLED,
        CategoryAttributeCollection::URL_KEY,
        CategoryAttributeCollection::META_TITLE,
        CategoryAttributeCollection::META_DESCRIPTION,
        CategoryAttributeCollection::META_KEYWORDS
    ];

    /**
     * Attribute collection name
     */
    const ATTRIBUTE_COLLECTION_NAME = CategoryAttributeCollection::class;

    /**
     * @var Collection
     */
    protected $categoryCollection;

    /**
     * Account constructor.
     *
     * @param ScopeConfigInterface $scopeConfig
     * @param StoreManagerInterface $storeManager
     * @param Factory $collectionFactory
     * @param CollectionByPagesIteratorFactory $resourceColFactory
     * @param Collection $categoryCollection
     * @param array $data
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        StoreManagerInterface $storeManager,
        Factory $collectionFactory,
        CollectionByPagesIteratorFactory $resourceColFactory,
        Collection $categoryCollection,
        array $data = []
    ) {
        $this->categoryCollection = $categoryCollection;

        parent::__construct($scopeConfig, $storeManager, $collectionFactory, $resourceColFactory, $data);
    }

    /**
     * @return string
     * @throws LocalizedException
     */
    public function export()
    {
        $filters      = $this->_parameters;
        $columns      = $this->_getHeaderColumns();
        $collection   = $this->_getEntityCollection();
        $exportFilter = $filters[Export::FILTER_ELEMENT_GROUP];
        foreach ($exportFilter as $field => $filter) {
            if (in_array($field, $columns, true)) {
                if ($filter || $filter === '0') {
                    if ($field === CategoryAttributeCollection::STORE_ID) {
                        $collection->addFieldToFilter(
                            [$field, $field, $field, $field],
                            [
                                ['like' => $filter],
                                ['like' => "%,{$filter}"],
                                ['like' => "{$filter},%"],
                                ['like' => "%,{$filter},%"]
                            ]
                        );
                    } else {
                        $collection->addFieldToFilter($field, [
                            'like' => "%{$filter}%"
                        ]);
                    }
                }
            }
        }

        $this->getWriter()->setHeaderCols($columns);

        $this->_exportCollectionByPages($collection);

        return $this->getWriter()->getContents();
    }

    /**
     * @param AbstractModel $item
     *
     * @throws LocalizedException
     */
    public function exportItem($item)
    {
        $this->getWriter()->writeRow($item->getData());
    }

    /**
     * @return string
     */
    public function getEntityTypeCode()
    {
        return 'mp_faqs_categories';
    }

    /**
     * @return array|string[]
     * @throws LocalizedException
     */
    protected function _getHeaderColumns()
    {
        $filters = $this->_parameters;
        if (!isset($filters[Export::FILTER_ELEMENT_SKIP])) {
            return $this->_permanentAttributes;
        }

        $skip = $filters[Export::FILTER_ELEMENT_SKIP];

        if (count($skip) === count($this->_permanentAttributes)) {
            throw new LocalizedException(__('There is no data for the export.'));
        }

        return array_diff($this->_permanentAttributes, $skip);
    }

    /**
     * @return AbstractDb|Collection
     */
    protected function _getEntityCollection()
    {
        $articleCollection = $this->categoryCollection;
        $articleCollection->getSelect()->joinLeft(
            ['mpfac' => $articleCollection->getTable('mageplaza_faqs_article_category')],
            'main_table.category_id = mpfac.category_id',
            ['article_id']
        )->columns([
            'articles' => new Zend_Db_Expr('GROUP_CONCAT(DISTINCT `mpfac`.`article_id`)')
        ])->group(['main_table.category_id']);

        $articleCollection->addFilterToMap('store_ids', 'main_table.store_ids');
        $articleCollection->addFilterToMap('visibility', 'main_table.visibility');

        return $articleCollection;
    }

    /**
     * @return DataCollection|mixed
     * @throws Exception
     */
    public function getAttributeCollection()
    {
        return $this->_attributeCollection->buildAttributes($this->_filterAttributes);
    }
}
