<?php

namespace KupShop\AutomationConfiguratorBundle\Configurator\Orders\Conditions\Fields;

use KupShop\AutomationConfiguratorBundle\Configurator\Interfaces\Conditions\Fields\Field;
use KupShop\AutomationConfiguratorBundle\Configurator\Orders\OrdersContext;
use KupShop\AutomationConfiguratorBundle\Util\ExpressionContext;
use Query\QueryBuilder;

class HasCharge extends Field implements OrdersContext
{
    public function getConfig(): array
    {
        return [
            'label' => 'Má příplatek',
            'type' => 'multiselect',
            'values' => $this->getCharges(),
            'operators' => ['multiselect_function'],
            'function' => true,
        ];
    }

    public function isEnabled(): bool
    {
        return findModule(\Modules::PRODUCTS_CHARGES);
    }

    public function getName(): string
    {
        return 'has_charge';
    }

    public function getGroupName(): ?string
    {
        return 'order_flags';
    }

    public function getCompareValue(ExpressionContext $context, $args = null)
    {
        $context = $context->getContext();

        return !empty(array_intersect(explode(',', $context['order_charges']), $args[0] ?? []));
    }

    /**
     * @param QueryBuilder $context
     */
    public function modifyPrefetchFastCondition($context, $jsonValue)
    {
        $chargeIds = $this->prefetchUtil->getMultiSelectValues($jsonValue);

        if (!empty($chargeIds)) {
            foreach ($chargeIds as $chargeId) {
                $subQuery[] = 'FIND_IN_SET(:chargeId'.$chargeId.', order_charges)';
                $subParams['chargeId'.$chargeId] = $chargeId;
            }

            $context->andHaving(implode(' OR ', $subQuery));
            $context->addParameters($subParams);
        }

        return $context;
    }

    /**
     * @param QueryBuilder $context
     */
    public function modifyPrefetchOnUse($context)
    {
        $context->addSubselect($this->getOrderChargesSubQuery(
            "concat_ws(',', 
            GROUP_CONCAT(json_extract(json_extract(note, '$.charge'), ('$.id_charge'))), 
            GROUP_CONCAT(replace(json_extract(note, '$.id_charge'), '\"', '')))"), 'order_charges');

        return $context;
    }

    private function getCharges(): array
    {
        $qb = sqlQueryBuilder()
            ->select('id, title, admin_title')
            ->from('charges')
            ->orderBy('title');

        $orderCharges = [];
        foreach ($qb->execute() as $item) {
            $orderCharges[] = ['value' => $item['id'], 'title' => $item['title'] ?: $item['admin_title']];
        }

        return $orderCharges;
    }

    private function getOrderChargesSubQuery(string $field): QueryBuilder
    {
        return sqlQueryBuilder()
            ->select($field)
            ->from('order_items', 'oi')
            ->where('oi.id_order = o.id');
    }
}
