<?php
/**
 * Live Feed Service - Manages live feed connections and API keys.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Modules\LiveFeed;

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

final class LiveFeedService {

    const OPTION_KEY_FEEDS = 'mt_primelink_live_feeds';
    const OPTION_KEY_API_KEYS = 'mt_primelink_live_feed_api_keys';

    /**
     * Generate a new API key.
     *
     * @param string $name Feed name.
     * @param array  $permissions Permissions (read, write, etc.).
     * @return array API key data.
     */
    public static function generate_api_key( $name, $permissions = array() ) {
        $api_key = wp_generate_password( 32, false );
        $api_secret = wp_generate_password( 32, false );
        $key_hash = hash( 'sha256', $api_key );

        $keys = get_option( self::OPTION_KEY_API_KEYS, array() );
        $key_id = time() . '_' . wp_generate_password( 8, false );

        $keys[ $key_id ] = array(
            'name'        => sanitize_text_field( $name ),
            'key_hash'    => $key_hash,
            'api_secret'  => $api_secret,
            'permissions' => $permissions,
            'created_at'  => current_time( 'mysql' ),
            'last_used'   => null,
            'status'      => 'active',
        );

        update_option( self::OPTION_KEY_API_KEYS, $keys, false );

        return array(
            'key_id'     => $key_id,
            'api_key'    => $api_key, // Only returned once!
            'api_secret' => $api_secret,
            'name'       => $name,
        );
    }

    /**
     * Verify API key.
     *
     * @param string $api_key API key.
     * @return array|false Key data or false if invalid.
     */
    public static function verify_api_key( $api_key ) {
        if ( empty( $api_key ) ) {
            return false;
        }

        $key_hash = hash( 'sha256', $api_key );
        $keys = get_option( self::OPTION_KEY_API_KEYS, array() );

        foreach ( $keys as $key_id => $key_data ) {
            if ( hash_equals( $key_data['key_hash'], $key_hash ) && $key_data['status'] === 'active' ) {
                // Update last used
                $keys[ $key_id ]['last_used'] = current_time( 'mysql' );
                update_option( self::OPTION_KEY_API_KEYS, $keys, false );

                return array_merge( $key_data, array( 'key_id' => $key_id ) );
            }
        }

        return false;
    }

    /**
     * Revoke API key.
     *
     * @param string $key_id Key ID.
     * @return bool Success.
     */
    public static function revoke_api_key( $key_id ) {
        $keys = get_option( self::OPTION_KEY_API_KEYS, array() );
        if ( ! isset( $keys[ $key_id ] ) ) {
            return false;
        }

        $keys[ $key_id ]['status'] = 'revoked';
        $keys[ $key_id ]['revoked_at'] = current_time( 'mysql' );

        return update_option( self::OPTION_KEY_API_KEYS, $keys, false );
    }

    /**
     * Get all API keys.
     *
     * @return array API keys (without actual key values for security).
     */
    public static function get_api_keys() {
        $keys = get_option( self::OPTION_KEY_API_KEYS, array() );
        $result = array();

        foreach ( $keys as $key_id => $key_data ) {
            $result[ $key_id ] = array(
                'key_id'     => $key_id,
                'name'       => $key_data['name'],
                'created_at' => $key_data['created_at'],
                'last_used'  => $key_data['last_used'] ?? null,
                'status'     => $key_data['status'],
                'permissions' => $key_data['permissions'] ?? array(),
            );
        }

        return $result;
    }

    /**
     * Create a new live feed connection.
     *
     * @param array $data Feed data.
     * @return array Feed with ID.
     */
    public static function create_feed( $data ) {
        $feeds = get_option( self::OPTION_KEY_FEEDS, array() );
        $feed_id = time() . '_' . wp_generate_password( 8, false );

        $feed = array(
            'id'          => $feed_id,
            'name'        => sanitize_text_field( $data['name'] ?? '' ),
            'source_url'  => esc_url_raw( $data['source_url'] ?? '' ),
            'api_key'     => sanitize_text_field( $data['api_key'] ?? '' ),
            // Source type: prime_woocommerce (default, PrimeLink ↔ PrimeLink) or woocommerce_rest.
            // More types (generic_json, etc.) can be added later.
            'source_type' => sanitize_text_field( $data['source_type'] ?? 'prime_woocommerce' ),
            // WooCommerce REST credentials (used only when source_type === 'woocommerce_rest').
            'wc_consumer_key'    => sanitize_text_field( $data['wc_consumer_key'] ?? '' ),
            'wc_consumer_secret' => sanitize_text_field( $data['wc_consumer_secret'] ?? '' ),
            // Fields to synchronize. Defaults: all major fields.
            'sync_fields' => isset( $data['sync_fields'] ) && is_array( $data['sync_fields'] )
                ? array_values( array_unique( array_map( 'sanitize_text_field', $data['sync_fields'] ) ) )
                : array( 'price', 'stock', 'description', 'images', 'categories', 'tags' ),
            'sync_type'   => sanitize_text_field( $data['sync_type'] ?? 'products' ),
            'sync_mode'   => sanitize_text_field( $data['sync_mode'] ?? 'auto' ), // auto, manual, scheduled
            'interval'    => absint( $data['interval'] ?? 300 ), // seconds
            'last_sync'   => null,
            'next_sync'   => null,
            'status'      => sanitize_text_field( $data['status'] ?? 'active' ),
            'created_at'  => current_time( 'mysql' ),
            'updated_at'  => current_time( 'mysql' ),
            'stats'       => array(
                'total_syncs'    => 0,
                'total_products' => 0,
                'last_error'     => null,
            ),
            // External sync token for real cron jobs.
            'sync_token'  => wp_generate_password( 32, false ),
        );

        $feeds[ $feed_id ] = $feed;
        update_option( self::OPTION_KEY_FEEDS, $feeds, false );

        return $feed;
    }

    /**
     * Get all feeds.
     *
     * @return array Feeds.
     */
    public static function get_feeds() {
        return get_option( self::OPTION_KEY_FEEDS, array() );
    }

    /**
     * Get feed by ID.
     *
     * @param string $feed_id Feed ID.
     * @return array|false Feed data or false.
     */
    public static function get_feed( $feed_id ) {
        $feeds = get_option( self::OPTION_KEY_FEEDS, array() );
        return $feeds[ $feed_id ] ?? false;
    }

    /**
     * Update feed.
     *
     * @param string $feed_id Feed ID.
     * @param array  $data Update data.
     * @return bool Success.
     */
    public static function update_feed( $feed_id, $data ) {
        $feeds = get_option( self::OPTION_KEY_FEEDS, array() );
        if ( ! isset( $feeds[ $feed_id ] ) ) {
            return false;
        }

        $feed = $feeds[ $feed_id ];
        
        if ( isset( $data['name'] ) ) {
            $feed['name'] = sanitize_text_field( $data['name'] );
        }
        if ( isset( $data['source_url'] ) ) {
            $feed['source_url'] = esc_url_raw( $data['source_url'] );
        }
        if ( isset( $data['api_key'] ) ) {
            $feed['api_key'] = sanitize_text_field( $data['api_key'] );
        }
        if ( isset( $data['source_type'] ) ) {
            $feed['source_type'] = sanitize_text_field( $data['source_type'] );
        }
        if ( isset( $data['wc_consumer_key'] ) ) {
            $feed['wc_consumer_key'] = sanitize_text_field( $data['wc_consumer_key'] );
        }
        if ( isset( $data['wc_consumer_secret'] ) ) {
            $feed['wc_consumer_secret'] = sanitize_text_field( $data['wc_consumer_secret'] );
        }
        if ( isset( $data['sync_fields'] ) && is_array( $data['sync_fields'] ) ) {
            $feed['sync_fields'] = array_values( array_unique( array_map( 'sanitize_text_field', $data['sync_fields'] ) ) );
        }
        if ( isset( $data['sync_type'] ) ) {
            $feed['sync_type'] = sanitize_text_field( $data['sync_type'] );
        }
        if ( isset( $data['sync_mode'] ) ) {
            $feed['sync_mode'] = sanitize_text_field( $data['sync_mode'] );
        }
        if ( isset( $data['interval'] ) ) {
            $feed['interval'] = absint( $data['interval'] );
        }
        if ( isset( $data['status'] ) ) {
            $feed['status'] = sanitize_text_field( $data['status'] );
        }

        $feed['updated_at'] = current_time( 'mysql' );
        $feeds[ $feed_id ] = $feed;

        return update_option( self::OPTION_KEY_FEEDS, $feeds, false );
    }

    /**
     * Delete feed.
     *
     * @param string $feed_id Feed ID.
     * @return bool Success.
     */
    public static function delete_feed( $feed_id ) {
        $feeds = get_option( self::OPTION_KEY_FEEDS, array() );
        if ( ! isset( $feeds[ $feed_id ] ) ) {
            return false;
        }

        unset( $feeds[ $feed_id ] );
        return update_option( self::OPTION_KEY_FEEDS, $feeds, false );
    }

    /**
     * Update feed sync stats.
     *
     * @param string $feed_id Feed ID.
     * @param array  $stats Stats to update.
     * @return bool Success.
     */
    public static function update_feed_stats( $feed_id, $stats ) {
        $feeds = get_option( self::OPTION_KEY_FEEDS, array() );
        if ( ! isset( $feeds[ $feed_id ] ) ) {
            return false;
        }

        $feed = $feeds[ $feed_id ];
        $feed['last_sync'] = current_time( 'mysql' );
        $feed['next_sync'] = date( 'Y-m-d H:i:s', time() + $feed['interval'] );
        
        if ( isset( $stats['total_syncs'] ) ) {
            $feed['stats']['total_syncs'] = absint( $stats['total_syncs'] );
        }
        if ( isset( $stats['total_products'] ) ) {
            $feed['stats']['total_products'] = absint( $stats['total_products'] );
        }
        if ( isset( $stats['last_error'] ) ) {
            $feed['stats']['last_error'] = sanitize_textarea_field( $stats['last_error'] );
        }

        $feeds[ $feed_id ] = $feed;
        return update_option( self::OPTION_KEY_FEEDS, $feeds, false );
    }

    /**
     * Get normalized sync fields for a feed.
     *
     * @param array $feed Feed data.
     * @return array List of sync field keys.
     */
    public static function get_sync_fields( $feed ) {
        $defaults = array( 'price', 'stock', 'description', 'images', 'categories', 'tags' );
        $fields   = isset( $feed['sync_fields'] ) && is_array( $feed['sync_fields'] ) ? $feed['sync_fields'] : $defaults;
        $fields   = array_values( array_intersect( $fields, $defaults ) );

        // Fallback to all defaults if nothing valid left.
        return ! empty( $fields ) ? $fields : $defaults;
    }
}

