<?php

namespace App\Support;

/**
 * Read-only accessor over `config/locales.php`. Catalog is intentionally
 * code-managed (not DB-managed) so the script ships with the right metadata
 * for every locale without buyers having to know IETF codes or font stacks.
 *
 * Callers that need a Project's active locales should still go through the
 * `projects.default_locale` + `projects.active_locales` columns — those
 * carry the user's choice. This class is for resolving catalog metadata
 * (name, direction, font stack) once you have a code.
 */
class Locales
{
    /**
     * Every locale in the catalog.
     *
     * @return array<int, array{code: string, name: string, native_name: string, direction: string, font_stack: string}>
     */
    public static function all(): array
    {
        $catalog = config('locales.catalog', []);

        return is_array($catalog) ? array_values($catalog) : [];
    }

    /**
     * Catalog codes, in catalog order. Used by validators to constrain
     * `default_locale` / `active_locales` input to the known set.
     *
     * @return array<int, string>
     */
    public static function codes(): array
    {
        return array_map(static fn (array $row) => $row['code'], self::all());
    }

    /**
     * Lookup a single locale by code. Returns null when the code isn't in
     * the catalog — callers should treat that as "fall back to default
     * locale" rather than throwing, so a stray code in a kit JSON or DB
     * row doesn't blow up rendering.
     *
     * @return array{code: string, name: string, native_name: string, direction: string, font_stack: string}|null
     */
    public static function find(string $code): ?array
    {
        foreach (self::all() as $row) {
            if ($row['code'] === $code) {
                return $row;
            }
        }

        return null;
    }

    /**
     * Direction lookup. Returns `'ltr'` when the code isn't in the catalog
     * — same defensive fallback as `find()`.
     */
    public static function directionFor(string $code): string
    {
        $row = self::find($code);

        return $row['direction'] ?? 'ltr';
    }

    /**
     * Whether a code is a known catalog entry. Cheaper than `find()` for
     * boolean checks (e.g. validation rules).
     */
    public static function isKnown(string $code): bool
    {
        return self::find($code) !== null;
    }
}
