<?php
if ( ! defined( 'ABSPATH' ) ) exit;
/** @noinspection PhpExpressionResultUnusedInspection */

class ScholarSync_Remote
{
//    private static $OPTION_PREFIX = 'scholar-sync-';

    public static $CUSTOMER_API_KEY = SCHOLAR_SYNC_OPTION_PREFIX . 'customer-apikey';
    private $remote_url;
    private $data;
    private $has_error = false;
    private $init_error = '';
    private $headers;

    function __construct($end_point_name, $add_apikey = true) {
        $url = SCHOLAR_SYNC_SERVICE_URL . $end_point_name;
        $this->headers['domain'] = get_site_url();
        if ($add_apikey) {
            if ( ! get_option( 'scholar_sync_service_consent', false ) ) {
                $this->has_error  = true;
                $this->init_error = __( 'Scholar Sync is not connected yet. Please click the "I agree — Connect to scholar-sync.org" button in the notice at the top of the page. This is required before the plugin can fetch any data.', 'scholar-sync' );
                return;
            }
            $apikey = get_option($this::$CUSTOMER_API_KEY);
            if ($apikey) {
                $this->headers['apikey'] = $apikey;
            } else {
                require_once SCHOLAR_SYNC_PLUGIN_DIR . '/includes/class-scholar-sync-activator.php';
                ScholarSync_Activator::crete_apikey();
                $apikey = get_option($this::$CUSTOMER_API_KEY);
                if ($apikey) {
                    $this->headers['apikey'] = $apikey;
                } else {
                    $this->has_error  = true;
                    $this->init_error = __( 'Could not register with scholar-sync.org. Please try again or contact support.', 'scholar-sync' );
                    return;
                }
            }
        }

        // Attach Freemius context headers when the SDK is available and the
        // user has completed the Freemius opt-in (is_registered).
        if ( function_exists( 'scholar_sync_fs' ) ) {
            $fs = scholar_sync_fs();
            if ( $fs->is_registered() ) {
                $fs_user    = $fs->get_user();
                $fs_install = $fs->get_site();
                if ( is_object( $fs_user ) ) {
                    $this->headers['fs_user_id'] = (string) $fs_user->id;
                }
                if ( is_object( $fs_install ) ) {
                    $this->headers['fs_install_id'] = (string) $fs_install->id;
                }
                $fs_license = $fs->_get_license();
                if ( is_object( $fs_license ) && ! empty( $fs_license->id ) ) {
                    $this->headers['fs_license_id'] = (string) $fs_license->id;
                }
                $plan_name = $fs->get_plan_name();
                if ( $plan_name && 'PLAN_NAME' !== $plan_name ) {
                    $this->headers['fs_plan'] = $plan_name;
                }
            }
        }

        $this->remote_url = $url;
    }

    public function get_url(): string {
        return $this->remote_url;
    }

    public function set_url(string $url) {
        $this->remote_url = $url;
    }

    public function add_param_to_url($key, $value) {
        if ( $this->has_error ) {
            return;
        }
        $this->remote_url = add_query_arg($key, $value, $this->remote_url);
    }

    public function retrieve_remote_data() {
        if ( $this->has_error ) {
            return;
        }
        $args = array('timeout' => SCHOLAR_SYNC_TIMEOUT, 'headers' => $this->headers);
        try {
            $response   = wp_remote_get( $this->remote_url, $args );
            $this->data = json_decode( wp_remote_retrieve_body( $response ), true );
        }
        catch (Exception $e) {
            $this->has_error = true;
        }
    }

    /**
     * Non-blocking POST — fire and forget.
     * Does not wait for a response; ideal for event notifications.
     */
    public function fire_post( array $body = [] ) {
        if ( $this->has_error ) {
            return;
        }
        wp_remote_post( $this->remote_url, array(
            'timeout'  => 1,
            'blocking' => false,
            'headers'  => $this->headers,
            'body'     => $body,
        ) );
    }

    public function retrieve_remote_data_post( array $body ) {
        if ( $this->has_error ) {
            return;
        }
        $args = array(
            'timeout' => SCHOLAR_SYNC_TIMEOUT,
            'headers' => $this->headers,
            'body'    => $body,
        );
        try {
            $response   = wp_remote_post( $this->remote_url, $args );
            $this->data = json_decode( wp_remote_retrieve_body( $response ), true );
        } catch ( Exception $e ) {
            $this->has_error = true;
        }
    }

    public function has_error(): bool
    {
        if ( $this->has_error ) {
            return true;
        }
        if ( ! is_array( $this->data ) ) {
            return true;
        }
        if ( isset( $this->data['message'] ) ) {
            return true;
        }
        return false;
    }

    public function get_data() {
        return $this->data;
    }

    public function get_error_message() {
        if ( $this->init_error ) {
            return $this->init_error;
        }
        if ( ! is_array( $this->data ) ) {
            return __( 'Could not connect to the scholar-sync.org service. Please try again.', 'scholar-sync' );
        }
        return $this->data['message'];
    }

    public function get_error_message_4_display() {
        $msg = $this->get_error_message();
        return '<div class="notice error"><p><strong>' . esc_html__( 'Error', 'scholar-sync' ) . ':</strong> ' . esc_html( $msg ) . '</p></div>';
    }

    public function get_error_code() {
        return $this->data['code'];
    }

    /**
     * Returns true when the service response signals that the current plan
     * limit has been reached and an upgrade is required.
     */
    public function is_upgrade_required(): bool {
        return ! empty( $this->data['data']['upgrade_required'] );
    }

    /**
     * Returns the structured plan-limit data from the service response
     * (limit_type, limit_value, plan, etc.) when upgrade_required is true.
     *
     * @return array Empty array when the response has no limit data.
     */
    public function get_upgrade_data(): array {
        return isset( $this->data['data'] ) && is_array( $this->data['data'] )
            ? $this->data['data']
            : [];
    }

}