<?php
/**
 * Tools REST API Class
 *
 * @package SAAI
 */

namespace SAAI\REST;

use SAAI\Abstracts\Abstract_Class;
use SAAI\Traits\Singleton_Trait;
use SAAI\Classes\Memory\Create_Memory;
use SAAI\Classes\Memory\Data_Upload;
use SAAI\Helpers\Connect;
use SAAI\Helpers\Helper;

defined( 'ABSPATH' ) || exit;

/**
 * Tools REST API Class
 */
class Tools extends Abstract_Class {

    use Singleton_Trait;

    /**
     * Rate limit duration in seconds (6 hours).
     */
    const RATE_LIMIT_DURATION = 1 * HOUR_IN_SECONDS;

    /**
     * Run the class
     */
    public function run() {
        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
    }

    /**
     * Register REST API routes
     */
    public function register_routes() {
        // Recreate AI Memory endpoint.
        register_rest_route(
            'storeagent-ai/v1',
            '/tools/recreate-memory',
            array(
                'methods'             => 'POST',
                'callback'            => array( $this, 'recreate_memory' ),
                'permission_callback' => array( $this, 'check_admin_permissions' ),
            )
        );

        // Clear Post Hashes endpoint.
        register_rest_route(
            'storeagent-ai/v1',
            '/tools/clear-post-hashes',
            array(
                'methods'             => 'POST',
                'callback'            => array( $this, 'clear_post_hashes' ),
                'permission_callback' => array( $this, 'check_admin_permissions' ),
            )
        );
    }

    /**
     * Check admin permissions
     *
     * @param \WP_REST_Request $request Request object.
     * @return bool
     */
    public function check_admin_permissions( $request ) {
        return current_user_can( 'manage_options' );
    }

    /**
     * Check if rate limit has passed for a specific action
     *
     * @param string $action The action name.
     * @return bool True if rate limit has passed, false otherwise.
     */
    protected function is_rate_limit_passed( $action ) {
        $last_execution = get_option( "saai_tools_{$action}_last_execution", 0 );
        $current_time   = time();

        return ( $current_time - $last_execution ) >= self::RATE_LIMIT_DURATION;
    }

    /**
     * Update the last execution time for a specific action
     *
     * @param string $action The action name.
     */
    protected function update_last_execution( $action ) {
        update_option( "saai_tools_{$action}_last_execution", time() );
    }

    /**
     * Get remaining time until action can be used again
     *
     * @param string $action The action name.
     * @return int Remaining time in seconds.
     */
    protected function get_remaining_time( $action ) {
        $last_execution = get_option( "saai_tools_{$action}_last_execution", 0 );
        $current_time   = time();
        $elapsed_time   = $current_time - $last_execution;

        return max( 0, self::RATE_LIMIT_DURATION - $elapsed_time );
    }

    /**
     * Recreate AI Memory
     *
     * @param \WP_REST_Request $request Request object.
     * @return \WP_REST_Response
     */
    public function recreate_memory( $request ) {
        // Check rate limit.
        if ( ! $this->is_rate_limit_passed( 'recreate_memory' ) ) {
            $remaining_time = $this->get_remaining_time( 'recreate_memory' );
            $minutes        = floor( $remaining_time / MINUTE_IN_SECONDS );

            return new \WP_REST_Response(
                array(
                    'success' => false,
                    'message' => sprintf(
                        /* translators: %1$d: minutes */
                        __( 'This action can only be performed once every hour. Please wait %1$d minutes before trying again.', 'storeagent-ai-for-woocommerce' ),
                        $minutes
                    ),
                ),
                429
            );
        }

        $create_memory = Create_Memory::instance();

        // Check if the store is eligible for chat.
        if ( ! $create_memory->is_eligible_for_chat() ) {
            return new \WP_REST_Response(
                array(
                    'success' => false,
                    'message' => __( 'Your plan does not support AI Chat functionality.', 'storeagent-ai-for-woocommerce' ),
                ),
                400
            );
        }

        // Reset the memory created flag to force recreation.
        update_option( Create_Memory::MEMORY_CREATED_OPTION, 'no' );
        delete_option( Create_Memory::SHOW_SETUP_PROGRESS_OPTION );
        delete_option( Create_Memory::SETUP_EMAIL_SENT_OPTION );

        // Create AI memory.
        $response = $this->create_ai_memory_api_call();
        if ( is_wp_error( $response ) ) {
            return new \WP_REST_Response(
                array(
                    'success' => false,
                    'message' => $response->get_error_message(),
                ),
                500
            );
        }

        // Save the options.
        update_option( Create_Memory::MEMORY_CREATED_OPTION, 'yes' );

        $post_types = Helper::get_post_types_with_ai_memory_enabled();
        // Schedule the recurring post data upload.
        foreach ( $post_types as $post_type ) {
            Data_Upload::instance()->schedule_post_data_upload( $post_type );
        }

        // Update rate limit timestamp.
        $this->update_last_execution( 'recreate_memory' );

        return new \WP_REST_Response(
            array(
                'success' => true,
                'message' => __( 'AI Memory recreated successfully. Post data will be uploaded automatically.', 'storeagent-ai-for-woocommerce' ),
            ),
            200
        );
    }

    /**
     * Clear Post Data Hashes
     *
     * @param \WP_REST_Request $request Request object.
     * @return \WP_REST_Response
     */
    public function clear_post_hashes( $request ) {
        // Check rate limit.
        if ( ! $this->is_rate_limit_passed( 'clear_post_hashes' ) ) {
            $remaining_time = $this->get_remaining_time( 'clear_post_hashes' );
            $minutes        = floor( $remaining_time / MINUTE_IN_SECONDS );

            return new \WP_REST_Response(
                array(
                    'success' => false,
                    'message' => sprintf(
                        /* translators: %1$d: minutes */
                        __( 'This action can only be performed once every hour. Please wait %1$d minutes before trying again.', 'storeagent-ai-for-woocommerce' ),
                        $minutes
                    ),
                ),
                429
            );
        }

        global $wpdb;

        $meta_keys = array(
            Data_Upload::POST_DATA_UPLOAD_HASH_META,
            Data_Upload::POST_DATA_UPLOAD_TIMESTAMP_META,
            Data_Upload::POST_DATA_CURRENT_HASH_META,
            Data_Upload::PENDING_POST_DATA_UPLOAD_META,
        );

        $deleted_count = 0;

        foreach ( $meta_keys as $meta_key ) {
            // Delete metadata for all posts.
            $deleted = $wpdb->delete(
                $wpdb->postmeta,
                array( 'meta_key' => $meta_key ),
                array( '%s' )
            );

            if ( false !== $deleted ) {
                $deleted_count += $deleted;
            }
        }

        // Clear any cached data.
        wp_cache_flush();

        // Log the action.
        wc_get_logger()->info(
            sprintf(
                'Post data hashes cleared. %d metadata entries deleted.',
                $deleted_count
            ),
            array( 'source' => 'storeagent-ai-for-woocommerce' )
        );

        // Re-enable the upload progress notice since posts will need to be re-uploaded.
        if ( $deleted_count > 0 ) {
            update_option( Create_Memory::SHOW_SETUP_PROGRESS_OPTION, 'yes' );

            $post_types = Helper::get_post_types_with_ai_memory_enabled();
            // Schedule the post data upload to begin the re-upload process.
            foreach ( $post_types as $post_type ) {
                Data_Upload::instance()->schedule_post_data_upload( $post_type );
            }
        }

        // Update rate limit timestamp.
        $this->update_last_execution( 'clear_post_hashes' );

        return new \WP_REST_Response(
            array(
                'success' => true,
                'message' => sprintf(
                    /* translators: %d: number of metadata entries cleared */
                    __( 'Post data hashes cleared successfully. %d metadata entries were removed. Posts will be re-uploaded to AI memory automatically.', 'storeagent-ai-for-woocommerce' ),
                    $deleted_count
                ),
            ),
            200
        );
    }

    /**
     * Create AI memory by calling the worker plugin endpoint
     *
     * @return true|\WP_Error
     */
    protected function create_ai_memory_api_call() {
        $headers = array(
            'Content-Type'  => 'application/json',
            'X-Origin'      => wp_parse_url( get_home_url(), PHP_URL_HOST ),
            'Authorization' => 'Basic ' . base64_encode( Connect::get_consumer_key() . ':' . Connect::get_consumer_secret() ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
        );

        $response = wp_remote_post(
            Helper::get_storeagent_base_url( 'api' ) . '/storeagent/v1/memory/create',
            array(
                'headers' => $headers,
                'timeout' => 30,
            )
        );

        if ( is_wp_error( $response ) ) {
            return $response;
        }

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

        if ( $code > 299 ) {
            return new \WP_Error(
                'storeagent_create_ai_memory_error',
                isset( $body['message'] ) ? $body['message'] : __( 'Failed to create AI memory for store.', 'storeagent-ai-for-woocommerce' ),
                $body
            );
        }

        return true;
    }
}
