<?php

declare(strict_types=1);

final class MyronMigrationOperationsService
{
    public function __construct(
        private readonly PDO $pdo,
        private readonly MyronModulePackageInstallLedger $moduleLedger,
        private readonly MyronModuleRegistry $moduleRegistry,
    ) {
    }

    /** @return array<string, mixed> */
    public function status(): array
    {
        $status = MyronMigrationRunner::status($this->pdo);
        $handoffs = $this->moduleLedger->pendingBootstrapMigrations();

        return [
            'registered' => $status['registered'],
            'applied' => $status['applied'],
            'pending' => $status['pending'],
            'registeredCount' => count($status['registered']),
            'appliedCount' => count($status['applied']),
            'pendingCount' => count($status['pending']),
            'hasPending' => $status['pending'] !== [] || $handoffs !== [],
            'moduleHandoffs' => $handoffs,
        ];
    }

    /** @return array<string, mixed> */
    public function applyPending(): array
    {
        $before = $this->status();
        $report = MyronMigrationRunner::migrateWithReport($this->pdo);
        $reconciledSkus = [];
        if ($report['pending'] === []) {
            $reconciledSkus = $this->moduleLedger->reconcileBootstrapMigrations(
                $this->moduleRegistry->presentModules()
            );
        }
        $after = $this->status();

        return [
            'outcome' => $report['appliedNow'] === [] && $reconciledSkus === [] ? 'up_to_date' : 'applied',
            'pendingBefore' => $before['pending'],
            'appliedNow' => $report['appliedNow'],
            'remainingPending' => $after['pending'],
            'reconciledModuleSkus' => $reconciledSkus,
            'moduleHandoffs' => $after['moduleHandoffs'],
            'hasPending' => $after['hasPending'],
        ];
    }
}
