<?php

declare(strict_types=1);

return static function (string $tableSuffix): callable {
    return static function (PDO $pdo) use ($tableSuffix): void {
        $systemRoot = dirname(__DIR__, 2);       // app/system
        $appRoot = dirname(__DIR__, 3);          // app
        require_once $systemRoot . '/support/Support.php';
        require_once $systemRoot . '/mic/MicElementResolverInterface.php';
        require_once $systemRoot . '/mic/MicElementSearchable.php';
        require_once $systemRoot . '/mic/MicElementRegistry.php';
        require_once $systemRoot . '/mic/SearchTextExtractor.php';
        require_once $appRoot . '/modules/search/SearchIndexService.php';
        require_once $appRoot . '/modules/search/SearchIndexer.php';

        $driver = (string) $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
        $tableExists = static function (string $table) use ($pdo, $driver): bool {
            if ($driver === 'sqlite') {
                $statement = $pdo->query("SELECT name FROM sqlite_master WHERE type='table' AND name=" . $pdo->quote($table));
                return $statement !== false && $statement->fetchColumn() !== false;
            }
            $statement = $pdo->prepare('SHOW TABLES LIKE :table');
            $statement->execute([':table' => $table]);
            return $statement->fetchColumn() !== false;
        };

        if (!$tableExists('search_documents') || !$tableExists('pages') || !$tableExists('page_versions')) {
            // Cannot backfill until the schema is in place; the prior migration handles that.
            return;
        }

        $registry = function_exists('myronMicElementRegistry') ? myronMicElementRegistry() : new MicElementRegistry();
        $extractor = new MyronSearchTextExtractor($registry);
        $service = new MyronSearchIndexService($pdo);
        $indexer = new MyronSearchIndexer($pdo, $service, $extractor);

        $indexedCount = static function (string $pageId) use ($pdo): int {
            $statement = $pdo->prepare("SELECT COUNT(*) FROM search_documents WHERE entity_type = 'page' AND entity_id = :id");
            $statement->execute([':id' => $pageId]);
            return (int) $statement->fetchColumn();
        };

        $summary = [
            'processed' => 0,
            'indexed' => 0,
            'skipped' => 0,
            'errors' => 0,
        ];

        $pageIds = $indexer->listAllPublishedPageIds();
        foreach ($pageIds as $pageId) {
            $summary['processed']++;
            try {
                $indexer->indexPageById($pageId);
                if ($indexedCount($pageId) > 0) {
                    $summary['indexed']++;
                } else {
                    $summary['skipped']++;
                }
            } catch (Throwable $e) {
                $summary['errors']++;
                error_log('[search-backfill] indexPageById failed for ' . $pageId . ': ' . $e->getMessage());
            }
        }

        error_log('[search-backfill] APO-269 summary: ' . json_encode($summary, JSON_UNESCAPED_SLASHES));
    };
};
