<?php
defined( 'ABSPATH' ) || exit;

/**
 * Google Fonts data provider.
 *
 * Reads the bundled assets/google-fonts.json catalog and exposes it as
 * structured data for the Settings page, the Editor, and the Renderer.
 * Uses a WordPress transient (keyed by JALPI_VERSION) so the JSON is only
 * decoded once per version.
 */
class Jalpi_Google_Fonts {

    private static ?self $instance = null;

    /** @var array|null In-memory cache for the current request. */
    private ?array $fonts = null;

    public static function instance(): self {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {}

    // =========================================================================
    // Data access
    // =========================================================================

    /**
     * Return the full list of bundled Google Fonts.
     *
     * Each entry has: family (string), category (string), variants (string[]).
     *
     * @return array[]
     */
    public function get_fonts(): array {
        if ( null !== $this->fonts ) {
            return $this->fonts;
        }

        $cache_key = 'jalpi_google_fonts_' . JALPI_VERSION;
        $cached    = get_transient( $cache_key );

        if ( false !== $cached && is_array( $cached ) ) {
            $this->fonts = $cached;
            return $this->fonts;
        }

        $json_path = JALPI_DIR . 'assets/google-fonts.json';
        if ( ! file_exists( $json_path ) ) {
            $this->fonts = [];
            return $this->fonts;
        }

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
        $raw  = file_get_contents( $json_path );
        $data = json_decode( $raw, true );

        $this->fonts = is_array( $data['fonts'] ?? null ) ? $data['fonts'] : [];

        set_transient( $cache_key, $this->fonts, DAY_IN_SECONDS );

        return $this->fonts;
    }

    /**
     * Return fonts formatted as the [{label, value}] array used by
     * Jalpi_Settings::get_font_options() and the Editor font picker.
     *
     * Values follow the existing convention: "Family Name", category-fallback
     * so the renderer's fontFamily extraction regex continues to work.
     *
     * @return array[]
     */
    public function get_font_select_options(): array {
        $options = [];
        foreach ( $this->get_fonts() as $font ) {
            $family   = $font['family'];
            $category = $font['category'] ?? 'sans-serif';
            $options[] = [
                'label'    => $family,
                'value'    => '"' . $family . '", ' . $category,
                'category' => $category,
            ];
        }
        return $options;
    }

    /**
     * Look up a single font by family name.
     *
     * @param  string $family  e.g. "Inter", "Playfair Display"
     * @return array|null      Font entry or null if not found.
     */
    public function get_font( string $family ): ?array {
        foreach ( $this->get_fonts() as $font ) {
            if ( strcasecmp( $font['family'], $family ) === 0 ) {
                return $font;
            }
        }
        return null;
    }

    /**
     * Return fonts grouped by category for the editor UI.
     *
     * @return array<string, array[]>  e.g. ['sans-serif' => [...], 'serif' => [...]]
     */
    public function get_fonts_grouped(): array {
        $groups = [];
        foreach ( $this->get_fonts() as $font ) {
            $cat = $font['category'] ?? 'sans-serif';
            $groups[ $cat ][] = $font;
        }
        return $groups;
    }

    /**
     * Category labels for display in the UI.
     */
    public static function category_labels(): array {
        return [
            'sans-serif'  => __( 'Sans Serif',  'jalpi-page-builder' ),
            'serif'       => __( 'Serif',        'jalpi-page-builder' ),
            'display'     => __( 'Display',      'jalpi-page-builder' ),
            'handwriting' => __( 'Handwriting',  'jalpi-page-builder' ),
            'monospace'   => __( 'Monospace',    'jalpi-page-builder' ),
        ];
    }
}
