<?php
namespace ShopyPress\Controllers;
if ( ! defined( 'ABSPATH' ) ) exit;

use ShopyPress\Helpers\ShopifyCollections;
use ShopyPress\Helpers\ShopifyAuth;
use ShopyPress\Utils\OptionUtils;

class ShopifyCollectionsCtrl {

    /**
     * AJAX handler to fetch Shopify collections
     */
    public static function fetchCollections(): void {
        // Verify nonce
        if (!check_ajax_referer('shopypress_app_settings_nonce', 'nonce', false)) {
            wp_send_json_error([
                'message' => esc_html__('Invalid security token', 'synckube-products-sync-for-shopify'),
            ], 403);
            return;
        }

        // Check user capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => esc_html__('Insufficient permissions', 'synckube-products-sync-for-shopify'),
            ], 403);
            return;
        }

        // Sanitize and validate shop domain
        $shop = isset($_POST['shop']) ? sanitize_text_field(wp_unslash($_POST['shop'])) : '';

        if (empty($shop)) {
            wp_send_json_error([
                'message' => esc_html__('Shop domain is required', 'synckube-products-sync-for-shopify'),
            ], 400);
            return;
        }

        // Fetch collections
        $collections = ShopifyCollections::fetchCollections($shop);

        if ($collections === null) {
            wp_send_json_error([
                'message' => esc_html__('Failed to fetch collections. Please check your credentials and shop domain.', 'synckube-products-sync-for-shopify'),
            ], 500);
            return;
        }

        // Format collections for frontend
        $formatted_collections = ShopifyCollections::formatCollections($collections);

        wp_send_json_success([
            'collections' => $formatted_collections,
            'total' => count($formatted_collections),
        ]);
    }

    /**
     * AJAX handler to save collection selection
     */
    public static function saveCollectionSelection(): void {
        // Verify nonce
        if (!check_ajax_referer('shopypress_app_settings_nonce', 'nonce', false)) {
            wp_send_json_error([
                'message' => esc_html__('Invalid security token', 'synckube-products-sync-for-shopify'),
            ], 403);
            return;
        }

        // Check user capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => esc_html__('Insufficient permissions', 'synckube-products-sync-for-shopify'),
            ], 403);
            return;
        }

        // Sanitize and validate input
        $collection_id = isset($_POST['collection_id']) ? sanitize_text_field(wp_unslash($_POST['collection_id'])) : '';
        $collection_title = isset($_POST['collection_title']) ? sanitize_text_field(wp_unslash($_POST['collection_title'])) : '';
        $is_checked = isset($_POST['is_checked']) ? filter_var(wp_unslash($_POST['is_checked']), FILTER_VALIDATE_BOOLEAN) : false;

        if (empty($collection_id)) {
            wp_send_json_error([
                'message' => esc_html__('Collection ID is required', 'synckube-products-sync-for-shopify'),
            ], 400);
            return;
        }

        // Get current selections
        $options = OptionUtils::getInstance();
        $selected_collections = $options->getOption('selected_collections', []);

        // Update selection
        if ($is_checked) {
            $selected_collections[$collection_id] = [
                'title' => $collection_title, // Already sanitized above
                'selected' => true,
                'selected_at' => current_time('mysql'),
            ];
        } else {
            unset($selected_collections[$collection_id]);
        }

        // Save to options
        $options->setOption('selected_collections', $selected_collections);

        wp_send_json_success([
            'message' => esc_html__('Selection saved successfully', 'synckube-products-sync-for-shopify'),
            'selected_collections' => $selected_collections,
        ]);
    }

    /**
     * AJAX handler to save collection order
     */
    public static function saveCollectionOrder(): void {
        // Verify nonce
        if (!check_ajax_referer('shopypress_app_settings_nonce', 'nonce', false)) {
            wp_send_json_error([
                'message' => esc_html__('Invalid security token', 'synckube-products-sync-for-shopify'),
            ], 403);
            return;
        }

        // Check user capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => esc_html__('Insufficient permissions', 'synckube-products-sync-for-shopify'),
            ], 403);
            return;
        }

        // Sanitize and validate input
        $collection_order = isset($_POST['collection_order']) ? map_deep(wp_unslash($_POST['collection_order']), 'sanitize_text_field') : [];

        if (!is_array($collection_order)) {
            wp_send_json_error([
                'message' => esc_html__('Invalid collection order data', 'synckube-products-sync-for-shopify'),
            ], 400);
            return;
        }

        // Sanitize the collection order data
        $sanitized_order = [];
        foreach ($collection_order as $item) {
            if (isset($item['id']) && isset($item['order'])) {
                $sanitized_order[] = [
                    'id' => sanitize_text_field($item['id']),
                    'order' => absint($item['order']),
                ];
            }
        }

        // Save to options
        $options = OptionUtils::getInstance();
        $options->setOption('collection_order', $sanitized_order);

        wp_send_json_success([
            'message' => esc_html__('Collection order saved successfully', 'synckube-products-sync-for-shopify'),
            'collection_order' => $sanitized_order,
        ]);
    }

    /**
     * Regenerate Storefront API token (called when credentials change)
     *
     * @param string $shop Shopify store domain
     * @return void
     */
    public static function regenerateStorefrontToken(string $shop): void
    {
        // Clear cached admin access token (credentials may have changed)
        ShopifyAuth::clearAccessToken();

        // Clear existing storefront token
        $options = OptionUtils::getInstance();
        $options->setOption('shopify_api_token', '');

        // Generate new token
        $admin_access_token = ShopifyAuth::getAccessToken($shop);

        if (!$admin_access_token) {
            error_log('ShopyPress: Unable to regenerate Storefront token - Admin API authentication failed');
            return;
        }

        $storefront_token = self::createStorefrontAccessToken($shop, $admin_access_token);

        if ($storefront_token) {
            $options->setOption('shopify_api_token', $storefront_token);
            error_log('ShopyPress: Storefront API token regenerated after credentials change');
        } else {
            error_log('ShopyPress: Failed to regenerate Storefront token');
        }
    }

    /**
     * Create Storefront Access Token via Shopify Admin API
     *
     * @param string $shop_domain Shopify store domain
     * @param string $admin_access_token Admin API access token
     * @return string|null Generated Storefront API token or null on failure
     */
    private static function createStorefrontAccessToken(string $shop_domain, string $admin_access_token): ?string
    {
        $graphql_url = "https://{$shop_domain}/admin/api/2025-10/graphql.json";

        $mutation = 'mutation StorefrontAccessTokenCreate($input: StorefrontAccessTokenInput!) {' . "\n" .
            '  storefrontAccessTokenCreate(input: $input) {' . "\n" .
            '    userErrors {' . "\n" .
            '      field' . "\n" .
            '      message' . "\n" .
            '    }' . "\n" .
            '    shop {' . "\n" .
            '      id' . "\n" .
            '    }' . "\n" .
            '    storefrontAccessToken {' . "\n" .
            '      accessScopes {' . "\n" .
            '        handle' . "\n" .
            '      }' . "\n" .
            '      accessToken' . "\n" .
            '      title' . "\n" .
            '    }' . "\n" .
            '  }' . "\n" .
            '}';

        $variables = [
            'input' => [
                'title' => 'SyncKube - WordPress Integration (Auto-generated)'
            ]
        ];

        $payload = [
            'query' => $mutation,
            'variables' => $variables
        ];

        // Make GraphQL request
        $response = wp_remote_post($graphql_url, [
            'headers' => [
                'Content-Type' => 'application/json',
                'X-Shopify-Access-Token' => $admin_access_token
            ],
            'body' => wp_json_encode($payload),
            'timeout' => 30,
        ]);

        // Check for HTTP errors
        if (is_wp_error($response)) {
            error_log('ShopyPress: Failed to create Storefront token - ' . $response->get_error_message());
            return null;
        }

        $response_code = wp_remote_retrieve_response_code($response);
        $response_body = wp_remote_retrieve_body($response);

        if ($response_code !== 200) {
            error_log("ShopyPress: Failed to create Storefront token - HTTP {$response_code}");
            return null;
        }

        // Parse JSON response
        $data = json_decode($response_body, true);

        // Check for GraphQL errors
        if (isset($data['errors']) && !empty($data['errors'])) {
            error_log('ShopyPress: GraphQL errors - ' . wp_json_encode($data['errors']));
            return null;
        }

        // Check for user errors
        if (isset($data['data']['storefrontAccessTokenCreate']['userErrors'])
            && !empty($data['data']['storefrontAccessTokenCreate']['userErrors'])) {
            error_log('ShopyPress: User errors - ' . wp_json_encode($data['data']['storefrontAccessTokenCreate']['userErrors']));
            return null;
        }

        // Extract access token
        $access_token = $data['data']['storefrontAccessTokenCreate']['storefrontAccessToken']['accessToken'] ?? null;

        if (empty($access_token)) {
            error_log('ShopyPress: No access token in response');
            return null;
        }

        return $access_token;
    }
}
