<?php
if (!defined('ABSPATH')) exit;

class SS_Schema {
    public static function init(){
        // async builder hook + print to <head>
        add_action('ss_index_refresh',[__CLASS__,'generate_schema'], 10, 1);
        add_action('wp_head', [__CLASS__, 'print_jsonld'], 99);

        // whenever a Q&A post is saved, invalidate cache and queue a rebuild
        add_action('save_post_ss_qa', [__CLASS__,'queue_build_on_save'], 20, 3);
    }

    /** Short-lived status for editor notices */
    private static function set_status($post_id, $type, $msg){
        set_transient('ss_schema_status_' . (int)$post_id, [
            'type' => $type,   // 'success' | 'error' | 'info'
            'msg'  => $msg,
        ], 10 * MINUTE_IN_SECONDS);
    }

    /** On save: clear 24h cache and schedule a near-immediate rebuild (non-blocking). */
    // public static function queue_build_on_save($post_id, $post, $update){
    //     if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) return;
    //     if ($post->post_type !== 'ss_qa') return;

    //     // drop the "last build" cache so next build is fresh
    //     delete_transient('ss_last_schema_build_' . (int) $post_id);

    //     // fire WP-Cron a few seconds later so the editor isn't blocked
    //     if (!wp_next_scheduled('ss_index_refresh', [$post_id])) {
    //         wp_schedule_single_event(time()+3, 'ss_index_refresh', [$post_id]);
    //     }

    //     self::set_status($post_id, 'info', 'Server error found.');
    // }

    // SS_Schema::queue_build_on_save
    public static function queue_build_on_save($post_id, $post, $update){
        if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) return;
        if ($post->post_type !== 'ss_qa') return;

        // Invalidate cache & clear only the error/attempt flags
        delete_transient('ss_last_schema_build_' . (int)$post_id);
        delete_post_meta($post_id, '_ss_schema_error');
        delete_post_meta($post_id, '_ss_schema_attempted');

        // IMPORTANT: do NOT delete _ss_schema_json/_ss_schema_sig here.
        // We preserve last-known-good until a new successful build replaces it.

        // Try building now for the demo
        if (method_exists(__CLASS__, 'generate_schema')) {
            self::generate_schema($post_id);
        }
    }





    /**
     * Build payload -> call API (Http wrapper) -> verify signature -> save meta
     */
   public static function generate_schema($post_id){

    // --- Feature flag ---
    $flags = (array) get_option(SS_Settings::OPT_FEATURE_FLAGS, []);
    if (!in_array('schema', $flags, true)) {
        do_action('searchshifter_log','schema','flag_disabled',['post_id'=>$post_id]);
        return;
    }

    // --- License gate ---
    if (!SS_Licensing::is_active()){
        do_action('searchshifter_log','schema','readonly_denied',['post_id'=>$post_id]);
        return;
    }

    // --- Schema Governor toggle (NEW) ---
    $govern = (bool) get_option( SS_Settings::OPT_SCHEMA_GOVERNOR, true );
    if (!$govern) {
        do_action('searchshifter_log','schema','governor_disabled',['post_id'=>$post_id]);
        return;
    }

    // --- Config ---
    $apiKey = trim((string) get_option(SS_Settings::OPT_API_KEY, ''));
    $parsed = wp_parse_url( get_site_url() );
    $domain = trim(
        (string) get_option(
            SS_Settings::OPT_DOMAIN,
            $parsed['host'] ?? ''
        )
    );
    $base   = SS_Licensing::api_base();
    if (!$apiKey || !$domain || !$base) {
        do_action('searchshifter_log','schema','missing_config',['post_id'=>$post_id]);
        return;
    }

    // --- Post guard ---
    $post = get_post($post_id);
    if (!$post || $post->post_type !== 'ss_qa') return;

    // mark attempt
    update_post_meta($post_id, '_ss_schema_attempted', time());

    // --- 24h cache ---
    $build_cache_key = 'ss_last_schema_build_' . (int) $post_id;

    $force = false;

    if (
        isset( $_GET['ss_force'], $_GET['ss_nonce'] )
        && current_user_can( 'manage_options' )
        && wp_verify_nonce(
            sanitize_text_field( wp_unslash( $_GET['ss_nonce'] ) ),
            'searchshifter_force_schema'
        )
    ) {
        $force = true;
    }

    if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
        $force = true;
    }

    if (defined('DOING_AJAX') && DOING_AJAX) $force = true;

    if (!$force && get_transient($build_cache_key)) {
        do_action('searchshifter_log','schema','cache_hit',['post_id'=>$post_id]);
        return;
    }

    // --- Locale ---
    $lang = str_replace('_','-', get_locale());
    if (!preg_match('/^[a-z]{2}(-[A-Z]{2})?$/', $lang)) {
        $lang = substr($lang, 0, 2);
    }

    // --- Load saved Q&A pairs ---
    $pairs_meta = (array) get_post_meta($post_id, SS_QA_Admin_UI::META_PAIRS, true);
    $pairs = [];
    foreach ($pairs_meta as $row) {
        $q = isset($row['q']) ? trim(wp_strip_all_tags($row['q'])) : '';
        $a = isset($row['a']) ? trim(wp_strip_all_tags($row['a'])) : '';
        if ($q !== '' && $a !== '') $pairs[] = ['q'=>$q, 'a'=>$a];
    }
    if (empty($pairs)) {
        $pairs[] = [
            'q' => get_the_title($post_id),
            'a' => wp_strip_all_tags(get_post_field('post_content', $post_id)),
        ];
    }

    // --- Organization block ---
    $org = SS_Settings::get_org();

    // --- Payload ---
    $payload = [
        'domain' => $domain,
        'payload' => [
            'url'      => get_permalink($post),
            'lang'     => $lang,
            'pairs'    => $pairs,
            'geo_mode' => true,
            'org'      => $org,
        ],
        'plugin_version' => SEARCHSHIFTER_VERSION,
    ];

    // --- Call API ---
    $resp = \SS\Core\Http::postJson('schema.build', '/schema/build', $payload, ['timeout'=>20]);

    if (empty($resp['ok']) || empty($resp['json']['ok']) || empty($resp['json']['data'])) {
        update_post_meta($post_id,'_ss_schema_error', 'schema_build_failed: HTTP '.(int)($resp['status'] ?? 0));
        do_action('searchshifter_log','schema','bad_response',['post_id'=>$post_id,'code'=>$resp['status'] ?? 0]);
        return;
    }

    // --- Unpack ---
    $body         = $resp['json'];
    $data         = $body['data'];
    $ts           = (int)($body['ts'] ?? 0);
    $exp          = (int)($body['exp'] ?? 0);
    $nonce        = (string)($body['nonce'] ?? '');
    $sig          = (string)($body['sig'] ?? '');
    $signedPath   = isset($body['signed_path'])   ? (string)$body['signed_path']   : '';
    $signedMethod = isset($body['signed_method']) ? (string)$body['signed_method'] : 'POST';

    // --- Verify signature ---
    $signMethod = get_option(SS_Settings::OPT_SIGNING_METHOD, 'hmac');
    $verified   = false;

    if ($signMethod === 'hmac'){
        $secret   = (string) get_option(SS_Settings::OPT_SIGNING_SECRET, '');
        $dataJson = json_encode($data, JSON_UNESCAPED_SLASHES);
        if ($signedPath === '') {
            $parsed_base = wp_parse_url( $base );
            $basePath   = $parsed_base['path'] ?? '/api';
            $signedPath = rtrim($basePath, '/') . '/schema/build';
        }
        if ($exp && time() > ($exp + 60)) {
            update_post_meta($post_id,'_ss_schema_error', 'schema_signature_expired');
            do_action('searchshifter_log','schema','expired_sig',['post_id'=>$post_id,'ts'=>$ts,'exp'=>$exp]);
            return;
        }
        $verified = SS_Security::verify_hmac_signature($signedMethod, $signedPath, $ts, $nonce, $dataJson, $sig, $secret);

    } else {
        $schema_json = !empty($data['jsonld_min']) ? (string)$data['jsonld_min']
                    : (isset($data['jsonld']) ? wp_json_encode($data['jsonld']) : '');
        $pub_b64     = (string) get_option(SS_Settings::OPT_PUBLIC_KEY, '');
        $verified    = ($schema_json && $sig && $pub_b64)
            ? SS_Security::verify_signature($schema_json,$sig,$pub_b64)
            : false;
    }

    if (!$verified){
        delete_post_meta($post_id,'_ss_schema_json');
        delete_post_meta($post_id,'_ss_schema_sig');
        update_post_meta($post_id,'_ss_schema_error', 'schema_signature_invalid');
        do_action('searchshifter_log','schema','signature_invalid',['post_id'=>$post_id]);
        return;
    }

    // --- Persist ---
    $schema_json = !empty($data['jsonld_min']) ? (string)$data['jsonld_min']
                : (isset($data['jsonld']) ? wp_json_encode($data['jsonld']) : '');

    if ($schema_json) {
        update_post_meta($post_id, '_ss_schema_json', $schema_json);
        update_post_meta($post_id, '_ss_schema_sig',  $sig);
        delete_post_meta($post_id, '_ss_schema_error');
        set_transient('ss_last_schema_build_'.(int)$post_id, time(), DAY_IN_SECONDS);
        do_action('searchshifter_log','schema','saved',['post_id'=>$post_id]);
    }
}






    /** Output saved JSON-LD into <head> when viewing Q&A. */
    public static function print_jsonld(){
    if (!is_singular('ss_qa')) return;

    // NEW: Stop output if Schema Governor is OFF
    $govern = (bool) get_option( SS_Settings::OPT_SCHEMA_GOVERNOR, true );
    if (!$govern) return;

    $post_id = get_queried_object_id();
    $json = get_post_meta($post_id, '_ss_schema_json', true);
    if (!$json) return;

    echo "\n<script type=\"application/ld+json\">" . esc_html( $json ) . "</script>\n";
}

}
