<?php

declare(strict_types=1);

final class MyronDashboardReadModel
{
    public function __construct(
        private readonly MyronContentRepository $content,
        private readonly MyronFileRepository $files,
        private readonly MyronAuthRepository $auth,
        private readonly MyronLicenseRepository $license,
        private readonly MyronMailSettingsRepository $mail,
        private readonly MyronAiIntegrationRepository $aiIntegrations,
        private readonly MyronAuditLogRepository $auditLog,
        private readonly MyronSiteSettingsRepository $settings,
        private readonly MyronComponentRegistryRepository $components,
        private readonly MyronSectionRegistryRepository $sections,
        private readonly MyronTemplateDefinitionRepository $templates,
        private readonly MyronTokenPatchRepository $tokenPatches,
        private readonly MyronCurrentSiteUsageReadModel $siteUsage,
    ) {
    }

    /**
     * @return array<string, mixed>
     */
    public function administrationSummary(): array
    {
        $snapshot = $this->license->currentSnapshot();
        $users = $this->auth->listUsers();
        $aiConnections = $this->activeAiConnections();
        $settings = $this->settings->getSettings();

        return [
            'license' => [
                'plan' => $snapshot->plan,
                'status' => $snapshot->status,
                'lastValidatedAt' => $snapshot->lastValidatedAt,
                'environment' => $snapshot->environment,
                'href' => myronBuildAdminUrl('administration.license'),
            ],
            'team' => [
                'total' => count($users),
                'administrators' => count(array_filter($users, static fn (array $user): bool => myronUserCanAccessAdministration($user))),
                'content' => count(array_filter($users, static fn (array $user): bool => myronUserCanAccessContent($user))),
                'design' => count(array_filter($users, static fn (array $user): bool => myronUserCanAccessDesign($user))),
                'href' => myronBuildAdminUrl('identity.users'),
            ],
            'aiActivity' => [
                'events24h' => $this->auditLog->countAiEventsSince(gmdate('Y-m-d H:i:s', time() - 86400)),
                'connections' => count($aiConnections),
                'href' => myronBuildAdminUrl('administration.auditLog'),
            ],
            'system' => [
                'siteTitle' => (string) ($settings['site_title'] ?? 'MyronCMS'),
                'mailConfigured' => $this->mail->isConfigured(),
                'aiConfigured' => $aiConnections !== [],
                'settingsHref' => myronBuildAdminUrl('administration.siteSettings'),
                'mailHref' => myronBuildAdminUrl('administration.mail'),
                'aiHref' => myronBuildAdminUrl('administration.aiConnections'),
            ],
        ];
    }

    /**
     * @return array<string, mixed>
     */
    public function contentSummary(): array
    {
        $pagesByState = $this->content->countPagesByPublicationState();
        $filesByClass = $this->files->countFilesByMediaClass();
        $pages = $this->content->listPages();
        usort($pages, static fn (array $a, array $b): int => strcmp((string) ($b['updated_at'] ?? ''), (string) ($a['updated_at'] ?? '')));

        return [
            'pages' => [
                'published' => (int) ($pagesByState['published'] ?? 0),
                'draft' => (int) ($pagesByState['draft'] ?? 0),
                'total' => array_sum($pagesByState),
                'href' => myronBuildAdminUrl('content.pages'),
            ],
            'assets' => [
                'image' => (int) ($filesByClass['image'] ?? 0),
                'video' => (int) ($filesByClass['video'] ?? 0),
                'audio' => (int) ($filesByClass['audio'] ?? 0),
                'document' => (int) ($filesByClass['document'] ?? 0),
                'href' => myronBuildAdminUrl('content.files'),
            ],
            'structure' => [
                'categories' => count($this->content->listPageCategories(false)),
                'menus' => count($this->content->listMenusWithItems()),
                'categoriesHref' => myronBuildAdminUrl('content.categories'),
                'menusHref' => myronBuildAdminUrl('content.menus'),
            ],
            'recent' => [
                'pages' => array_slice($pages, 0, 3),
                'href' => myronBuildAdminUrl('content.pages'),
            ],
        ];
    }

    /**
     * @return array<string, mixed>
     */
    public function designSummary(): array
    {
        $patches = $this->tokenPatches->listPatchesByToken();
        $usageIndex = array_values($this->siteUsage->templateUsageIndex());
        usort($usageIndex, static fn (array $a, array $b): int => ((int) ($b['pageCount'] ?? 0)) <=> ((int) ($a['pageCount'] ?? 0)));

        return [
            'inventory' => [
                'components' => $this->components->countComponents(),
                'sections' => $this->sections->countSections(),
                'templates' => $this->templates->countTemplates(),
                'href' => myronBuildAdminUrl('design.templateStudioSiteTemplates'),
            ],
            'tokens' => [
                'customized' => count($patches),
                'href' => myronBuildAdminUrl('design.systems'),
            ],
            'coverage' => [
                'topTemplates' => array_slice($usageIndex, 0, 3),
                'href' => myronBuildAdminUrl('content.templates'),
            ],
        ];
    }

    /**
     * @return list<MyronAiIntegration>
     */
    private function activeAiConnections(): array
    {
        return array_values(array_filter(
            $this->aiIntegrations->listAll(),
            static fn (MyronAiIntegration $integration): bool => !$integration->isRevoked()
        ));
    }
}
