<?php
/**
 * PrimeLink Update System with Envato API Integration.
 * 
 * Allows automatic updates when license is active and valid.
 * Uses Envato API to download updates (Envato compliant).
 *
 * @package PrimeLink
 */

namespace PrimeLink\Core;

use PrimeLink\Helpers\EnvatoHelper;

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

final class Updater {

    /**
     * Store license verification result.
     */
    private static $license_result = null;

    /**
     * Store update check result.
     */
    private static $update_result = null;

    /**
     * Update check API endpoint (optional - can be set via filter).
     * This should be a PHP endpoint that verifies license and returns version information.
     * Endpoint receives purchase_code via POST and returns JSON with version info only if license is valid.
     * For example: https://api.malotop.ro/api.php or your own endpoint.
     */
    private static function get_update_check_url() {
        $url = apply_filters( 'mt_primelink_update_check_url', '' );
        
        // Default: empty (will skip version check, only verify license)
        // You can set this via filter to check for new versions
        // Example: add_filter( 'mt_primelink_update_check_url', function() { return 'https://api.malotop.ro/api.php'; } );
        return $url;
    }

    /**
     * Initialize update system.
     */
    public static function init() {
        // Perform background license check automatically on admin pages
        if ( is_admin() ) {
            self::$license_result = EnvatoHelper::verify_license( true );
            
            // Check for updates if license is active (cached for 1 hour for faster update detection)
            if ( self::$license_result['status'] ?? false ) {
                $transient_key = 'mt_primelink_next_update_check';
                if ( false === ( self::$update_result = get_transient( $transient_key ) ) ) {
                    self::$update_result = self::check_update_available();
                    set_transient( $transient_key, self::$update_result, HOUR_IN_SECONDS );
                }
            }
        }
        
        // Hook into WordPress update system
        add_filter( 'pre_set_site_transient_update_plugins', array( __CLASS__, 'inject_update' ), 10, 1 );
        add_filter( 'upgrader_package_options', array( __CLASS__, 'intercept_download' ), 10, 1 );
        
        // If user doesn't have a valid license, show the activation pending notification in plugins page
        if ( is_admin() && ! ( self::$license_result['status'] ?? false ) ) {
            add_action( 'after_plugin_row_' . MT_PRIMELINK_BASENAME, array( __CLASS__, 'show_license_notice' ), 10, 3 );
        }
    }

    /**
     * Check if update is available.
     * 
     * Sends purchase code to server endpoint for license verification.
     * Server returns version info only if license is valid.
     * 
     * @return array Update information.
     */
    private static function check_update_available() {
        $update_check_url = self::get_update_check_url();
        
        // If no update check URL is configured, return no update
        if ( empty( $update_check_url ) ) {
            return array(
                'status' => false,
                'message' => __( 'Update check URL not configured.', 'primelink' ),
            );
        }

        // Get purchase code to send to server for verification
        $activation    = get_option( 'mt_primelink_license_activation', array() );
        $purchase_code = $activation['purchase_code'] ?? $activation['license_code'] ?? '';

        // In development bypass mode, allow a dummy purchase code so we can test updates
        if ( defined( 'MT_PRIMELINK_DEV_LICENSE_BYPASS' ) && MT_PRIMELINK_DEV_LICENSE_BYPASS && empty( $purchase_code ) ) {
            $purchase_code = 'DEV-LICENSE-CODE';
        }

        // If no purchase code at all, can't check for updates
        if ( empty( $purchase_code ) ) {
            return array(
                'status'  => false,
                'message' => __( 'Purchase code not found.', 'primelink' ),
            );
        }

        // Make request to check for updates (send purchase code for server-side verification)
        $response = wp_remote_post( $update_check_url, array(
            'timeout' => 15,
            'headers' => array(
                'User-Agent' => 'PrimeLink-Update-Checker/' . EnvatoHelper::get_current_version(),
                'Content-Type' => 'application/x-www-form-urlencoded',
            ),
            'body' => array(
                'purchase_code' => $purchase_code,
                'site_url'      => home_url(),
                'current_version' => EnvatoHelper::get_current_version(),
            ),
        ) );

        if ( is_wp_error( $response ) ) {
            return array(
                'status' => false,
                'message' => __( 'Failed to check for updates.', 'primelink' ),
            );
        }

        $response_code = wp_remote_retrieve_response_code( $response );
        $body = wp_remote_retrieve_body( $response );
        $data = json_decode( $body, true );

        // If server returns error (e.g., license invalid), return no update
        if ( $response_code >= 400 || empty( $data ) || ! is_array( $data ) ) {
            return array(
                'status' => false,
                'message' => __( 'License verification failed or no updates available.', 'primelink' ),
            );
        }

        // Server should return version only if license is valid
        // If license is invalid, server should return error status
        if ( isset( $data['error'] ) || isset( $data['status'] ) && $data['status'] === false ) {
            return array(
                'status' => false,
                'message' => $data['message'] ?? __( 'License verification failed.', 'primelink' ),
            );
        }

        // If no version in response, no update available
        if ( ! isset( $data['version'] ) ) {
            return array(
                'status' => false,
                'message' => __( 'No updates available.', 'primelink' ),
            );
        }

        $current_version = EnvatoHelper::get_current_version();
        $new_version = $data['version'];

        if ( version_compare( $current_version, $new_version, '<' ) ) {
            return array(
                'status' => true,
                'version' => $new_version,
                'download_url' => $data['download_url'] ?? '',
                'changelog' => $data['changelog'] ?? '',
                'message' => sprintf( __( 'New version %s is available.', 'primelink' ), $new_version ),
            );
        }

        return array(
            'status' => false,
            'message' => __( 'You are using the latest version.', 'primelink' ),
        );
    }

    /**
     * Get download URL for the update.
     * 
     * Constructs download URL that validates purchase code server-side.
     * Download can be from Envato API or from your server.
     * 
     * @return string Download URL or empty string on failure.
     */
    private static function get_download_url() {
        // Get purchase code for verification
        $activation    = get_option( 'mt_primelink_license_activation', array() );
        $purchase_code = $activation['purchase_code'] ?? $activation['license_code'] ?? '';

        // In development bypass mode, allow a dummy purchase code so we can test downloads
        if ( defined( 'MT_PRIMELINK_DEV_LICENSE_BYPASS' ) && MT_PRIMELINK_DEV_LICENSE_BYPASS && empty( $purchase_code ) ) {
            $purchase_code = 'DEV-LICENSE-CODE';
        }

        if ( empty( $purchase_code ) ) {
            return '';
        }

        // Get new version from update result
        $new_version = self::$update_result['version'] ?? '';

        // First, try to get download URL from update check response (JSON)
        if ( ! empty( self::$update_result['download_url'] ) ) {
            $download_url = self::$update_result['download_url'];
            
            // If download_url from JSON doesn't have purchase_code, add it
            if ( strpos( $download_url, 'purchase_code' ) === false ) {
                $download_url = add_query_arg( 'purchase_code', $purchase_code, $download_url );
            }
            
            return $download_url;
        }

        // Fallback: Construct download URL using endpoint filter
        // Endpoint must be configured via filter - no default hardcoded URL for compliance
        $download_endpoint = apply_filters( 
            'mt_primelink_update_download_endpoint', 
            '' // Must be configured via filter (e.g., in theme's functions.php or mu-plugin)
        );

        if ( ! empty( $download_endpoint ) ) {
            // Add purchase code and version as parameters
            return add_query_arg( array(
                'purchase_code' => $purchase_code,
                'version' => $new_version,
                'item_id' => apply_filters( 'mt_primelink_envato_item_id', '' ),
            ), $download_endpoint );
        }

        // If no download endpoint configured, return empty (user will need to download manually)
        return '';
    }

    /**
     * Inject update into WordPress update system.
     *
     * @param object $transient Update transient.
     * @return object
     */
    public static function inject_update( $transient ) {
        if ( empty( $transient->checked ) ) {
            return $transient;
        }

        // Only proceed if license is active
        if ( ! ( self::$license_result['status'] ?? false ) ) {
            return $transient;
        }

        // Only proceed if update is available
        if ( ! ( self::$update_result['status'] ?? false ) ) {
            return $transient;
        }

        $current_version = EnvatoHelper::get_current_version();
        $new_version = self::$update_result['version'] ?? '';

        if ( empty( $new_version ) || version_compare( $current_version, $new_version, '>=' ) ) {
            return $transient;
        }

        $plugin_file = MT_PRIMELINK_BASENAME;
        
        // Get download URL (from update check or constructed)
        $download_url = self::get_download_url();

        // If still no download URL, we can't provide update
        if ( empty( $download_url ) ) {
            return $transient;
        }

        // Add to WordPress update system
        $transient->response[ $plugin_file ] = (object) array(
            'id'          => $plugin_file,
            'slug'        => 'primelink',
            'plugin'      => $plugin_file,
            'new_version' => $new_version,
            'url'         => apply_filters( 'mt_primelink_plugin_url', 'https://codecanyon.net/item/primelink' ),
            'package'     => $download_url,
            'tested'      => get_bloginfo( 'version' ),
            'requires'    => '5.8',
            'requires_php' => '7.4',
        );

        return $transient;
    }

    /**
     * Intercept download to verify license before allowing download.
     *
     * @param array $options Package options.
     * @return array
     */
    public static function intercept_download( $options ) {
        if ( ! isset( $options['package'] ) || empty( $options['package'] ) ) {
            return $options;
        }

        // Only intercept our plugin updates
        if ( ! isset( $options['hook_extra']['plugin'] ) || 
             $options['hook_extra']['plugin'] !== MT_PRIMELINK_BASENAME ) {
            return $options;
        }

        // Verify license is still active before allowing download
        $license_status = EnvatoHelper::verify_license( false );
        if ( ! ( $license_status['status'] ?? false ) ) {
            // License not active - prevent download
            return new \WP_Error( 'license_inactive', __( 'License is not active. Please activate your license to download updates.', 'primelink' ) );
        }

        return $options;
    }

    /**
     * Force check for updates (clears cache and checks again).
     * 
     * @return array Update result.
     */
    public static function check_for_updates() {
        // Clear cache
        delete_transient( 'mt_primelink_next_update_check' );
        delete_site_transient( 'update_plugins' );
        
        // Force fresh license check
        self::$license_result = EnvatoHelper::verify_license( false );
        
        // Force fresh update check
        self::$update_result = self::check_update_available();
        
        // Cache the result (1 hour for faster update detection)
        set_transient( 'mt_primelink_next_update_check', self::$update_result, HOUR_IN_SECONDS );
        
        return self::$update_result;
    }

    /**
     * Get update result (for external use).
     */
    public static function get_update_result() {
        return self::$update_result;
    }

    /**
     * Get license result (for external use).
     */
    public static function get_license_result() {
        return self::$license_result;
    }

    /**
     * Show license notice in plugins page if license is not active.
     *
     * @param string $plugin_file Plugin file.
     * @param array  $plugin_data Plugin data.
     * @param string $status Status.
     */
    public static function show_license_notice( $plugin_file, $plugin_data, $status ) {
        $settings_url = admin_url( 'admin.php?page=mt-primelink-settings' );
        ?>
        <tr class="active">
            <td colspan="4">
                <div class="notice notice-error inline notice-alt" style="margin: 5px 20px 10px 20px">
                    <p>
                        <b><?php esc_html_e( 'License is not activated. Please enter your Envato purchase code to receive automatic updates and support.', 'primelink' ); ?></b>
                        <a href="<?php echo esc_url( $settings_url ); ?>" style="text-decoration: underline;">
                            <?php esc_html_e( 'Activate License', 'primelink' ); ?>
                        </a>.
                    </p>
                </div>
            </td>
        </tr>
        <?php
    }
}
