<?php
/**
 * Builds structured write-impact metadata from the design index.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks\Support;

use LolaCoreForBricks\Index\IndexReader;

/**
 * Populates the impact field for class write previews and confirmations.
 */
final class ImpactPayload
{
    /**
     * @return array{pages: int, elements: int, page_names: string[]}
     */
    public static function forClass(string $classId, ?IndexReader $reader = null): array
    {
        if ($classId === '') {
            return [
                'pages'       => 0,
                'elements'    => 0,
                'page_names'  => [],
            ];
        }

        $edges    = ($reader ?? new IndexReader())->usageOf(BricksMetaKeys::REF_CLASS, $classId);
        $postIds  = [];
        $pageNames = [];

        foreach ($edges as $edge) {
            $postId = (int) ($edge['post_id'] ?? 0);
            if ($postId <= 0) {
                continue;
            }

            if (!isset($postIds[$postId])) {
                $postIds[$postId]     = true;
                $pageNames[] = (string) get_the_title($postId);
            }
        }

        return [
            'pages'      => count($postIds),
            'elements'   => count($edges),
            'page_names' => $pageNames,
        ];
    }

    /**
     * @param string[] $classIds
     * @return array{pages: int, elements: int, page_names: string[]}
     */
    public static function forClasses(array $classIds, ?IndexReader $reader = null): array
    {
        $readerInstance = $reader ?? new IndexReader();
        $postIds        = [];
        $elementCount   = 0;
        $pageNames      = [];

        foreach ($classIds as $classId) {
            if (!is_string($classId) || $classId === '') {
                continue;
            }

            foreach ($readerInstance->usageOf(BricksMetaKeys::REF_CLASS, $classId) as $edge) {
                ++$elementCount;
                $postId = (int) ($edge['post_id'] ?? 0);
                if ($postId <= 0 || isset($postIds[$postId])) {
                    continue;
                }

                $postIds[$postId] = true;
                $pageNames[]      = (string) get_the_title($postId);
            }
        }

        return [
            'pages'      => count($postIds),
            'elements'   => $elementCount,
            'page_names' => $pageNames,
        ];
    }

    /**
     * @return array{references: int, pages: int, page_names: string[], summary: array<string, int>}
     */
    public static function forVariable(string $variableName, ?IndexReader $reader = null): array
    {
        $variableName = ltrim($variableName, '-');
        if ($variableName === '') {
            return [
                'references' => 0,
                'pages'      => 0,
                'page_names' => [],
                'summary'    => [
                    'elements'     => 0,
                    'classes'      => 0,
                    'theme_styles' => 0,
                    'other'        => 0,
                ],
            ];
        }

        $edges   = ($reader ?? new IndexReader())->usageOf(BricksMetaKeys::REF_VARIABLE, $variableName);
        $postIds = [];
        $summary = [
            'elements'     => 0,
            'classes'      => 0,
            'theme_styles' => 0,
            'other'        => 0,
        ];
        $pageNames = [];

        foreach ($edges as $edge) {
            $area = (string) ($edge['area'] ?? '');
            $kind = match ($area) {
                BricksMetaKeys::AREA_CLASS_SETTINGS => 'classes',
                BricksMetaKeys::AREA_THEME_STYLE    => 'theme_styles',
                BricksMetaKeys::AREA_CONTENT,
                BricksMetaKeys::AREA_HEADER,
                BricksMetaKeys::AREA_FOOTER,
                BricksMetaKeys::AREA_GLOBAL_ELEMENT => 'elements',
                default                             => 'other',
            };

            ++$summary[$kind];

            $postId = (int) ($edge['post_id'] ?? 0);
            if ($postId > 0 && !isset($postIds[$postId])) {
                $postIds[$postId] = true;
                $pageNames[]      = (string) get_the_title($postId);
            }
        }

        return [
            'references' => count($edges),
            'pages'      => count($postIds),
            'page_names' => $pageNames,
            'summary'    => $summary,
        ];
    }
}
