<?php

namespace KupShop\ProductSetsBundle\Admin\Tabs;

use KupShop\AdminBundle\Admin\WindowTab;
use Query\Operator;

class ProductSetsWindowTab extends WindowTab
{
    protected $title = 'flapSets';

    protected $template = 'productSets.tpl';

    public static function getTypes()
    {
        return [
            'products' => 1,
        ];
    }

    public function getTemplate(): string
    {
        if (findModule(\Modules::PRODUCTS, \Modules::SUB_SETS) === 'js_multisets') {
            return 'products.multisets.tpl';
        }

        return parent::getTemplate();
    }

    public function getVars($smarty_tpl_vars)
    {
        $ID = $this->getID();

        $data['categories'] = sqlFetchAll(
            sqlQueryBuilder()
            ->select('id, name')
            ->from('set_categories')
            ->execute(),
            ['id' => 'name']
        );

        $qb = sqlQueryBuilder()
            ->select('sp.id as id_set, p.id, p.title, sp.category, sp.price')
            ->from('set_products', 'sp')
            ->leftJoin('sp', 'products', 'p', 'sp.id_product = p.id')
            ->where(Operator::equals(['id_product_master' => $ID]))
            ->orderBy('sp.category');

        $productVatId = $this->window->getObjectData()['vat'] ?? null;
        $productVat = getVat($productVatId);

        $data['products'] = [];
        foreach ($qb->execute() as $item) {
            if (!empty($item['price'])) {
                $item['price'] = toDecimal($item['price'])->addVat($productVat)->printFloatValue(2);
            }

            $data['products'][] = $item;
        }

        foreach ($data['products'] as &$product) {
            $qb = sqlQueryBuilder()
                ->select('pv.id, pv.title, psv.id as checked, psv.price')
                ->from('products_variations', 'pv')
                ->leftJoin('pv', 'set_products', 'ps', 'ps.id_product = pv.id_product')
                ->leftJoin('ps', 'set_products_variations', 'psv', 'psv.id_set_product = ps.id AND psv.id_variation = pv.id')
                ->join('pv', 'products_variations_combination', 'pvc', 'pvc.id_variation = pv.id')
                ->join('pvc', 'products_variations_choices_values', 'pvcv', 'pvcv.id = pvc.id_value')
                ->where(Operator::equals(['pv.id_product' => $product['id'], 'ps.id_product_master' => $ID]))
                ->groupBy('pv.id')
                ->orderBy('pvcv.sort');

            $product['variations'] = [];
            foreach ($qb->execute() as $variation) {
                if (!empty($variation['price'])) {
                    $variation['price'] = toDecimal($variation['price'])->addVat($productVat)->printFloatValue(2);
                }

                $product['variations'][] = $variation;
            }
        }

        return $data;
    }

    public function handleUpdate()
    {
        parent::handleUpdate();

        $data = $this->getData();

        sqlGetConnection()->transactional(function () use ($data) {
            $set = false;

            foreach ($data as $id => $product) {
                $product['id_product'] = intval($product['id_product']);
                $product['id_product_master'] = $this->getID();

                if (!empty($product['delete']) || !$id || $product['id_product'] <= 0) {
                    if ($id > 0) {
                        $this->deleteSQL('set_products', $this->filterFields($product, ['id_product', 'id_product_master']));
                    }
                    continue;
                }
                $set = true;

                $product['price'] = $this->prepareItemPrice($product);

                if ($id < 0) {
                    $this->insertSQL('set_products', $this->excludeFields($product, ['variations', 'id_set']), $this->filterFields($product, ['id_product', 'id_product_master']));
                    $product['id_product'] = sqlInsertId();
                } else {
                    $this->updateSQL('set_products', $this->excludeFields($product, ['variations', 'id_set']), $this->filterFields($product, ['id_product', 'id_product_master']));
                }

                if (!empty($product['variations'])) {
                    $this->deleteSQL('set_products_variations', ['id_set_product' => $product['id_set']]);

                    foreach ($product['variations'] as $variation => $val) {
                        // konrola pro pripad pouziti stare i nove sablony
                        if (($val['checked'] ?? '') === 'Y' || $val === 'Y') {
                            $insert = [
                                'id_set_product' => $product['id_set'],
                                'id_variation' => $variation,
                            ];
                            if (findModule(\Modules::PRODUCTS, \Modules::SUB_SETS) === 'js_multisets') {
                                $insert['price'] = $this->prepareItemPrice($val);
                            }

                            $this->insertSQL('set_products_variations', $insert);
                        }
                    }
                }
            }

            sqlQueryBuilder()
                ->update('products')
                ->set('campaign', $set ? 'ADD_TO_SET("PS", campaign)' : 'REMOVE_FROM_SET("PS", campaign)')
                ->where(Operator::equals(['id' => $this->getID()]))
                ->execute();
        });
    }

    private function prepareItemPrice(array $item): ?float
    {
        $productData = getVal('data', default: []);

        if (array_key_exists('price', $item)) {
            if ($price = $this->preparePrice($item['price'])) {
                return toDecimal($price)->removeVat(getVat($productData['vat']))->asFloat();
            }
        }

        return null;
    }
}
