<?php
/**
 * Platform Connector Service - Manages platform connectors and real-time sync.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Modules\Imports\Service;

use PrimeLink\Modules\Imports\Connectors\PlatformConnectorInterface;
use PrimeLink\Modules\Imports\Connectors\ShopifyConnector;
use PrimeLink\Modules\Imports\Connectors\MagentoConnector;
use PrimeLink\Modules\Imports\Connectors\BigCommerceConnector;

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

final class PlatformConnectorService {

    /**
     * Get available connectors.
     *
     * @return array
     */
    public static function get_connectors() {
        return array(
            'shopify'      => new ShopifyConnector(),
            'magento'      => new MagentoConnector(),
            'bigcommerce'  => new BigCommerceConnector(),
        );
    }

    /**
     * Get connector by name.
     *
     * @param string $name Connector name.
     * @return PlatformConnectorInterface|null
     */
    public static function get_connector( $name ) {
        $connectors = self::get_connectors();
        return $connectors[ $name ] ?? null;
    }

    /**
     * Test connection with platform.
     *
     * @param string $connector_name Connector name.
     * @param array  $credentials   Connection credentials.
     * @return array
     */
    public static function test_connection( $connector_name, $credentials ) {
        $connector = self::get_connector( $connector_name );
        if ( ! $connector ) {
            return array(
                'success' => false,
                'message' => 'Connector not found.',
            );
        }

        return $connector->test_connection( $credentials );
    }

    /**
     * Fetch data from platform.
     *
     * @param string $connector_name Connector name.
     * @param array  $credentials   Connection credentials.
     * @param string $data_type     Data type (products, orders, customers).
     * @param array  $options       Fetch options.
     * @return array
     */
    public static function fetch_data( $connector_name, $credentials, $data_type, $options = array() ) {
        $connector = self::get_connector( $connector_name );
        if ( ! $connector ) {
            return array(
                'success' => false,
                'error'   => 'Connector not found.',
            );
        }

        // Build cache key from connector, data type, and options
        // Only cache if not using pagination (to avoid stale data)
        $use_cache = empty( $options['page'] ) && empty( $options['since_id'] );
        $cache_key = null;
        
        if ( $use_cache ) {
            $cache_key = sprintf(
                'platform_%s_%s_%s',
                $connector_name,
                $data_type,
                md5( serialize( array( $credentials, $options ) ) )
            );
            
            $cached = \PrimeLink\Helpers\CacheHelper::get( $cache_key );
            if ( $cached !== null ) {
                return $cached;
            }
        }

        // Validate credentials before fetching
        if ( empty( $credentials ) || ! is_array( $credentials ) ) {
            return array(
                'success' => false,
                'error'   => 'Invalid credentials: Credentials are empty or not an array.',
            );
        }
        
        // Log credentials validation (without exposing sensitive data)
        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
            \PrimeLink\Helpers\LoggerHelper::debug(
                'Platform Connector Fetch Data',
                array(
                    'connector'     => $connector_name,
                    'data_type'     => $data_type,
                    'has_token'     => ! empty( $credentials['access_token'] ),
                    'token_length'  => isset( $credentials['access_token'] ) ? strlen( $credentials['access_token'] ) : 0,
                    'has_store_hash' => ! empty( $credentials['store_hash'] ),
                    'has_account_uuid' => ! empty( $credentials['account_uuid'] ),
                    'credentials_keys' => array_keys( $credentials ),
                )
            );
        }

        // Fetch from platform
        $result = null;
        switch ( $data_type ) {
            case 'products':
                $result = $connector->fetch_products( $credentials, $options );
                break;
            case 'orders':
                $result = $connector->fetch_orders( $credentials, $options );
                break;
            case 'customers':
                $result = $connector->fetch_customers( $credentials, $options );
                break;
            case 'coupons':
                // Optional: only BigCommerce currently supports coupons in our connector
                if ( method_exists( $connector, 'fetch_coupons' ) ) {
                    $result = $connector->fetch_coupons( $credentials, $options );
                } else {
                    $result = array(
                        'success' => false,
                        'error'   => 'Coupons import is not supported for this platform connector yet.',
                    );
                }
                break;
            default:
                $result = array(
                    'success' => false,
                    'error'   => 'Invalid data type.',
                );
        }

        // Cache successful results for 5 minutes
        if ( $use_cache && $cache_key && isset( $result['success'] ) && $result['success'] ) {
            \PrimeLink\Helpers\CacheHelper::set( $cache_key, $result, 300 ); // 5 minutes
        }

        return $result;
    }

    /**
     * Convert platform data to import format.
     *
     * @param string $connector_name Connector name.
     * @param array  $platform_data Platform data.
     * @param string $data_type     Data type.
     * @return array
     */
    public static function convert_data( $connector_name, $platform_data, $data_type ) {
        $connector = self::get_connector( $connector_name );
        if ( ! $connector ) {
            return array();
        }

        return $connector->convert_to_woocommerce( $platform_data, $data_type );
    }

    /**
     * Register webhook for real-time sync.
     *
     * @param int    $import_id     Import ID.
     * @param string $connector_name Connector name.
     * @param array  $credentials   Connection credentials.
     * @param array  $events        Events to sync.
     * @return array
     */
    public static function register_webhooks( $import_id, $connector_name, $credentials, $events ) {
        $connector = self::get_connector( $connector_name );
        if ( ! $connector ) {
            return array(
                'success' => false,
                'error'   => 'Connector not found.',
            );
        }

        $webhook_url = self::get_webhook_url( $import_id );
        $webhook_ids = array();

        foreach ( $events as $event ) {
            $full_event = self::build_event_name( $connector_name, $event );
            $result = $connector->register_webhook( $credentials, $full_event, $webhook_url );
            if ( $result['success'] ) {
                $webhook_ids[] = array(
                    'event'      => $event,
                    'webhook_id' => $result['webhook_id'] ?? '',
                );
            }
        }

        // Store webhook IDs
        if ( ! empty( $webhook_ids ) ) {
            update_option( 'mt_primelink_webhooks_' . $import_id, $webhook_ids, false );
        }

        return array(
            'success'     => true,
            'webhook_ids' => $webhook_ids,
        );
    }

    /**
     * Unregister webhooks.
     *
     * @param int    $import_id     Import ID.
     * @param string $connector_name Connector name.
     * @param array  $credentials   Connection credentials.
     * @return bool
     */
    public static function unregister_webhooks( $import_id, $connector_name, $credentials ) {
        $webhook_ids = get_option( 'mt_primelink_webhooks_' . $import_id, array() );
        if ( empty( $webhook_ids ) ) {
            return true;
        }

        $connector = self::get_connector( $connector_name );
        if ( ! $connector ) {
            return false;
        }

        $all_success = true;
        foreach ( $webhook_ids as $webhook ) {
            $success = $connector->unregister_webhook( $credentials, $webhook['webhook_id'] ?? '' );
            if ( ! $success ) {
                $all_success = false;
            }
        }

        if ( $all_success ) {
            delete_option( 'mt_primelink_webhooks_' . $import_id );
        }

        return $all_success;
    }

    /**
     * Get webhook URL for import.
     *
     * @param int $import_id Import ID.
     * @return string
     */
    private static function get_webhook_url( $import_id ) {
        return rest_url( 'primelink/v1/webhook/' . absint( $import_id ) );
    }

    /**
     * Build event name for platform.
     *
     * @param string $connector_name Connector name.
     * @param string $event         Event type.
     * @return string
     */
    private static function build_event_name( $connector_name, $event ) {
        // Shopify events
        if ( $connector_name === 'shopify' ) {
            $event_map = array(
                'created' => 'products/create',
                'updated' => 'products/update',
                'deleted' => 'products/delete',
            );
            return $event_map[ $event ] ?? 'products/' . $event;
        }

        // BigCommerce events (handled directly in connector)
        if ( $connector_name === 'bigcommerce' ) {
            return $event; // Connector handles mapping internally
        }

        return $event;
    }

    /**
     * Process webhook payload.
     *
     * @param int    $import_id Import ID.
     * @param array  $payload   Webhook payload.
     * @return array
     */
    public static function process_webhook( $import_id, $payload ) {
        $draft = ImportRunner::get_draft( $import_id );
        if ( empty( $draft ) ) {
            return array(
                'success' => false,
                'error'   => 'Import not found.',
            );
        }

        $connector_name = $draft['step_data'][2]['connector'] ?? '';
        $credentials    = $draft['step_data'][2]['credentials'] ?? array();
        $data_type      = $draft['step_data'][2]['data_type'] ?? 'products';

        if ( empty( $connector_name ) ) {
            return array(
                'success' => false,
                'error'   => 'Connector not configured.',
            );
        }

        // Extract platform data from webhook payload
        $platform_data = self::extract_webhook_data( $connector_name, $payload );

        if ( empty( $platform_data ) ) {
            return array(
                'success' => false,
                'error'   => 'Invalid webhook payload.',
            );
        }

        // Convert to WooCommerce format
        $woo_data = self::convert_data( $connector_name, $platform_data, $data_type );

        // Import the item
        return self::import_webhook_item( $import_id, $woo_data, $data_type );
    }

    /**
     * Extract platform data from webhook payload.
     *
     * @param string $connector_name Connector name.
     * @param array  $payload        Webhook payload.
     * @return array
     */
    private static function extract_webhook_data( $connector_name, $payload ) {
        if ( $connector_name === 'shopify' ) {
            // Shopify webhook format
            return $payload['product'] ?? $payload['order'] ?? $payload['customer'] ?? array();
        }

        if ( $connector_name === 'bigcommerce' ) {
            // BigCommerce webhook format
            return $payload['data'] ?? $payload['product'] ?? $payload['order'] ?? $payload['customer'] ?? array();
        }

        if ( $connector_name === 'magento' ) {
            // Magento webhook format
            return $payload['data'] ?? $payload;
        }

        return $payload;
    }

    /**
     * Import item from webhook.
     *
     * @param int    $import_id Import ID.
     * @param array  $woo_data  WooCommerce-formatted data.
     * @param string $data_type Data type.
     * @return array
     */
    private static function import_webhook_item( $import_id, $woo_data, $data_type ) {
        // This would trigger a mini-import for the single item
        // For now, return success - full implementation would process the item
        return array(
            'success' => true,
            'message' => 'Webhook processed successfully.',
        );
    }
}

