<?php
/**
 * Regenerates Bricks external CSS files after design-system writes (Law 1).
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks\Support;

use LolaCoreForBricks\BricksEnv;

/**
 * Knows which regeneration path applies after each write type.
 */
final class CssRegenerator
{
    /**
     * Options Bricks already regenerates on update — no duplicate work.
     *
     * @var string[]
     */
    private const SELF_HEALING_OPTIONS = [
        BricksMetaKeys::OPTION_GLOBAL_VARIABLES,
        BricksMetaKeys::OPTION_THEME_STYLES,
        'bricks_color_palette',
    ];

    public function afterOptionWrite(string $option): void
    {
        if (in_array($option, self::SELF_HEALING_OPTIONS, true)) {
            return;
        }
    }

    /**
     * @param int[] $affectedPostIds
     */
    public function afterClassChange(array $affectedPostIds): void
    {
        $this->regeneratePosts($affectedPostIds);
    }

    /**
     * Changing a component regenerates CSS on every page that hosts an instance (Law 1).
     *
     * @param int[] $affectedPostIds
     */
    public function afterComponentChange(array $affectedPostIds): void
    {
        $this->regeneratePosts($affectedPostIds);
    }

    /**
     * @param int[] $affectedPostIds
     */
    private function regeneratePosts(array $affectedPostIds): void
    {
        if (BricksEnv::cssLoadingMode() !== 'file') {
            return;
        }

        foreach (array_unique(array_filter(array_map('intval', $affectedPostIds))) as $postId) {
            if ($postId <= 0) {
                continue;
            }

            foreach (BricksMetaKeys::pageMetaKeyToArea() as $metaKey => $area) {
                $elements = get_post_meta($postId, $metaKey, true);
                if (!is_array($elements) || $elements === []) {
                    continue;
                }

                $this->generatePostCssFile($postId, $area, $elements);
            }
        }
    }

    public function afterPageSettings(int $postId): void
    {
        $this->regeneratePosts([$postId]);
    }

    public function afterPageWrite(int $postId, string $area): void
    {
        if ($postId <= 0 || BricksEnv::cssLoadingMode() !== 'file') {
            return;
        }

        $metaKey = array_search($area, BricksMetaKeys::pageMetaKeyToArea(), true);
        if (!is_string($metaKey)) {
            return;
        }

        $elements = get_post_meta($postId, $metaKey, true);
        if (!is_array($elements) || $elements === []) {
            return;
        }

        $this->generatePostCssFile($postId, $area, $elements);
    }

    /**
     * @param array<int|string, array<string, mixed>> $elements
     */
    private function generatePostCssFile(int $postId, string $area, array $elements): void
    {
        if (!class_exists(\Bricks\Assets_Files::class)) {
            return;
        }

        \Bricks\Assets_Files::generate_post_css_file($postId, $area, $elements);
    }
}
