<?php
namespace Autogedal\AutogedalHelper\Plugin;

use Magento\Framework\DB\Select;
use Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory;
use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as SalesOrderGridCollection;
use Magento\Framework\App\DeploymentConfig;

class GridJoinCollection
{
    private $collection;
    private $deploymentConfig;

    public function __construct(
        SalesOrderGridCollection $collection,
        DeploymentConfig $deploymentConfig
    ) {

        $this->collection = $collection;
        $this->deploymentConfig = $deploymentConfig;
    }

    public function afterGetReport(
        CollectionFactory $subject,
        $collection,
        $requestName
    ) {
        if (($requestName === 'sales_order_grid_data_source') && $collection instanceof $this->collection
            && !$collection->getFlag('smartbill_filter')
        ) {
            $select = $collection->getSelect();
            $columns = $select->getPart(Select::COLUMNS);

            if (count(array_intersect(['soa_telephone', 'soi_sku'], $this->filterForTableNames($columns))) === 0) {
                $select->joinLeft(
                    ['admin_user'],
                    'main_table.autogedal_operator_id = admin_user.user_id',
                    ['operator_name' => new \Zend_Db_Expr("CONCAT(admin_user.firstname, ' ', admin_user.lastname)")]
                );
                $select->join(
                    ["soa_telephone" => $this->deploymentConfig->get('db/table_prefix') . "sales_order_address"],
                    'main_table.entity_id = soa_telephone.parent_id AND soa_telephone.address_type="shipping"',
                    array('telephone')
                );
                $select->join(
                    ['soi_sku' => 'sales_order_item'],
                    'soi_sku.order_id=`main_table`.entity_id AND soi_sku.product_type="simple"',
                    [
                        'sku' => new \Zend_Db_Expr('group_concat(soi_sku.sku SEPARATOR " | ")')
                    ]
                    );
                $select->joinLeft(
                    ['soi_sku_bundle' => 'sales_order_item'],
                    'soi_sku_bundle.order_id=`main_table`.entity_id AND soi_sku_bundle.product_type="bundle"',
                    [
                        'bundle_sku' => new \Zend_Db_Expr('soi_sku_bundle.sku')
                    ]
                )->distinct();
            }
            $select->group('main_table.entity_id');
            $collection->setFlag('smartbill_filter', true);
            return $collection;
        }

        if (($requestName === 'aitoc_deleteorders_archive_listing_data_source') &&
            $collection instanceof \Aitoc\DeleteOrders\Model\ResourceModel\Archive\Grid\Collection && !$collection->getFlag('smartbill_filter')
        ) {
            $select = $collection->getSelect();
            $columns = $select->getPart(Select::COLUMNS);

            if (count(array_intersect(['soa_telephone', 'soi_sku'], $this->filterForTableNames($columns))) === 0) {
                $select->join(
                    ["soa_telephone" => $this->deploymentConfig->get('db/table_prefix') . "sales_order_address"],
                    'main_table.order_id = soa_telephone.parent_id AND soa_telephone.address_type="shipping"',
                    array('telephone')
                );
                $select->join(
                    ['soi_sku' => 'sales_order_item'],
                    'soi_sku.order_id=`main_table`.order_id AND soi_sku.product_type="simple"',
                    [
                        'sku' => new \Zend_Db_Expr('group_concat(soi_sku.sku SEPARATOR " | ")')
                    ]
                    );
                $select->joinLeft(
                    ['soi_sku_bundle' => 'sales_order_item'],
                    'soi_sku_bundle.order_id=`main_table`.order_id AND soi_sku_bundle.product_type="bundle"',
                    [
                        'bundle_sku' => new \Zend_Db_Expr('soi_sku_bundle.sku')
                    ]
                )->distinct();
            }
            $select->group('main_table.order_id');
            $collection->setFlag('smartbill_filter', true);
            return $collection;
        }
        return $collection;
    }

    private function filterForTableNames(array $columns): array
    {
        $tableNames = [];
        foreach ($columns as $column) {
            $tableNames[] = $column[0];
        }
        return $tableNames;
    }
}