<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Installer\Database;

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;

if (!defined('_PS_VERSION_')) {
    exit;
}

abstract class AbstractMigration implements MigrationInterface
{
    /**
     * @var string
     */
    private $dbPrefix;

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

    final public function __construct(string $dbPrefix, string $dbEngine)
    {
        $this->dbPrefix = $dbPrefix;
        $this->dbEngine = $dbEngine;
    }

    /**
     * @return static
     *
     * @internal
     */
    public static function create(): MigrationInterface
    {
        return new static(_DB_PREFIX_, _MYSQL_ENGINE_);
    }

    public function down(Schema $schema): void
    {
    }

    protected function prefixTableName(string $name): string
    {
        return $this->dbPrefix . $name;
    }

    protected function createTable(Schema $schema, string $name): Table
    {
        $name = $this->prefixTableName($name);
        if ($schema->hasTable($name)) {
            return $schema->getTable($name);
        }

        return $schema
            ->createTable($name)
            ->addOption('engine', $this->dbEngine);
    }

    protected function dropTable(Schema $schema, string $name): void
    {
        $name = $this->prefixTableName($name);
        if ($schema->hasTable($name)) {
            $schema->dropTable($name);
        }
    }

    protected function addColumn(Table $table, string $name, string $type): Column
    {
        if ($table->hasColumn($name)) {
            return $table->getColumn($name);
        }

        return $table->addColumn($name, $type);
    }

    /**
     * @param string[] $columns
     */
    protected function setPrimaryKey(Table $table, array $columns): void
    {
        $primaryKey = $table->getPrimaryKey();
        if (null !== $primaryKey) {
            if ($columns === $primaryKey->getColumns()) {
                return;
            }

            $table->dropPrimaryKey();
        }

        $table->setPrimaryKey($columns);
    }

    protected function addIndex(Table $table, array $columns, string $name = null): void
    {
        foreach ($table->getIndexes() as $index) {
            if ($index->spansColumns($columns)) {
                return;
            }
        }

        $table->addIndex($columns, $name);
    }
}
