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

class SITECL_Update_Risk {

    /**
     * Called from scan orchestrator — returns issues for any pending updates that
     * have a Caution or High risk score.
     */
    public static function scan(): array {
        if ( ! function_exists( 'get_plugin_updates' ) ) {
            require_once ABSPATH . 'wp-admin/includes/update.php';
        }

        $updates = get_plugin_updates();

        if ( empty( $updates ) ) {
            return [];
        }

        $issues = [];

        foreach ( $updates as $plugin_file => $plugin_data ) {
            $slug    = explode( '/', $plugin_file )[0];
            $new_ver = $plugin_data->update->new_version ?? '';
            $old_ver = $plugin_data->Version ?? '';

            $risk = self::score_update( $slug, $old_ver, $new_ver, $plugin_data );

            if ( in_array( $risk['risk_level'], [ 'caution', 'high' ], true ) ) {
                $issues[] = [
                    'type'     => 'update_risk',
                    'severity' => $risk['risk_level'] === 'high' ? 'warning' : 'info',
                    'title'    => sprintf(
                        /* translators: %1$s plugin name, %2$s version, %3$s risk label */
                        __( '%1$s → %2$s: Risk %3$s', 'site-cliniq' ),
                        esc_html( $plugin_data->Name ),
                        esc_html( $new_ver ),
                        strtoupper( $risk['risk_level'] )
                    ),
                    'detail'      => $risk['plain_english'] ?? '',
                    'risk'        => $risk,
                    'plugin_slug' => $slug,
                ];
            }
        }

        return $issues;
    }

    /**
     * Score a single update.  Returns risk array (from AI or heuristic fallback).
     */
    public static function score_update( string $slug, string $old_ver, string $new_ver, object $plugin_data ): array {
        $cache_key = "sitecl_update_risk_{$slug}_{$new_ver}";
        $cached    = get_transient( $cache_key );
        if ( $cached ) {
            return $cached;
        }

        $wp_org_data = self::fetch_wp_org_data( $slug );
        $changelog   = $wp_org_data['sections']['changelog'] ?? '';

        $ai      = new SITECL_AI_Diagnosis();
        $prompt  = sprintf(
            'Assess the update risk for WordPress plugin "%s" updating from %s to %s. Changelog excerpt: %s. Active installs trend: %s. Last updated: %s.',
            $plugin_data->Name ?? $slug,
            $old_ver,
            $new_ver,
            wp_trim_words( wp_strip_all_tags( $changelog ), 150 ),
            $wp_org_data['active_installs'] ?? 'unknown',
            $wp_org_data['last_updated'] ?? 'unknown'
        );

        $result = $ai->diagnose( $prompt, SITECL_AI_Diagnosis::system_prompt_update_risk(), 400 );

        if ( is_wp_error( $result ) ) {
            // Heuristic fallback.
            $result = self::heuristic_risk( $old_ver, $new_ver, $wp_org_data );
        }

        set_transient( $cache_key, $result, DAY_IN_SECONDS );

        return $result;
    }

    private static function fetch_wp_org_data( string $slug ): array {
        $cache_key = "sitecl_wporg_{$slug}";
        $cached    = get_transient( $cache_key );
        if ( $cached ) {
            return $cached;
        }

        $response = wp_remote_get( "https://api.wordpress.org/plugins/info/1.0/{$slug}.json" );
        if ( is_wp_error( $response ) ) {
            return [];
        }

        $data = json_decode( wp_remote_retrieve_body( $response ), true ) ?? [];
        set_transient( $cache_key, $data, HOUR_IN_SECONDS * 6 );

        return $data;
    }

    /** Heuristic: major version bump = caution, everything else = safe. */
    private static function heuristic_risk( string $old_ver, string $new_ver, array $wp_org ): array {
        $old_major = (int) explode( '.', $old_ver )[0];
        $new_major = (int) explode( '.', $new_ver )[0];

        if ( $new_major > $old_major ) {
            return [
                'risk_level'       => 'caution',
                /* translators: %1$s: old plugin version number, %2$s: new plugin version number */
                'plain_english'    => sprintf( __( 'Major version update (%1$s → %2$s). Test on staging before updating live site.', 'site-cliniq' ), $old_ver, $new_ver ),
                'breaking_changes' => [],
                'recommendation'   => __( 'Test on staging first.', 'site-cliniq' ),
            ];
        }

        return [
            'risk_level'       => 'safe',
            'plain_english'    => __( 'Minor update, low risk.', 'site-cliniq' ),
            'breaking_changes' => [],
            'recommendation'   => __( 'Safe to update.', 'site-cliniq' ),
        ];
    }
}
