<?php

namespace Autogedal\Extend\Block\Widget;

use Magento\Framework\View\Element\Template;
use Magento\Widget\Block\BlockInterface;
use Magento\Framework\View\Element\Template\Context;
use Magento\Catalog\Model\CategoryRepository;
use Magento\Catalog\Model\Layer\Category as CategoryLayer;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Autogedal\Extend\ViewModel\ProductCompatibility as ProductCompatibilityViewModel;
use Magento\Catalog\Model\Product\Attribute\Repository as AttributeRepository;

class ProductCompatibility extends Template implements BlockInterface
{
    const CATEGORY_ID = 2161; // Bare Transversale Green Valley

    /**
     * @var CategoryRepository
     */
    protected $categoryRepository;

    /**
     * @var ProductCollectionFactory
     */
    protected $productCollectionFactory;

    /**
     * @var ProductCompatibilityViewModel
     */
    protected $viewModel;

    /**
     * @var CategoryLayer
     */
    protected $categoryLayer;

    /**
     * @var AttributeRepository
     */
    protected $attributeRepository;

    /**
     * @var string
     */
    protected $_template = 'Autogedal_Extend::widget/product_compatibility.phtml';

    /**
     * @param Context $context
     * @param CategoryRepository $categoryRepository
     * @param ProductCollectionFactory $productCollectionFactory
     * @param ProductCompatibilityViewModel $viewModel
     * @param CategoryLayer $categoryLayer
     * @param AttributeRepository $attributeRepository
     * @param array $data
     */
    public function __construct(
        Context $context,
        CategoryRepository $categoryRepository,
        ProductCollectionFactory $productCollectionFactory,
        ProductCompatibilityViewModel $viewModel,
        CategoryLayer $categoryLayer,
        AttributeRepository $attributeRepository,
        array $data = []
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->productCollectionFactory = $productCollectionFactory;
        $this->viewModel = $viewModel;
        $this->categoryLayer = $categoryLayer;
        $this->attributeRepository = $attributeRepository;
        parent::__construct($context, $data);
    }

    /**
     * Get ViewModel instance
     *
     * @return ProductCompatibilityViewModel
     */
    public function getViewModel()
    {
        return $this->viewModel;
    }

    /**
     * Get filter options from layered navigation
     *
     * @return array
     */
    public function getFilterOptions()
    {
        try {
            $category = $this->categoryRepository->get(self::CATEGORY_ID);
            $this->categoryLayer->setCurrentCategory($category);

            $productCollection = $this->categoryLayer->getProductCollection();

            $marcaOptions = [];
            $modelOptions = [];
            $caroserieOptions = [];
            $tpPlafonOptions = [];
            $yearOptions = [];

            $attributeCodes = ['auto_brand', 'auto_model', 'auto_body_bare', 'auto_roof_type_bare', 'auto_from_to_bare'];

            foreach ($attributeCodes as $attributeCode) {
                try {
                    $attribute = $this->attributeRepository->get($attributeCode);
                    $optionsFacetedData = $productCollection->getFacetedData($attributeCode);

                    $options = [];
                    if ($optionsFacetedData && is_array($optionsFacetedData)) {
                        foreach ($optionsFacetedData as $optionId => $data) {
                            if (isset($data['count']) && $data['count'] > 0) {
                                $label = $attribute->getSource()->getOptionText($optionId);
                                if (!$label) {
                                    $label = $optionId;
                                }

                                $options[] = [
                                    'value' => $optionId,
                                    'label' => $label,
                                    'count' => $data['count']
                                ];
                            }
                        }
                    }

                    switch ($attributeCode) {
                        case 'auto_brand':
                            $marcaOptions = $this->sortAlphabetically($options);
                            break;
                        case 'auto_model':
                            $modelOptions = $options;
                            break;
                        case 'auto_body_bare':
                            $caroserieOptions = $this->sortAlphabetically($options);
                            break;
                        case 'auto_roof_type_bare':
                            $tpPlafonOptions = $this->sortAlphabetically($options);
                            break;
                        case 'auto_from_to_bare':
                            $yearOptions = $options;
                            break;
                    }
                } catch (\Exception $attrException) {}
            }

            return [
                'marca' => $marcaOptions,
                'model' => $modelOptions,
                'caroserie' => $caroserieOptions,
                'tp_plafon' => $tpPlafonOptions,
                'year' => $yearOptions
            ];

        } catch (\Exception $e) {}
    }

    /**
     * Sort options alphabetically by label
     *
     * @param array $options
     * @return array
     */
    private function sortAlphabetically($options)
    {
        usort($options, function ($a, $b) {
            return strcasecmp($a['label'], $b['label']);
        });

        return $options;
    }

    /**
     * Get AJAX URL for loading products
     *
     * @return string
     */
    public function getAjaxUrl()
    {
        return $this->getUrl('autogedal_extend/compatibility/products');
    }

    /**
     * Get AJAX URL for loading filter options
     *
     * @return string
     */
    public function getFilterOptionsUrl()
    {
        return $this->getUrl('autogedal_extend/compatibility/filteroptions');
    }

    /**
     * Get widget title
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->getData('title') ?: __('Verificator Bare Transversale');
    }

    /**
     * Render block HTML
     *
     * @return string
     */
    public function toHtml()
    {
        return $this->getWidgetStatus() ? parent::toHtml() : '';
    }

    /**
     * Get widget status
     *
     * @return bool
     */
    public function getWidgetStatus()
    {
        return $this->getData('widget_status') !== '0';
    }
}
