<?php
/**
 * Plugin Name: Searchwise API Data Feed 
 * Description: افزونه‌ای برای جمع‌آوری اطلاعات محصولات ووکامرس در قالب یک خوراک
 * Version: 1.0.2
 * Author: Searchwise
 * Author URI: https://www.searchwise.ir/
 * License: GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: searchwise-API-data-feed
 */

if (!defined('ABSPATH')) {
    exit; // Prevent direct access
}



// Check if WooCommerce is active before loading plugin
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {

    class Searchwise_WC_Product_Feed_Controller extends WP_REST_Controller {
        private $plugin_version = "1.0.2";
        private $plugin_slug = "searchwise-API-data-feed";

        public function __construct() {
            add_action('rest_api_init', array($this, 'register_routes'));
        }

        /**
         * Register the API route for the product feed.
         */
        public function register_routes() {
            $namespace = 'v1';
            $route = 'product/feed';

            register_rest_route($namespace, '/' . $route, array(
                array(
                    'methods'             => 'POST',
                    'callback'            => array($this, 'handle_product_request'),
                    'permission_callback' => array($this, 'permission_check'),
                )
            ));
        }
        

        public function permission_check($request) {
            $auth_response = $this->has_access($request);
            if (is_wp_error($auth_response)) {
                return new WP_Error('error', 'Authentication server could not be reached.', array('status' => 503));
            }
            if (is_wp_error($auth_response) || !isset($auth_response['success']) || $auth_response['success'] !== true) {
                return new WP_Error(
                    'rest_forbidden',
                    'Invalid API Key.',
                    array('status' => 401)
                );
            }
    
            return true;
        }

        /**
         * Validate the request
         *
         * @param WP_REST_Request $request The REST API request object.
         * @return array|WP_Error The decoded JSON response from the server or an error.
         */
        private function has_access($request) {
            $endpoint_url = 'https://merchants.searchwise.ir/api/v1/feed/validate-token';

            $site_url = wp_parse_url(get_site_url());
            $merchant_domain =  $site_url['host'];
            
            $api_key = $request->get_header('x_api_key');

            $response = wp_safe_remote_post($endpoint_url, array(
                'method'      => 'POST',
                'timeout'     => 5,
                'body'        => array(
                'merchant_domain' => $merchant_domain,
                'api_key'     => $api_key,
                'plugin_version' => $this->plugin_version,
                ),
            ));

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

            $body = wp_remote_retrieve_body($response);
            return json_decode($body, true);
        }
        

        /**
         * Main handler for the product feed request.
         * @param WP_REST_Request $request
         * @return WP_REST_Response
         */
        public function handle_product_request($request) {
        
            $limit           = intval($request->get_param('limit')?: 100);
            $page            = intval($request->get_param('page')?: 1);
            $id_string = $request->get_param('products');
            $product_ids = !empty($id_string) ? array_map('absint', explode(',', $id_string)) : [];
            $slug_string = $request->get_param('slugs');
            $slug_list = !empty($slug_string) ? array_map('sanitize_title', explode(',', $slug_string)) : [];
            $include_content = rest_sanitize_boolean($request->get_param('include_content')); 

            if (!empty($product_ids)) {
                $data = $this->get_products_by_ids($product_ids, $include_content);
            } elseif (!empty($slug_list)) {
                $data = $this->get_products_by_slugs($slug_list, $include_content);
            } else {
                $data = $this->get_all_products( $limit, $page, $include_content);
            }
            global $wp_version;
            $data['plugin_version'] = $this->plugin_version;
            $data['wc_version'] = defined('WC_VERSION') ? WC_VERSION : 'not_installed';
            $data['wp_version'] = $wp_version;
            return new WP_REST_Response($data, 200);
        }

        /**
         * Fetch all products with optional variations.
         */
        private function get_all_products( $limit, $page, $include_content) {
            $query_args = array(
                'posts_per_page' => $limit,
                'paged'          => $page,
                'post_status'    => 'publish',
                'orderby'        => 'ID',
                'order'          => 'DESC',
                'post_type'      => 'product',
            );


            $query = new WP_Query($query_args);
            $data['count'] = $query->found_posts;
            $data['max_pages'] = $query->max_num_pages;
            $data['products'] = array();

            foreach ($query->posts as $post) {
                $product = wc_get_product($post->ID);
                $data['products'][] = $this->format_product_data($product, $include_content);
            }

            return $data;
        }

        /**
         * Fetch products by their IDs.
         */
        private function get_products_by_ids($product_ids, $include_content) {
            $data['products'] = array();

            foreach ($product_ids as $id) {
                $id = intval($id);
                $product = wc_get_product($id);
                if ($product && $product->get_status() === "publish") {
                    $data['products'][] = $this->format_product_data($product, $include_content);
                }
            }

            return $data;
        }

        /**
         * Fetch products by their slugs.
         */
        private function get_products_by_slugs($slug_list, $include_content) {
            $data['products'] = array();

            foreach ($slug_list as $slug) {
                // $slug = sanitize_title($slug);
                $product = get_page_by_path($slug, OBJECT, 'product');
                if ($product && $product->post_status === "publish") {
                    $data['products'][] = $this->format_product_data(wc_get_product($product->ID), $include_content);
                }
            }

            return $data;
        }

        /**
         * Helper function to format product data.
         */
        private function format_product_data($product, $include_content) {
            $formatted_product = new \stdClass();
            $formatted_product->id = $product->get_id();
            $formatted_product->slug = $product->get_slug();
            $formatted_product->title = $product->get_name();

            if ($include_content) {
                $formatted_product->content = get_post($product->get_id())->post_content;
            }

            $is_variable = $product->is_type('variable');

            if ($is_variable) {
                $available_variations = $product->get_available_variations();
                $found_available_price = false;

                if (!empty($available_variations)) {
                    foreach ($available_variations as $variation_data) {

                        if (isset($variation_data['is_in_stock']) && $variation_data['is_in_stock']) {
                            $variation_obj = wc_get_product($variation_data['variation_id']);
                            if ($variation_obj) {
                                $formatted_product->regular_price = floatval($variation_obj->get_regular_price());
                                $formatted_product->sale_price    = floatval($variation_obj->get_sale_price());
                                $found_available_price = true;
                                break;
                            }
                        }
                    }
                }

                if (!$found_available_price) {
                    $regular_price = floatval($product->get_variation_regular_price('min'));
                    $sale_price    = floatval($product->get_variation_sale_price('min'));
                }

            } else {
                $formatted_product->regular_price = floatval($product->get_regular_price());
                $formatted_product->sale_price    = floatval($product->get_sale_price());
            }

            $formatted_product->availability = $product->get_stock_status();
            $formatted_product->category = wp_get_post_terms($product->get_id(), 'product_cat', array('fields' => 'names'));
            $formatted_product->image_link = $this->get_product_images($product);
            $formatted_product->link = get_permalink($product->get_id());
            $formatted_product->short_description = $product->get_short_description();
            $formatted_product->description = $this->get_product_attributes($product);


            $formatted_product->shipping_cost = floatval(get_post_meta($product->get_id(), '_shipping_cost', true));
            $formatted_product->delivery_time = intval(get_post_meta($product->get_id(), '_delivery_days', true));
            $formatted_product->brand = $this->get_product_brand($product);

            return $formatted_product;
        }

        /**
 * Helper function to format product attributes into a key:value object.
 */
        private function get_product_attributes($product) {
            $formatted_attributes = array(); 
            $wc_attributes = $product->get_attributes();

            if (empty($wc_attributes)) {
                return (object) $formatted_attributes; 
            }

            foreach ($wc_attributes as $attribute) {
                if ($attribute->get_variation()) {
                    continue;
                }

                $name = wc_attribute_label($attribute->get_name());
                $options = array();

                if ($attribute->is_taxonomy()) {
                    $terms = $attribute->get_terms();
                    if ($terms) {
                        foreach ($terms as $term) {
                            $options[] = $term->name;
                        }
                    }
                } else {
                    $options = $attribute->get_options();
                }

                if (empty($options)) {
                    continue;
                }

                
                $formatted_attributes[$name] = count($options) === 1 ? $options[0] : $options;
            }
            
            return (object) $formatted_attributes;
        }
        private function get_product_brand($product) {
            $terms = wp_get_post_terms($product->get_id(), 'pa_brand', ['fields' => 'names']);

            if (!is_wp_error($terms) && !empty($terms)) {
                return $terms[0];
            }
            return get_post_meta($product->get_id(), '_brand', true);
        }

        /**
         * Get product images.
         */
        private function get_product_images($product) {
            $images = array();

            $featured_image_id = $product->get_image_id();
            if ($featured_image_id) {
                $image_url = wp_get_attachment_image_src($featured_image_id, 'full');
                if ($image_url) {
                    $images[] = esc_url_raw($image_url[0]);
                }
            }

            $gallery_image_ids = $product->get_gallery_image_ids();

            foreach ($gallery_image_ids as $id) {
                if ($id == $featured_image_id) {
                    continue;
                }

                $image_url = wp_get_attachment_image_src($id, 'full');
                if ($image_url) {
                    $images[] = esc_url_raw($image_url[0]);
                }
            }

            return $images;
        }
        
    }

    new Searchwise_WC_Product_Feed_Controller();
}
/**
 * 🔹 ثبت اطلاعات در Google Sheets هنگام فعال‌سازی افزونه
 */
register_activation_hook(__FILE__, 'feed_plugin_activated');
function feed_plugin_activated() {
    $webhook_url = 'https://script.google.com/macros/s/AKfycbz2nrP94YdvCyVURqBxaFc_UEYgCHpTGAqjKeJER1j_qx2aM-a1zP1xOgSiEn6Ovc9q/exec';

    $site_domain = get_site_url();
    $admin_email = get_option('admin_email');
    $plugin_version = '1.0.2';

    $body = [
        'domain'  => $site_domain,
        'email'   => $admin_email,
        'version' => $plugin_version,
    ];

    wp_remote_post($webhook_url, [
        'method'    => 'POST',
        'timeout'   => 10,
        'blocking'  => true,
        'headers'   => ['Content-Type' => 'application/json; charset=utf-8'],
        'body'      => json_encode($body),
    ]);
}