<?php

namespace MintyPHP\Console\Commands\Database;

use MintyPHP\Console\Commands\Module\AbstractModuleCommand;
use MintyPHP\Console\Runner\Module\ModuleRunnerInterface;

/**
 * Apply pending core SQL migrations from db/updates/.
 *
 * Mirror of `module:migrate` for core schema changes. Each `db/updates/*.sql`
 * file MUST be idempotent; applied filenames are tracked in `core_migrations`.
 *
 * `--status` prints applied/pending lists without running anything.
 */
final class MigrateCommand extends AbstractModuleCommand
{
    public function __construct(?ModuleRunnerInterface $moduleRunner = null)
    {
        parent::__construct($moduleRunner);
    }

    public function name(): string
    {
        return 'db:migrate';
    }

    public function description(): string
    {
        return 'Apply pending core SQL migrations from db/updates/';
    }

    public function usage(): string
    {
        return <<<'USAGE'
        Usage: php bin/console db:migrate [--status]

        Options:
          --status    Print applied / pending migration filenames without running anything

        Each file under db/updates/*.sql is applied at most once and tracked in
        the core_migrations table. Files MUST be idempotent (e.g. CREATE TABLE
        IF NOT EXISTS, INSERT … ON DUPLICATE KEY UPDATE) so first-run on an
        existing schema is a no-op.

        `bin/console module:sync` runs db:migrate as its first step.
        USAGE;
    }

    public function execute(array $args, array $options): int
    {
        if (!empty($options['status'])) {
            $status = $this->moduleRunner()->dbMigrateStatus();

            $appliedCount = count($status['applied']);
            $pendingCount = count($status['pending']);

            echo sprintf("db-migrate-status: %d applied, %d pending\n\n", $appliedCount, $pendingCount);

            echo "applied:\n";
            if ($appliedCount === 0) {
                echo "  (none)\n";
            } else {
                foreach ($status['applied'] as $filename) {
                    echo '  ' . $filename . PHP_EOL;
                }
            }

            echo "\npending:\n";
            if ($pendingCount === 0) {
                echo "  (none)\n";
            } else {
                foreach ($status['pending'] as $filename) {
                    echo '  ' . $filename . PHP_EOL;
                }
            }

            return 0;
        }

        $result = $this->moduleRunner()->dbMigrate();
        if ($result['exit_code'] === 0) {
            echo $result['message'] . PHP_EOL;
        } else {
            fwrite(STDERR, $result['message'] . PHP_EOL);
        }

        return (int) $result['exit_code'];
    }
}
