<?php

namespace MintyPHP\Tests\Architecture;

use PHPUnit\Framework\TestCase;

class StatusTaxonomyContractTest extends TestCase
{
    use ProjectFileAssertionSupport;

    /**
     * @return list<string>
     */
    private function taxonomyEnumFiles(): array
    {
        return [
            'lib/Domain/Taxonomy/SystemAuditOutcome.php',
            'lib/Domain/Taxonomy/SystemAuditChannel.php',
            'lib/Domain/Taxonomy/UserLifecycleAction.php',
            'lib/Domain/Taxonomy/UserLifecycleTriggerType.php',
            'lib/Domain/Taxonomy/UserLifecycleStatus.php',
            'lib/Domain/Taxonomy/ImportAuditStatus.php',
            'lib/Domain/Taxonomy/ScheduledJobStatus.php',
            'lib/Domain/Taxonomy/ScheduledJobRunStatus.php',
            'lib/Domain/Taxonomy/ScheduledJobTriggerType.php',
            'lib/Domain/Taxonomy/MailLogStatus.php',
            'lib/Domain/Taxonomy/TenantStatus.php',
            'lib/Domain/Taxonomy/SchedulerRuntimeResult.php',
        ];
    }

    /**
     * @return array<string,list<string>>
     */
    private function taxonomySchemaExpectations(): array
    {
        return [
            'pages/admin/system-audit/filter-schema.php' => [
                'SystemAuditOutcome::values()',
                'SystemAuditChannel::values()',
            ],
            'pages/admin/user-lifecycle-audit/filter-schema.php' => [
                'gridEnumSanitizer(UserLifecycleAction::class)',
                'gridEnumSanitizer(UserLifecycleStatus::class)',
                'gridEnumSanitizer(UserLifecycleTriggerType::class)',
            ],
            'pages/admin/import-audit/filter-schema.php' => [
                'ImportAuditStatus::values()',
            ],
            'pages/admin/scheduled-jobs/filter-schema.php' => [
                'ScheduledJobStatus::values()',
            ],
            'pages/admin/scheduled-jobs/runs-filter-schema.php' => [
                'ScheduledJobRunStatus::values()',
                'ScheduledJobTriggerType::values()',
            ],
            'pages/admin/mail-log/filter-schema.php' => [
                'MailLogStatus::values()',
            ],
        ];
    }

    /**
     * @return list<string>
     */
    private function taxonomyDataEndpointFiles(): array
    {
        return [
            'pages/admin/system-audit/data().php',
            'pages/admin/user-lifecycle-audit/data().php',
            'pages/admin/import-audit/data().php',
            'pages/admin/scheduled-jobs/data().php',
            'pages/admin/scheduled-jobs/runs-data($id).php',
            'pages/admin/mail-log/data().php',
            'pages/admin/tenants/data().php',
        ];
    }

    /**
     * @return list<string>
     */
    private function taxonomyLiteralGuardFiles(): array
    {
        return [
            'lib/Service/Audit/SystemAuditService.php',
            'lib/Repository/Audit/SystemAuditLogRepository.php',
            'lib/Http/ApiSystemAuditReporter.php',
            'lib/Service/Audit/UserLifecycleAuditService.php',
            'lib/Repository/Audit/UserLifecycleAuditRepository.php',
            'lib/Service/Audit/ImportAuditService.php',
            'lib/Repository/Audit/ImportAuditRunRepository.php',
            'lib/Service/Scheduler/SchedulerRunService.php',
            'lib/Repository/Scheduler/ScheduledJobRepository.php',
            'lib/Repository/Scheduler/ScheduledJobRunRepository.php',
            'lib/Repository/Scheduler/SchedulerRuntimeRepository.php',
            'lib/Service/Mail/MailService.php',
            'lib/Repository/Mail/MailLogRepository.php',
            'lib/Service/Tenant/TenantService.php',
            'lib/Repository/Tenant/TenantRepository.php',
            'lib/Repository/Stats/AdminStatsRepository.php',
            'pages/admin/system-audit/data().php',
            'pages/admin/user-lifecycle-audit/data().php',
            'pages/admin/import-audit/data().php',
            'pages/admin/scheduled-jobs/data().php',
            'pages/admin/scheduled-jobs/runs-data($id).php',
            'pages/admin/mail-log/data().php',
            'pages/admin/tenants/data().php',
            'pages/admin/system-audit/index().php',
            'pages/admin/user-lifecycle-audit/index().php',
            'pages/admin/import-audit/index().php',
            'pages/admin/scheduled-jobs/index().php',
            'pages/admin/mail-log/index().php',
        ];
    }

    public function testTaxonomyEnumFilesUseSharedTraitAndRequiredMethods(): void
    {
        foreach ($this->taxonomyEnumFiles() as $file) {
            $content = $this->readProjectFile($file);
            $this->assertStringContainsString('enum ', $content, $file);
            $this->assertStringContainsString('use SupportsStringTaxonomy;', $content, $file);
            $this->assertStringContainsString('function labelToken()', $content, $file);
            $this->assertStringContainsString('function badgeVariant()', $content, $file);
        }
    }

    public function testFilterSchemasReadTaxonomyValuesFromEnums(): void
    {
        foreach ($this->taxonomySchemaExpectations() as $file => $snippets) {
            $content = $this->readProjectFile($file);
            foreach ($snippets as $snippet) {
                $this->assertStringContainsString($snippet, $content, $file);
            }
        }
    }

    public function testDataEndpointsUseEnumBasedBadgeAndLabelResolution(): void
    {
        foreach ($this->taxonomyDataEndpointFiles() as $file) {
            $content = $this->readProjectFile($file);
            $this->assertStringContainsString('->badgeVariant()', $content, $file);
            $this->assertStringContainsString('->labelToken()', $content, $file);
        }
    }

    public function testNoLegacyLiteralTaxonomyChecksRemainInMigratedFiles(): void
    {
        $forbiddenPatterns = [
            "/\\bstatus\\s*=\\s*'(running|success|partial|failed|skipped|queued|sent|active|inactive)'/",
            "/\\boutcome\\s*=\\s*'(success|failed|denied)'/",
            "/\\bchannel\\s*=\\s*'(web|api|scheduler|cli)'/",
            "/\\btrigger_type\\s*=\\s*'(scheduler|manual|cron|system)'/",
            "/\\baction\\s*=\\s*'(deactivate|delete|restore)'/",
            "/['\\\"]statuses['\\\"]\\s*=>\\s*'failed,skipped'/",
            "/['\\\"]actions['\\\"]\\s*=>\\s*'restore'/",
            "/in_array\\([^\\n]*\\[(?:[^\\]]*'(?:success|failed|denied|running|partial|skipped|queued|sent|active|inactive|scheduler|manual|web|api|cli|deactivate|delete|restore|ok|lock_not_acquired|unexpected_error)')/",
        ];

        foreach ($this->taxonomyLiteralGuardFiles() as $file) {
            $content = $this->readProjectFile($file);
            foreach ($forbiddenPatterns as $pattern) {
                $this->assertSame(0, preg_match($pattern, $content), $file . ' pattern=' . $pattern);
            }
        }
    }

    public function testImportAuditIndexTemplateDoesNotUseLegacyStatusMapper(): void
    {
        $content = $this->readProjectFile('pages/admin/import-audit/index(default).phtml');
        $moduleContent = $this->readProjectFile('web/js/pages/admin-import-audit-index.js');
        $this->assertStringNotContainsString('const statusLabel = (value) =>', $moduleContent);
        $this->assertStringNotContainsString("if (key === 'running')", $moduleContent);
        $this->assertStringContainsString('cell.label || \'-\'', $moduleContent);
        $this->assertStringContainsString("assetVersion('js/pages/admin-import-audit-index.js')", $content);
    }
}
