<?php
/**
 * Door 7 — Bricks design-system baseline facts for LolaCore memory.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks;

use LolaCore\Addon\Contract\MemoryBootstrapInterface;
use LolaCoreForBricks\Support\BricksMemoryMetrics;
use LolaCoreForBricks\Support\DesignConventionStore;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Seeds live Bricks inventory and convention facts into memory.
 */
class MemoryBootstrap implements MemoryBootstrapInterface
{
    public function __construct(
        private readonly ?BricksMemoryMetrics $metrics = null
    ) {
    }

    public function addonSlug(): string
    {
        return AbilitiesProvider::CATEGORY;
    }

    public function refreshInterval(): int
    {
        return DAY_IN_SECONDS;
    }

    public function generateBaselineFacts(): array
    {
        if (!BricksEnv::isAvailable() || !BricksEnv::meetsFloor()) {
            return [];
        }

        $metrics = $this->metrics()->collect();
        if ($metrics === null) {
            return [];
        }

        $facts = [
            $this->classesFact($metrics),
            $this->variablesFact($metrics),
            $this->conventionFact($metrics),
            $this->frameworkFact($metrics),
            $this->componentsFact($metrics),
            $this->templatesFact($metrics),
            $this->cssLoadingFact($metrics),
            $this->coverageFact($metrics),
        ];

        return array_values(array_filter($facts));
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, int>}|null
     */
    private function classesFact(array $metrics): ?array
    {
        $total  = (int) ($metrics['global_classes_total'] ?? 0);
        $unused = (int) ($metrics['global_classes_unused'] ?? 0);

        return [
            'content'         => sprintf(
                'Bricks global classes: %d total, %d with no indexed usage.',
                $total,
                $unused
            ),
            'fact_type'       => 'bootstrap',
            'importance'      => 8,
            'structured_data' => [
                'global_classes_total'  => $total,
                'global_classes_unused' => $unused,
            ],
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, int>}|null
     */
    private function variablesFact(array $metrics): ?array
    {
        $total  = (int) ($metrics['variables_total'] ?? 0);
        $unused = (int) ($metrics['variables_unused'] ?? 0);

        return [
            'content'         => sprintf(
                'Bricks global variables: %d total, %d with no indexed references.',
                $total,
                $unused
            ),
            'fact_type'       => 'bootstrap',
            'importance'      => 8,
            'structured_data' => [
                'variables_total'  => $total,
                'variables_unused' => $unused,
            ],
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, mixed>}|null
     */
    private function conventionFact(array $metrics): ?array
    {
        $convention = is_array($metrics['convention'] ?? null) ? $metrics['convention'] : [];
        $pattern    = trim((string) ($convention['naming_pattern'] ?? ''));
        if ($pattern === '') {
            return null;
        }

        return [
            'content'         => sprintf(
                'Bricks naming convention on this site: pattern %s. Variable policy: %s.',
                $pattern,
                (string) ($convention['variable_policy'] ?? 'not specified')
            ),
            'fact_type'       => 'bootstrap',
            'importance'      => 9,
            'structured_data' => [
                'naming_pattern'  => $pattern,
                'variable_policy' => (string) ($convention['variable_policy'] ?? ''),
            ],
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, mixed>}|null
     */
    private function frameworkFact(array $metrics): ?array
    {
        $stored = trim((string) (is_array($metrics['convention'] ?? null) ? ($metrics['convention']['external_framework'] ?? '') : ''));
        if ($stored !== '') {
            return [
                'content'         => sprintf('External class framework recorded for this Bricks site: %s.', $stored),
                'fact_type'       => 'bootstrap',
                'importance'      => 7,
                'structured_data' => ['external_framework' => $stored],
            ];
        }

        $detected = is_array($metrics['detected_framework'] ?? null) ? $metrics['detected_framework'] : null;
        if ($detected === null) {
            return null;
        }

        return [
            'content'         => sprintf(
                'Detected external class naming on this Bricks site: %s (%d%% confidence).',
                (string) ($detected['framework'] ?? 'unknown'),
                (int) ($detected['confidence'] ?? 0)
            ),
            'fact_type'       => 'bootstrap',
            'importance'      => 7,
            'structured_data' => $detected,
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, int>}|null
     */
    private function componentsFact(array $metrics): ?array
    {
        $total = (int) ($metrics['components_total'] ?? 0);

        return [
            'content'         => sprintf('Bricks components library: %d reusable components.', $total),
            'fact_type'       => 'bootstrap',
            'importance'      => 6,
            'structured_data' => ['components_total' => $total],
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, int>}|null
     */
    private function templatesFact(array $metrics): ?array
    {
        $total = (int) ($metrics['templates_total'] ?? 0);

        return [
            'content'         => sprintf('Bricks templates: %d published templates.', $total),
            'fact_type'       => 'bootstrap',
            'importance'      => 6,
            'structured_data' => ['templates_total' => $total],
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, string>}|null
     */
    private function cssLoadingFact(array $metrics): ?array
    {
        $mode = (string) ($metrics['css_loading'] ?? 'inline');

        return [
            'content'         => sprintf('Bricks CSS loading mode: %s.', $mode),
            'fact_type'       => 'bootstrap',
            'importance'      => 7,
            'structured_data' => ['css_loading' => $mode],
        ];
    }

    /**
     * @param array<string, mixed> $metrics
     * @return array{content: string, fact_type: string, importance: int, structured_data: array<string, mixed>}|null
     */
    private function coverageFact(array $metrics): ?array
    {
        $coverage = is_array($metrics['index_coverage'] ?? null) ? $metrics['index_coverage'] : [];
        $complete = (bool) ($coverage['complete'] ?? false);
        $percent  = isset($coverage['percent']) ? (int) $coverage['percent'] : null;

        $label = $complete
            ? 'complete'
            : ($percent !== null ? $percent . '% complete' : 'incomplete');

        return [
            'content'         => 'Bricks design index coverage: ' . $label . '.',
            'fact_type'       => 'bootstrap',
            'importance'      => 8,
            'structured_data' => $coverage,
        ];
    }

    private function metrics(): BricksMemoryMetrics
    {
        return $this->metrics ?? new BricksMemoryMetrics();
    }
}
