<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Remote;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Ddl\Table;
use Zend_Db_Exception;
use Zend_Db_Expr;

/**
 *
 */
class BasesSqlDeletedItemFinder implements DeletedItemFinderInterface
{
    /**
     * @var string
     */
    private $table;

    /**
     * @var string
     */
    private $idColumn;

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;
    /**
     * @var int
     */
    private $chunkSize;

    /**
     * @param ResourceConnection $resourceConnection
     * @param string $table
     * @param string $idColumn
     * @param int $chunkSize
     */
    public function __construct(
        ResourceConnection $resourceConnection,
        string             $table,
        string             $idColumn,
        int                $chunkSize = 1000
    )
    {
        $this->table = $table;
        $this->idColumn = $idColumn;
        $this->resourceConnection = $resourceConnection;
        $this->chunkSize = $chunkSize;
    }

    /**
     * @return array
     * @throws Zend_Db_Exception
     */
    public function getDeletedIds(): array
    {
        $connection = $this->resourceConnection->getConnection();
        $mainTable = $connection->getTableName($this->table);
        $idColumn = $this->idColumn;

        $row = $connection->fetchRow(
            $connection->select()->from($mainTable, [
                'max' => new Zend_Db_Expr("MAX($idColumn)"),
                'total' => new Zend_Db_Expr("COUNT($idColumn)")
            ])
        );

        $max = max((int)$row['max'], (int)$row['total']);
        $remainder = $max % $this->chunkSize;
        $times = ($max - $remainder) / $this->chunkSize;

        if ($remainder > 0) {
            $times++;
        }
        $output = [];

        $preparedStatement = $connection->select()->from($mainTable, [$idColumn])->where("$idColumn >= :start")->where("$idColumn <= :end");

        foreach (range(1, $times) as $i) {

            $start = 1 + (($i - 1) * $this->chunkSize);
            $end = $i * $this->chunkSize;

            $total = $connection->fetchCol($preparedStatement, [':start' => $start, ':end' => $end]);

            if (count($total) == $this->chunkSize) {
                continue;
            }
            foreach (array_diff(range($start, $end), $total) as $w) {
                $output[] = $w;
            }
        }

        return $output;
    }

    /**
     * @return Table
     * @throws Zend_Db_Exception
     */
    public function createTemporaryTable(): Table
    {
        $connection = $this->resourceConnection->getConnection();
        $tableName = $this->table . '_' . str_replace('.', '_', uniqid('tmp', true));
        $table = $connection->newTable($tableName);
        $table->addColumn(
            $this->idColumn,
            Table::TYPE_INTEGER,
            10,
            ['unsigned' => true, 'nullable' => false, 'primary' => true, 'auto_increment' => true],
            'Entity ID'
        );

        $table->setOption('type', 'memory');
        $connection->createTemporaryTable($table);
        return $table;
    }
}
