<?php

namespace AtlasAiDev\Awfah\Integrations;

use AtlasAiDev\Awfah\REST\Experiments_Controller;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Bridge to the official WordPress AI plugin (wordpress.org/plugins/ai).
 *
 * When the AI plugin is active, this bridge:
 *  1. Registers our block-editor experiments as Features in the AI plugin's
 *     framework (`wpai_register_features`), so they get a toggle card on the
 *     official Settings > AI screen. Pilot scope: excerpt generation only
 *     (see BRIDGED). Our own React UI is untouched — only the registration
 *     backend is shared.
 *  2. Applies user-controlled suppression of the AI plugin's duplicate
 *     experiments via its own `wpai_feature_{id}_enabled` filters, driven by
 *     the per-experiment `suppress_official` setting and the global
 *     `awfah_wpai_suppress_all` option (both editable in our Experiments tab).
 *  3. Exposes editorial Guidelines from the AI plugin (`wp_guideline` CPT) as
 *     a prompt suffix for our generation abilities.
 *
 * The AI plugin's APIs are experimental, so every touchpoint is feature-detected
 * and wrapped; when the plugin is absent or an API disappears, everything here
 * no-ops and our experiments run standalone exactly as before.
 */
class Wpai_Bridge {

    /**
     * Option key for the global "hide all official duplicates" switch.
     */
    const SUPPRESS_ALL_OPTION = 'awfah_wpai_suppress_all';

    /**
     * Map of our experiment slugs to the AI plugin's feature IDs that
     * duplicate them (used for suppression).
     *
     * @var array<string, string>
     */
    const MAP = [
        'generate-excerpt'    => 'excerpt-generation',
        'image-generation'    => 'image-generation',
        'summarization'       => 'summarization',
        'suggest-titles'      => 'title-generation',
        'alt-text-generation' => 'alt-text-generation',
    ];

    /**
     * Our experiments registered into the AI plugin's Feature framework,
     * mapped to the wpai Feature ID each registers as.
     * Pilot: excerpt only. The other four follow once the pilot is validated.
     *
     * @var array<string, string>
     */
    const BRIDGED = [
        'generate-excerpt'    => 'awfah-excerpt-generation',
        'image-generation'    => 'awfah-image-generation',
        'summarization'       => 'awfah-summarization',
        'suggest-titles'      => 'awfah-title-generation',
        'alt-text-generation' => 'awfah-alt-text-generation',
    ];

    /**
     * Experiments whose bridged Feature was enabled by the AI plugin this
     * request (set from each Feature's register()).
     *
     * @var array<string, bool>
     */
    private static array $wpai_enabled = [];

    /**
     * Whether the official AI plugin's Feature framework is available.
     */
    public static function is_wpai_active(): bool {
        return class_exists( '\WordPress\AI\Abstracts\Abstract_Feature' );
    }

    public function __construct() {
        if ( ! self::is_wpai_active() ) {
            return;
        }

        add_action( 'wpai_register_features', [ $this, 'register_features' ] );
        $this->default_bridged_features_on();
        $this->apply_suppressions();
    }

    /**
     * Default our bridged features to ENABLED on the AI plugin's side.
     *
     * The AI plugin's per-feature options default to false when missing
     * (Abstract_Feature::is_individually_enabled()), which would hide our
     * experiment until the user also enables it on Settings > AI. Seed the
     * option to true exactly once so the Settings > AI card starts ON and
     * stays consistent with actual behavior; after that the user's card
     * toggle is fully respected.
     */
    private function default_bridged_features_on(): void {
        foreach ( self::BRIDGED as $feature_id ) {
            $option = "wpai_feature_{$feature_id}_enabled";

            if ( null === get_option( $option, null ) ) {
                update_option( $option, true );
            }
        }
    }

    /**
     * Register our bridged experiments as Features in the AI plugin.
     *
     * @param object $registry \WordPress\AI\Features\Registry.
     */
    public function register_features( $registry ): void {
        if ( ! is_object( $registry ) || ! method_exists( $registry, 'register_feature' ) ) {
            return;
        }

        $features = [
            Wpai_Excerpt_Feature::class,
            Wpai_Image_Feature::class,
            Wpai_Summarization_Feature::class,
            Wpai_Title_Feature::class,
            Wpai_Alt_Text_Feature::class,
        ];

        foreach ( $features as $feature_class ) {
            try {
                $registry->register_feature( new $feature_class() );
            } catch ( \Throwable $e ) {
                // The AI plugin's Feature API is experimental — never fatal on drift.
            }
        }
    }

    /**
     * Called from a bridged Feature's register() — the AI plugin only calls
     * register() when the feature is enabled (its global + per-feature toggles).
     *
     * @param string $slug Our experiment slug.
     */
    public static function mark_enabled( string $slug ): void {
        self::$wpai_enabled[ $slug ] = true;
    }

    /**
     * Whether a bridged experiment may load its editor UI.
     *
     * Standalone (AI plugin absent) or non-bridged experiments: always true.
     * Bridged experiments: the AI plugin's toggles decide (Settings > AI).
     */
    public static function is_experiment_allowed( string $slug ): bool {
        if ( ! self::is_wpai_active() || ! array_key_exists( $slug, self::BRIDGED ) ) {
            return true;
        }

        return ! empty( self::$wpai_enabled[ $slug ] );
    }

    /**
     * Hide the AI plugin's duplicate experiments per user settings.
     *
     * A duplicate is only suppressed while OUR corresponding experiment is
     * enabled — disabling ours brings the official one back automatically.
     */
    private function apply_suppressions(): void {
        $all    = get_option( Experiments_Controller::OPTION_KEY, [] );
        $all    = is_array( $all ) ? $all : [];
        $global = (bool) get_option( self::SUPPRESS_ALL_OPTION, false );

        foreach ( self::MAP as $ours => $theirs ) {
            $row = ( isset( $all[ $ours ] ) && is_array( $all[ $ours ] ) ) ? $all[ $ours ] : [];

            $our_enabled = isset( $row['enabled'] ) ? (bool) $row['enabled'] : true;
            $suppress    = array_key_exists( 'suppress_official', $row )
                ? (bool) $row['suppress_official']
                : true; // Default: hide the duplicate next to our richer experiment.

            if ( $our_enabled && ( $global || $suppress ) ) {
                add_filter( "wpai_feature_{$theirs}_enabled", '__return_false' );
            }
        }
    }

    /**
     * Editorial Guidelines (AI plugin's wp_guideline CPT) formatted as a
     * system-instruction suffix. Empty string when unavailable.
     *
     * @param string[]    $categories Guideline categories (site, copy, images, additional).
     * @param string|null $block_name Optional block name for block-specific guidelines.
     */
    public static function guidelines_suffix( array $categories = [ 'site', 'copy' ], ?string $block_name = null ): string {
        if ( ! function_exists( '\WordPress\AI\format_guidelines_for_prompt' ) ) {
            return '';
        }

        try {
            $guidelines = \WordPress\AI\format_guidelines_for_prompt( $categories, $block_name );
        } catch ( \Throwable $e ) {
            return '';
        }

        if ( ! is_string( $guidelines ) || '' === trim( $guidelines ) ) {
            return '';
        }

        return "\n\n" . trim( $guidelines );
    }
}
