<?php
/**
 * Covalba Core — exposition Polylang dans WPGraphQL.
 *
 * Le connecteur tiers wp-graphql-polylang requiert un build composer et ne cible
 * pas WPGraphQL 2.x. On expose donc nous-mêmes le strict nécessaire pour le front
 * headless i18n : un champ `language` et un champ `translations` sur les types
 * traduisibles. Le filtrage par langue des connexions (énumération) est fait
 * côté front en JS via `language { slug }` — pas besoin d'argument where ici.
 *
 * Codes NEUTRES : slug = fr/en/es (exposé) ; code = FR/EN/ES.
 */

defined('ABSPATH') || exit;

add_action('graphql_register_types', function (): void {
    if (!function_exists('register_graphql_field') || !function_exists('pll_get_post_language')) {
        return; // WPGraphQL ou Polylang absent
    }

    register_graphql_object_type('CovalbaLanguage', [
        'description' => 'Langue Polylang (code neutre fr/en/es).',
        'fields'      => [
            'code'   => ['type' => 'String', 'description' => 'Code majuscule (FR/EN/ES).'],
            'slug'   => ['type' => 'String', 'description' => 'Code neutre minuscule (fr/en/es).'],
            'locale' => ['type' => 'String', 'description' => 'Locale WP interne (non exposée au public).'],
        ],
    ]);

    $post_id_of = static function ($source): int {
        if (is_object($source)) {
            if (isset($source->databaseId)) return (int) $source->databaseId;
            if (isset($source->ID)) return (int) $source->ID;
        }
        if (is_array($source) && isset($source['ID'])) return (int) $source['ID'];
        return 0;
    };

    // Types GraphQL traduisibles (graphql_single_name des CPT + Page + Post).
    foreach (['Page', 'Post', 'Produit', 'Toiture', 'Industrie', 'Reference'] as $gqlType) {
        register_graphql_field($gqlType, 'language', [
            'type'        => 'CovalbaLanguage',
            'description' => 'Langue Polylang du contenu.',
            'resolve'     => function ($source) use ($post_id_of) {
                $id = $post_id_of($source);
                if (!$id) return null;
                $slug = pll_get_post_language($id, 'slug');
                if (!$slug) return null;
                return [
                    'code'   => strtoupper($slug),
                    'slug'   => $slug,
                    'locale' => pll_get_post_language($id, 'locale'),
                ];
            },
        ]);

        register_graphql_field($gqlType, 'translations', [
            'type'        => ['list_of' => $gqlType],
            'description' => 'Traductions Polylang du contenu (toutes langues, soi-même inclus).',
            'resolve'     => function ($source) use ($post_id_of) {
                $id = $post_id_of($source);
                if (!$id || !function_exists('pll_get_post_translations')) return [];
                $out = [];
                foreach (pll_get_post_translations($id) as $tid) {
                    $p = get_post((int) $tid);
                    if ($p instanceof WP_Post) {
                        $out[] = new \WPGraphQL\Model\Post($p);
                    }
                }
                return $out;
            },
        ]);
    }
});

/**
 * Texte alternatif d'image traduit (EN/ES) sur MediaItem.
 *
 * Polylang ne traduit pas les médias (media_support off) → un seul `altText`
 * français partagé. On stocke les traductions en postmeta sur le MÊME média
 * (`_wp_attachment_image_alt_en` / `_es`) et on les expose ici. Le front, qui
 * récupère la page FR + ses `translations`, choisit la bonne langue côté JS.
 * Indépendant de Polylang : ne dépend que de WPGraphQL.
 */
add_action('graphql_register_types', function (): void {
    if (!function_exists('register_graphql_field')) {
        return;
    }

    $alt_resolver = static function (string $meta_key): callable {
        return static function ($source) use ($meta_key): ?string {
            $id = 0;
            if (is_object($source)) {
                if (isset($source->databaseId)) {
                    $id = (int) $source->databaseId;
                } elseif (isset($source->ID)) {
                    $id = (int) $source->ID;
                }
            }
            if (!$id) {
                return null;
            }
            $val = get_post_meta($id, $meta_key, true);
            return (is_string($val) && $val !== '') ? $val : null;
        };
    };

    register_graphql_field('MediaItem', 'altTextEn', [
        'type'        => 'String',
        'description' => "Texte alternatif traduit en anglais (postmeta _wp_attachment_image_alt_en). Null si absent.",
        'resolve'     => $alt_resolver('_wp_attachment_image_alt_en'),
    ]);

    register_graphql_field('MediaItem', 'altTextEs', [
        'type'        => 'String',
        'description' => "Texto alternativo traducido al español (postmeta _wp_attachment_image_alt_es). Null si ausente.",
        'resolve'     => $alt_resolver('_wp_attachment_image_alt_es'),
    ]);
});
