<?php

declare(strict_types=1);

namespace App\Infrastructure\Db\Migrations;

use Phinx\Db\Table;
use Phinx\Migration\AbstractMigration;
use Phinx\Util\Literal;

/**
 * Shared helpers for IRDB migrations.
 *
 * Hides per-adapter quirks: timestamp columns must be DATETIME(6) on MySQL but
 * plain TEXT (ISO-8601) on SQLite; binary columns must accept exactly 16 raw
 * bytes; default expressions need a Phinx Literal so they're emitted unquoted.
 */
abstract class BaseMigration extends AbstractMigration
{
    protected function isMysql(): bool
    {
        return $this->getAdapter()->getAdapterType() === 'mysql';
    }

    /**
     * Add a UTC timestamp column. MySQL gets DATETIME(6); SQLite gets the
     * datetime affinity (TEXT) per SPEC §4.
     *
     * @param array<string, mixed> $extra Extra Phinx column options (e.g. ['null' => true]).
     */
    protected function addTimestampColumn(Table $table, string $name, array $extra = []): Table
    {
        $opts = $extra;

        if ($this->isMysql()) {
            $opts['precision'] = 6;
        }

        if (!array_key_exists('default', $opts) && (!array_key_exists('null', $opts) || $opts['null'] === false)) {
            $opts['default'] = $this->isMysql()
                ? Literal::from('CURRENT_TIMESTAMP(6)')
                : Literal::from('CURRENT_TIMESTAMP');
        }

        return $table->addColumn($name, 'datetime', $opts);
    }

    /**
     * 16-byte binary column for IP/network storage.
     *
     * @param array<string, mixed> $extra
     */
    protected function addIpBinaryColumn(Table $table, string $name, array $extra = []): Table
    {
        $opts = array_merge(['limit' => 16], $extra);

        return $table->addColumn($name, 'binary', $opts);
    }
}
