<?php

namespace MintyPHP\Repository\Module;

use MintyPHP\DB;

/**
 * Manages the module_migrations tracking table.
 *
 * All SQL for module migration tracking lives here (strict layering).
 */
final class ModuleMigrationRepository implements ModuleMigrationRepositoryInterface
{
    public function ensureTrackingTable(): void
    {
        DB::query(
            'CREATE TABLE IF NOT EXISTS `module_migrations` (
                `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
                `module_id` VARCHAR(64) NOT NULL,
                `filename` VARCHAR(255) NOT NULL,
                `applied_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (`id`),
                UNIQUE KEY `uq_module_migration` (`module_id`, `filename`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci'
        );
    }

    /**
     * @return array<string, true> Filenames already applied, keyed by filename
     */
    public function getAppliedFilenames(string $moduleId): array
    {
        $applied = [];
        $rows = DB::select('SELECT filename FROM module_migrations WHERE module_id = ?', $moduleId);
        foreach ((array) $rows as $row) {
            if (!is_array($row)) {
                continue;
            }
            $filename = trim((string) (($row['module_migrations']['filename'] ?? $row['filename'] ?? '')));
            if ($filename !== '') {
                $applied[$filename] = true;
            }
        }
        return $applied;
    }

    public function recordApplied(string $moduleId, string $filename): void
    {
        DB::query(
            'INSERT INTO module_migrations (module_id, filename) VALUES (?, ?)',
            $moduleId,
            $filename
        );
    }

    public function beginTransaction(): void
    {
        DB::query('START TRANSACTION');
    }

    public function commit(): void
    {
        DB::query('COMMIT');
    }

    public function rollback(): void
    {
        DB::query('ROLLBACK');
    }

    public function executeStatement(string $sql): void
    {
        DB::query($sql);
    }
}
