<?php

declare(strict_types=1);

namespace App\Modules\Theme;

/**
 * ThemeManifest -- Parses and validates a theme.json manifest file.
 *
 * Single responsibility: read and validate one theme.json.
 * No HTML. No SQL. No file scanning.
 *
 * Required manifest fields:
 *   - code    : string -- Unique theme identifier (e.g. "theme-001")
 *   - name    : string -- Display name
 *   - version : string -- Semantic version (e.g. "1.0.0")
 *   - author  : string -- Author name or team
 *   - preview : string -- Preview image filename (relative to theme folder)
 *   - entry   : string -- Entry PHP filename (relative to theme folder)
 *
 * @package Inveetaire
 * @ref     RC-009
 */
class ThemeManifest
{
    /** @var string[] Required keys in every theme.json */
    private const REQUIRED_FIELDS = ['code', 'name', 'version', 'author', 'preview', 'entry'];

    /**
     * Parse and validate a theme.json file.
     *
     * @param string $manifestPath Absolute path to the theme.json file.
     * @return array|null Validated manifest array, or null if invalid/missing.
     */
    public function parse(string $manifestPath): ?array
    {
        if (!file_exists($manifestPath) || !is_readable($manifestPath)) {
            return null;
        }

        $raw = file_get_contents($manifestPath);
        if ($raw === false) {
            return null;
        }

        $data = json_decode($raw, true);
        if (!is_array($data)) {
            return null;
        }

        // Validate all required fields are present and non-empty strings
        foreach (self::REQUIRED_FIELDS as $field) {
            if (empty($data[$field]) || !is_string($data[$field])) {
                return null;
            }
        }

        // Return only the known required fields -- nothing extra
        return [
            'code'    => trim($data['code']),
            'name'    => trim($data['name']),
            'version' => trim($data['version']),
            'author'  => trim($data['author']),
            'preview' => trim($data['preview']),
            'entry'   => trim($data['entry']),
        ];
    }
}