<?php
/**
 * Live Feed REST API endpoints.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Core\Rest;

use PrimeLink\Modules\LiveFeed\LiveFeedService;
use PrimeLink\Modules\LiveFeed\LiveFeedSyncService;

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

final class LiveFeedRest {

    const NAMESPACE = 'primelink/v1';

    /**
     * Register REST routes.
     */
    public static function register() {
        add_action( 'rest_api_init', array( __CLASS__, 'register_routes' ) );
    }

    /**
     * Register routes.
     */
    public static function register_routes() {
        // Public endpoint for feed access (requires API key)
        register_rest_route(
            self::NAMESPACE,
            '/live-feed/products',
            array(
                'methods'             => 'GET',
                'callback'            => array( __CLASS__, 'get_products_feed' ),
                'permission_callback' => array( __CLASS__, 'verify_api_key' ),
            )
        );

        // Admin endpoints (require WordPress authentication)
        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds',
            array(
                'methods'             => 'GET',
                'callback'            => array( __CLASS__, 'get_feeds' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds',
            array(
                'methods'             => 'POST',
                'callback'            => array( __CLASS__, 'create_feed' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds/(?P<id>[a-zA-Z0-9_]+)',
            array(
                'methods'             => 'GET',
                'callback'            => array( __CLASS__, 'get_feed' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds/(?P<id>[a-zA-Z0-9_]+)',
            array(
                'methods'             => 'PUT',
                'callback'            => array( __CLASS__, 'update_feed' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds/(?P<id>[a-zA-Z0-9_]+)',
            array(
                'methods'             => 'DELETE',
                'callback'            => array( __CLASS__, 'delete_feed' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds/(?P<id>[a-zA-Z0-9_]+)/sync',
            array(
                'methods'             => 'POST',
                'callback'            => array( __CLASS__, 'sync_feed' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        // External sync endpoint (for real cron). Protected by per-feed token.
        register_rest_route(
            self::NAMESPACE,
            '/live-feed/feeds/(?P<id>[a-zA-Z0-9_]+)/external-sync',
            array(
                'methods'             => 'POST',
                'callback'            => array( __CLASS__, 'external_sync_feed' ),
                'permission_callback' => '__return_true',
            )
        );

        // API Key management
        register_rest_route(
            self::NAMESPACE,
            '/live-feed/api-keys',
            array(
                'methods'             => 'GET',
                'callback'            => array( __CLASS__, 'get_api_keys' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/api-keys',
            array(
                'methods'             => 'POST',
                'callback'            => array( __CLASS__, 'create_api_key' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/live-feed/api-keys/(?P<id>[a-zA-Z0-9_]+)',
            array(
                'methods'             => 'DELETE',
                'callback'            => array( __CLASS__, 'revoke_api_key' ),
                'permission_callback' => array( __CLASS__, 'permission' ),
            )
        );
    }

    /**
     * Permission callback for admin endpoints.
     */
    public static function permission() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return new \WP_Error(
                'rest_forbidden',
                __( 'You are not allowed to manage Live Feeds.', 'primelink' ),
                array( 'status' => 403 )
            );
        }
        return true;
    }

    /**
     * Verify API key for feed access.
     */
    public static function verify_api_key( $request ) {
        $api_key = $request->get_header( 'X-API-Key' );
        if ( empty( $api_key ) ) {
            $api_key = $request->get_param( 'api_key' );
        }

        if ( empty( $api_key ) ) {
            return new \WP_Error(
                'rest_forbidden',
                __( 'API key is required.', 'primelink' ),
                array( 'status' => 401 )
            );
        }

        $key_data = LiveFeedService::verify_api_key( $api_key );
        if ( ! $key_data ) {
            return new \WP_Error(
                'rest_forbidden',
                __( 'Invalid API key.', 'primelink' ),
                array( 'status' => 401 )
            );
        }

        return true;
    }

    /**
     * Get products feed (public endpoint).
     */
    public static function get_products_feed( $request ) {
        $modified_since = $request->get_param( 'modified_since' );
        $limit = absint( $request->get_param( 'limit' ) ) ?: 100;
        $offset = absint( $request->get_param( 'offset' ) ) ?: 0;

        $args = array(
            'post_type'      => 'product',
            'posts_per_page' => $limit,
            'offset'         => $offset,
            'post_status'    => 'publish',
            'orderby'        => 'modified',
            'order'          => 'DESC',
        );

        if ( $modified_since ) {
            $args['date_query'] = array(
                array(
                    'column'    => 'post_modified',
                    'after'     => $modified_since,
                    'inclusive' => false,
                ),
            );
        }

        $products = get_posts( $args );
        $feed_data = array();

        foreach ( $products as $product ) {
            $wc_product = wc_get_product( $product->ID );
            if ( ! $wc_product ) {
                continue;
            }

            $feed_data[] = array(
                'id'            => $product->ID,
                'sku'           => $wc_product->get_sku(),
                'name'          => $product->post_title,
                'description'   => $product->post_content,
                'short_description' => $product->post_excerpt,
                'price'         => $wc_product->get_regular_price(),
                'sale_price'    => $wc_product->get_sale_price(),
                'stock_quantity' => $wc_product->get_stock_quantity(),
                'stock_status'  => $wc_product->get_stock_status(),
                'weight'        => $wc_product->get_weight(),
                'length'        => $wc_product->get_length(),
                'width'         => $wc_product->get_width(),
                'height'        => $wc_product->get_height(),
                'categories'    => wp_get_post_terms( $product->ID, 'product_cat', array( 'fields' => 'names' ) ),
                'tags'          => wp_get_post_terms( $product->ID, 'product_tag', array( 'fields' => 'names' ) ),
                'images'        => self::get_product_images( $wc_product ),
                'modified'      => $product->post_modified,
            );
        }

        return array(
            'products' => $feed_data,
            'total'    => count( $feed_data ),
            'limit'    => $limit,
            'offset'   => $offset,
        );
    }

    /**
     * Get product images.
     */
    private static function get_product_images( $product ) {
        $images = array();
        $image_id = $product->get_image_id();
        if ( $image_id ) {
            $images[] = wp_get_attachment_image_url( $image_id, 'full' );
        }
        $gallery_ids = $product->get_gallery_image_ids();
        foreach ( $gallery_ids as $gallery_id ) {
            $images[] = wp_get_attachment_image_url( $gallery_id, 'full' );
        }
        return $images;
    }

    /**
     * Get all feeds.
     */
    public static function get_feeds( $request ) {
        $feeds  = LiveFeedService::get_feeds();
        $result = array();

        foreach ( $feeds as $feed_id => $feed ) {
            // Ensure ID is present.
            if ( empty( $feed['id'] ) ) {
                $feed['id'] = $feed_id;
            }

            // Build external sync URL (admin-only context, but route itself is public w/ token).
            if ( ! empty( $feed['sync_token'] ) ) {
                $feed['external_sync_url'] = add_query_arg(
                    'token',
                    $feed['sync_token'],
                    rest_url( self::NAMESPACE . '/live-feed/feeds/' . $feed['id'] . '/external-sync' )
                );
            }

            $result[] = $feed;
        }

        return array( 'feeds' => $result );
    }

    /**
     * Create feed.
     */
    public static function create_feed( $request ) {
        $data = $request->get_json_params();
        $feed = LiveFeedService::create_feed( $data );
        return $feed;
    }

    /**
     * Get feed by ID.
     */
    public static function get_feed( $request ) {
        $feed_id = $request['id'];
        $feed = LiveFeedService::get_feed( $feed_id );
        if ( ! $feed ) {
            return new \WP_REST_Response( array( 'message' => 'Feed not found.' ), 404 );
        }
        return $feed;
    }

    /**
     * Update feed.
     */
    public static function update_feed( $request ) {
        $feed_id = $request['id'];
        $data = $request->get_json_params();
        $success = LiveFeedService::update_feed( $feed_id, $data );
        if ( ! $success ) {
            return new \WP_REST_Response( array( 'message' => 'Feed not found.' ), 404 );
        }
        return LiveFeedService::get_feed( $feed_id );
    }

    /**
     * Delete feed.
     */
    public static function delete_feed( $request ) {
        $feed_id = $request['id'];
        $success = LiveFeedService::delete_feed( $feed_id );
        if ( ! $success ) {
            return new \WP_REST_Response( array( 'message' => 'Feed not found.' ), 404 );
        }
        return array( 'success' => true );
    }

    /**
     * Sync feed manually.
     */
    public static function sync_feed( $request ) {
        $feed_id = $request['id'];
        $feed = LiveFeedService::get_feed( $feed_id );
        if ( ! $feed ) {
            return new \WP_REST_Response( array( 'message' => 'Feed not found.' ), 404 );
        }

        $result = LiveFeedSyncService::sync_feed( $feed_id );
        return $result;
    }

    /**
     * External sync (token-based, for real cron jobs).
     *
     * @param \WP_REST_Request $request Request.
     * @return array|\WP_REST_Response
     */
    public static function external_sync_feed( $request ) {
        $feed_id = $request['id'];
        $token   = $request->get_param( 'token' );

        $feed = LiveFeedService::get_feed( $feed_id );
        if ( ! $feed || empty( $feed['sync_token'] ) ) {
            return new \WP_REST_Response( array( 'message' => 'Feed not found.' ), 404 );
        }

        if ( empty( $token ) || ! hash_equals( (string) $feed['sync_token'], (string) $token ) ) {
            return new \WP_REST_Response( array( 'message' => 'Invalid token.' ), 403 );
        }

        $result = LiveFeedSyncService::sync_feed( $feed_id );
        return $result;
    }

    /**
     * Get API keys.
     */
    public static function get_api_keys( $request ) {
        $keys = LiveFeedService::get_api_keys();
        return array( 'keys' => array_values( $keys ) );
    }

    /**
     * Create API key.
     */
    public static function create_api_key( $request ) {
        $data = $request->get_json_params();
        $name = sanitize_text_field( $data['name'] ?? 'API Key' );
        $permissions = $data['permissions'] ?? array( 'read' );
        
        $result = LiveFeedService::generate_api_key( $name, $permissions );
        return $result;
    }

    /**
     * Revoke API key.
     */
    public static function revoke_api_key( $request ) {
        $key_id = $request['id'];
        $success = LiveFeedService::revoke_api_key( $key_id );
        if ( ! $success ) {
            return new \WP_REST_Response( array( 'message' => 'API key not found.' ), 404 );
        }
        return array( 'success' => true );
    }
}

