<?php
/**
 * Magento Connector - Real-time import from Magento.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Modules\Imports\Connectors;

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

final class MagentoConnector implements PlatformConnectorInterface {

    /**
     * Get connector name.
     *
     * @return string
     */
    public function get_name() {
        return 'magento';
    }

    /**
     * Get connector display name.
     *
     * @return string
     */
    public function get_display_name() {
        return 'Magento';
    }

    /**
     * Get required credentials fields.
     *
     * @return array
     */
    public function get_credentials_fields() {
        return array(
            'base_url' => array(
                'label'       => 'Magento Base URL',
                'type'        => 'text',
                'placeholder' => 'https://your-store.com',
                'required'    => true,
                'description' => 'Your Magento store base URL',
            ),
            'access_token' => array(
                'label'       => 'Access Token',
                'type'        => 'password',
                'placeholder' => 'Your Magento access token',
                'required'    => true,
                'description' => 'REST API access token',
            ),
        );
    }

    /**
     * Build API URL.
     *
     * @param string $base_url Base URL.
     * @param string $endpoint  API endpoint.
     * @return string
     */
    private function build_api_url( $base_url, $endpoint ) {
        $base_url = rtrim( $base_url, '/' );
        return $base_url . '/rest/default/V1/' . ltrim( $endpoint, '/' );
    }

    /**
     * Make API request.
     *
     * @param string $url          API URL.
     * @param string $access_token Access token.
     * @param string $method       HTTP method.
     * @param array  $data         Request data.
     * @return array
     */
    private function api_request( $url, $access_token, $method = 'GET', $data = array() ) {
        $args = array(
            'headers' => array(
                'Authorization' => 'Bearer ' . $access_token,
                'Content-Type'  => 'application/json',
            ),
            'timeout'     => 30,
            'retry'       => 2, // Retry up to 2 times on failure
            'retry_delay' => 1, // 1 second delay between retries
        );

        if ( ! empty( $data ) && in_array( $method, array( 'POST', 'PUT', 'PATCH' ), true ) ) {
            $args['body'] = $data; // HttpHelper will handle JSON encoding
        }

        $response = \PrimeLink\Helpers\HttpHelper::request( $url, $method, $args );

        if ( ! $response['success'] ) {
            return array(
                'success' => false,
                'error'   => $response['error'] ?? 'API request failed',
            );
        }

        $body = $response['body'];
        $code = $response['code'];
        $decoded_data = json_decode( $body, true );

        if ( $code >= 200 && $code < 300 ) {
            return array(
                'success' => true,
                'data'    => $decoded_data,
            );
        }

        return array(
            'success' => false,
            'error'   => isset( $decoded_data['message'] ) ? $decoded_data['message'] : 'API request failed',
            'code'    => $code,
        );
    }

    /**
     * Test connection with platform.
     *
     * @param array $credentials Connection credentials.
     * @return array
     */
    public function test_connection( $credentials ) {
        $base_url     = $credentials['base_url'] ?? '';
        $access_token = $credentials['access_token'] ?? '';

        if ( empty( $base_url ) || empty( $access_token ) ) {
            return array(
                'success' => false,
                'message' => 'Missing required credentials.',
            );
        }

        $url = $this->build_api_url( $base_url, 'store/storeViews' );
        $result = $this->api_request( $url, $access_token );

        if ( $result['success'] ) {
            return array(
                'success' => true,
                'message' => 'Connection successful!',
                'data'    => $result['data'] ?? array(),
            );
        }

        return array(
            'success' => false,
            'message' => $result['error'] ?? 'Connection failed.',
        );
    }

    /**
     * Fetch products from platform.
     *
     * @param array $credentials Connection credentials.
     * @param array $options     Fetch options.
     * @return array
     */
    public function fetch_products( $credentials, $options = array() ) {
        $base_url     = $credentials['base_url'] ?? '';
        $access_token = $credentials['access_token'] ?? '';
        $limit        = isset( $options['limit'] ) ? absint( $options['limit'] ) : 20;
        $page         = isset( $options['page'] ) ? absint( $options['page'] ) : 1;

        if ( empty( $base_url ) || empty( $access_token ) ) {
            return array(
                'success' => false,
                'error'   => 'Missing required credentials.',
            );
        }

        $search_criteria = array(
            'searchCriteria' => array(
                'pageSize' => $limit,
                'currentPage' => $page,
            ),
        );

        $url = $this->build_api_url( $base_url, 'products?' . http_build_query( $search_criteria ) );
        $result = $this->api_request( $url, $access_token );

        if ( ! $result['success'] ) {
            return $result;
        }

        $products = $result['data']['items'] ?? array();
        $total = $result['data']['total_count'] ?? count( $products );
        $has_more = count( $products ) >= $limit;

        return array(
            'success'  => true,
            'data'    => $products,
            'total'   => $total,
            'has_more' => $has_more,
        );
    }

    /**
     * Fetch orders from platform.
     *
     * @param array $credentials Connection credentials.
     * @param array $options     Fetch options.
     * @return array
     */
    public function fetch_orders( $credentials, $options = array() ) {
        $base_url     = $credentials['base_url'] ?? '';
        $access_token = $credentials['access_token'] ?? '';
        $limit        = isset( $options['limit'] ) ? absint( $options['limit'] ) : 20;
        $page         = isset( $options['page'] ) ? absint( $options['page'] ) : 1;

        if ( empty( $base_url ) || empty( $access_token ) ) {
            return array(
                'success' => false,
                'error'   => 'Missing required credentials.',
            );
        }

        $search_criteria = array(
            'searchCriteria' => array(
                'pageSize' => $limit,
                'currentPage' => $page,
            ),
        );

        $url = $this->build_api_url( $base_url, 'orders?' . http_build_query( $search_criteria ) );
        $result = $this->api_request( $url, $access_token );

        if ( ! $result['success'] ) {
            return $result;
        }

        $orders = $result['data']['items'] ?? array();
        $total = $result['data']['total_count'] ?? count( $orders );
        $has_more = count( $orders ) >= $limit;

        return array(
            'success'  => true,
            'data'    => $orders,
            'total'   => $total,
            'has_more' => $has_more,
        );
    }

    /**
     * Fetch customers from platform.
     *
     * @param array $credentials Connection credentials.
     * @param array $options     Fetch options.
     * @return array
     */
    public function fetch_customers( $credentials, $options = array() ) {
        $base_url     = $credentials['base_url'] ?? '';
        $access_token = $credentials['access_token'] ?? '';
        $limit        = isset( $options['limit'] ) ? absint( $options['limit'] ) : 20;
        $page         = isset( $options['page'] ) ? absint( $options['page'] ) : 1;

        if ( empty( $base_url ) || empty( $access_token ) ) {
            return array(
                'success' => false,
                'error'   => 'Missing required credentials.',
            );
        }

        $search_criteria = array(
            'searchCriteria' => array(
                'pageSize' => $limit,
                'currentPage' => $page,
            ),
        );

        $url = $this->build_api_url( $base_url, 'customers/search?' . http_build_query( $search_criteria ) );
        $result = $this->api_request( $url, $access_token );

        if ( ! $result['success'] ) {
            return $result;
        }

        $customers = $result['data']['items'] ?? array();
        $total = $result['data']['total_count'] ?? count( $customers );
        $has_more = count( $customers ) >= $limit;

        return array(
            'success'  => true,
            'data'    => $customers,
            'total'   => $total,
            'has_more' => $has_more,
        );
    }

    /**
     * Convert Magento product to WooCommerce format.
     *
     * @param array  $magento_product Magento product data.
     * @param string $type           Data type.
     * @return array
     */
    public function convert_to_woocommerce( $magento_product, $type = 'product' ) {
        if ( $type !== 'product' ) {
            return array();
        }

        $product = array(
            'post' => array(
                'post_title'   => $magento_product['name'] ?? '',
                'post_content' => $magento_product['description'] ?? '',
                'post_excerpt' => $magento_product['short_description'] ?? '',
                'post_status'  => ( $magento_product['status'] ?? 1 ) === 1 ? 'publish' : 'draft',
            ),
            'product' => array(
                'sku'            => $magento_product['sku'] ?? '',
                'regular_price'  => $this->get_price( $magento_product ),
                'stock'          => $magento_product['extension_attributes']['stock_item']['qty'] ?? 0,
                'stock_status'   => $this->get_stock_status( $magento_product ),
                'weight'         => $magento_product['weight'] ?? '',
            ),
            'images' => array(
                'images' => $this->extract_images( $magento_product ),
            ),
            'tax' => array(
                'product_cat' => $this->extract_categories( $magento_product ),
            ),
        );

        return $product;
    }

    /**
     * Get product price.
     *
     * @param array $magento_product Magento product.
     * @return string
     */
    private function get_price( $magento_product ) {
        return $magento_product['price'] ?? '';
    }

    /**
     * Get stock status.
     *
     * @param array $magento_product Magento product.
     * @return string
     */
    private function get_stock_status( $magento_product ) {
        $stock_item = $magento_product['extension_attributes']['stock_item'] ?? array();
        $is_in_stock = $stock_item['is_in_stock'] ?? false;
        return $is_in_stock ? 'instock' : 'outofstock';
    }

    /**
     * Extract images from Magento product.
     *
     * @param array $magento_product Magento product.
     * @return array
     */
    private function extract_images( $magento_product ) {
        $images = array();
        $media_gallery = $magento_product['media_gallery_entries'] ?? array();
        foreach ( $media_gallery as $entry ) {
            if ( ! empty( $entry['file'] ) ) {
                $base_url = rtrim( $magento_product['base_url'] ?? '', '/' );
                $images[] = $base_url . '/media/catalog/product' . $entry['file'];
            }
        }
        return $images;
    }

    /**
     * Extract categories from Magento product.
     *
     * @param array $magento_product Magento product.
     * @return array
     */
    private function extract_categories( $magento_product ) {
        $categories = array();
        $category_ids = $magento_product['category_ids'] ?? array();
        // In a full implementation, you'd fetch category names by IDs
        return $categories;
    }

    /**
     * Register webhook for real-time sync.
     *
     * @param array  $credentials Connection credentials.
     * @param string $event      Event type.
     * @param string $webhook_url Webhook URL.
     * @return array
     */
    public function register_webhook( $credentials, $event, $webhook_url ) {
        // Magento webhook registration would go here
        // This is a placeholder - Magento may require different webhook setup
        return array(
            'success'    => false,
            'error'      => 'Webhook registration not yet implemented for Magento.',
        );
    }

    /**
     * Unregister webhook.
     *
     * @param array  $credentials Connection credentials.
     * @param string $webhook_id  Webhook ID.
     * @return bool
     */
    public function unregister_webhook( $credentials, $webhook_id ) {
        return false;
    }
}


