<?php
namespace PSSG_Sync_Sheet\App\Http;

use PSSG_Sync_Sheet\App\Http\Sheet;
use PSSG_Sync_Sheet\App\Service\Products;
use PSSG_Sync_Sheet\App\Service\Standalone;
use PSSG_Sync_Sheet\App\Service\Request_Log;
/**
 * Product update using 
 * api request
 * 
 */
class Api
{

    use Standalone;
    public $route_namespace = 'pssg_gsheet_sync/v1';
    public $product_route = 'product';
    public $multiple_product_route = 'multiples';
    public $product_id;
    
    /**
     * Current request log ID
     *
     * @var int|null
     */
    public $current_log_id = null;


    public $product_updated_stats = false;
    public $Products;
    public $Sheet;
    public $request;
    public $requestedParams;
    public $api_response = [];
    public $http_response_code = 200;

    public $columns; //by $Products->get_columns()
    public $columns_label; //like ['sku'=> 'SKU', 'title'=> 'Product Title']
    public $columns_param_label; //like ['sku'=> 'SKU', 'title'=> 'Product_Title']

    /**
     * just flip of like ['sku'=> 'SKU', 'title'=> 'Product_Title']
     * Actually if found any array, we will replace with _ with space
     *
     * @var array
     */
    public $columns_param_label_flip;

    public function __construct()
    {
        $this->Products = Products::init();
        $this->Sheet = Sheet::init();

        $this->columns = $this->Products->get_columns();
        $this->columns_label = $this->Products->get_columns_label();
        $this->columns_param_label = array_map( function($val){
            return str_replace(" ", "_", $val);
        }, $this->columns_label );
        $this->columns_param_label_flip = array_flip( $this->columns_param_label );

        add_action('rest_api_init', [$this,'register_endpoint']);
    }


    public function register_endpoint() {
        register_rest_route( $this->route_namespace, '/' . $this->product_route, array(
            'methods' => 'POST',
            'callback' => [$this,'handle_request'],
            'permission_callback'   => [$this,'permission_callback'],
        ));

        register_rest_route( $this->route_namespace, '/' . $this->multiple_product_route, array(
            'methods' => 'POST',
            'callback' => [$this,'multiple_handle_request'],
            'permission_callback'   => [$this,'permission_callback'],
        ));
    }
    
    /**
     * Function to handle the POST request and update the option.
     * 
     *
     * @test new \WP_REST_Request();
     * @param \WP_REST_Request $request Request will come using \WP_REST_Request class
     * @return \WP_REST_Response
     */
    public function handle_request($request)
    {
        $this->request = $request;
        // Get the option name and value from the request.
        $this->requestedParams = $request->get_params();
        
        // Log the request
        $log_id = Request_Log::log_request([
            'endpoint' => $this->route_namespace . '/' . $this->product_route,
            'method' => 'POST',
            'request_data' => $this->requestedParams,
            'status' => 'processing',
            'access_key_valid' => 1,
            'product_id' => isset($this->requestedParams['ID']) ? absint($this->requestedParams['ID']) : null,
        ]);
        $this->current_log_id = $log_id;
        
        if( count($this->requestedParams) <= 1){
            $response_data = [
                'status' => 'error', 
                'message' => __('Parameter is not found', 'product-sync-master-sheet'),
            ];
            
            // Update log with error
            if ($log_id) {
                Request_Log::update_log($log_id, [
                    'status' => 'error',
                    'status_code' => $this->http_response_code,
                    'response_data' => $response_data,
                    'error_message' => __('Parameter is not found', 'product-sync-master-sheet'),
                ]);
            }
            
            return new \WP_REST_Response( $response_data , $this->http_response_code );
        }

        //Depend on this property, Response will display and It's able to handle from other Class/ even from other Plugin
        //using action hook 'pssg_api_request_handle'
        $this->product_updated_stats = true;

        /**
         * Action Hook: 'pssg_api_request_handle'
         * @hook pssg_api_request_handle 
         * @desc Control API Request's Object using 
         */
        do_action( 'pssg_api_request_handle', $this );



        
        /**
         * $this->product_updated_stats 
         * this value actually changed/handled by action hook 'pssg_api_request_handle'
         * 
         * eta ejjonno kora hoyeche jeno
         * action hook er madhome amra eta change korte pari.
         * true and false value.
         * 
         * that's why, I decrered it true before action hook (pssg_product_update_requested)
         */
        if( $this->product_updated_stats ){
            // Update log with success
            if ($log_id) {
                Request_Log::update_log($log_id, [
                    'status' => 'success',
                    'status_code' => $this->http_response_code,
                    'response_data' => $this->api_response,
                ]);
            }
            return new \WP_REST_Response( $this->api_response , $this->http_response_code );
        }

        // Update log with response
        if ($log_id) {
            Request_Log::update_log($log_id, [
                'status' => 'success',
                'status_code' => $this->http_response_code,
                'response_data' => $this->api_response,
            ]);
        }

        // Return a success response.
        return new \WP_REST_Response( $this->api_response, $this->http_response_code);
        
    }

    /**
     * For handle Multiple product update request
     * can be remove actually
     *
     * @param \WP_REST_Request $request Request will come using \WP_REST_Request class
     * @return \WP_REST_Response
     */
    public function multiple_handle_request( $request )
    {
        $this->request = $request;
        // Get the option name and value from the request.
        $this->requestedParams = $request->get_params();

        // Log the request
        $log_id = Request_Log::log_request([
            'endpoint' => $this->route_namespace . '/' . $this->multiple_product_route,
            'method' => 'POST',
            'request_data' => $this->requestedParams,
            'status' => 'processing',
            'access_key_valid' => 1,
        ]);
        $this->current_log_id = $log_id;

        //Depend on this property, Response will display and It's able to handle from other Class/ even from other Plugin
        //using action hook 'pssg_api_request_handle'
        $this->product_updated_stats = true;

        /**
         * Action Hook: 'pssg_api_request_handle'
         * @hook pssg_api_request_handle 
         * @desc Control API Request's Object using 
         */
        do_action( 'pssg_api_multiple_request_handle', $this );

        // Update log with response
        if ($log_id) {
            Request_Log::update_log($log_id, [
                'status' => 'success',
                'status_code' => $this->http_response_code,
                'response_data' => $this->api_response,
            ]);
        }

        // Return a success response.
        return new \WP_REST_Response( $this->api_response, $this->http_response_code);
        
    }

    
    /**
     * Permission callback for REST API endpoints
     * Validates the access key from the request
     *
     * @param \WP_REST_Request $request
     * @return bool|\WP_Error
     */
    public function permission_callback( $request )
    {
        // Get access key from request header or parameter
        $access_key = $request->get_header('X-PSSG-Access-Key');
        
        if (empty($access_key)) {
            $access_key = $request->get_param('access_key');
        }
        
        // Check if access key is configured
        if (!Request_Log::has_access_key()) {
            // Log the failed request
            Request_Log::log_request([
                'endpoint' => $request->get_route(),
                'method' => $request->get_method(),
                'request_data' => $request->get_params(),
                'status' => 'error',
                'status_code' => 403,
                'access_key_valid' => 0,
                'error_message' => __('Access key not configured. Please generate an access key from settings.', 'product-sync-master-sheet'),
            ]);
            
            return new \WP_Error(
                'rest_forbidden',
                __('Access key not configured. Please generate an access key from settings.', 'product-sync-master-sheet'),
                ['status' => 403]
            );
        }
        
        // Validate the access key
        if (empty($access_key) || !Request_Log::validate_access_key($access_key)) {
            // Log the failed request
            Request_Log::log_request([
                'endpoint' => $request->get_route(),
                'method' => $request->get_method(),
                'request_data' => $request->get_params(),
                'status' => 'unauthorized',
                'status_code' => 401,
                'access_key_valid' => 0,
                'error_message' => __('Invalid or missing access key.', 'product-sync-master-sheet'),
            ]);
            
            return new \WP_Error(
                'rest_forbidden',
                __('Invalid or missing access key. Please check your access key in the plugin settings.', 'product-sync-master-sheet'),
                ['status' => 401]
            );
        }
        
        return true;
    }

}