<?php

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

class AIEO_Exchanger_Puller {

    
    public static function run_full($job_id) {
        $job = AIEO_Exchanger_Imports::get((int) $job_id);
        if (!$job) { return array('ok' => false, 'error' => 'job_not_found', 'processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 1); }

        @set_time_limit(600); 

        $manifest = self::fetch_manifest($job);
        if (is_wp_error($manifest)) {
            AIEO_Exchanger_Imports::record_run_result($job['id'], 'manifest_error');
            AIEO_Exchanger_Run_Log::record('target', (int) $job['id'], 0, 0, 0, 0, 0, array(array('phase' => 'manifest', 'error' => $manifest->get_error_message())));
            return array('ok' => false, 'error' => $manifest->get_error_message(), 'processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 1);
        }

        $totals = array('processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 0);

        foreach ((array) ($manifest['shards'] ?? array()) as $shard) {
            $r = self::run_one_shard($job, (string) $shard['rest']);
            $totals['processed'] += (int) $r['processed'];
            $totals['created']   += (int) $r['created'];
            $totals['updated']   += (int) $r['updated'];
            $totals['skipped']   += (int) $r['skipped'];
            $totals['errors']    += (int) $r['errors'];
        }

        AIEO_Exchanger_Imports::record_run_result($job['id'], 'OK');
        return array_merge(array('ok' => true), $totals);
    }

    
    public static function run_one_shard(array $job, $shard_url) {
        $resp = wp_remote_get((string) $shard_url, array(
            'timeout' => 30,
            'headers' => array(
                'Authorization' => 'Bearer ' . (string) $job['feed_token'],
                'Accept'        => 'application/json',
            ),
        ));
        if (is_wp_error($resp)) {
            $err = $resp->get_error_message();
            AIEO_Exchanger_Run_Log::record('target', (int) $job['id'], 0, 0, 0, 0, 0, array(array('phase' => 'shard_fetch', 'url' => $shard_url, 'error' => $err)));
            return array('processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 1);
        }
        $code = (int) wp_remote_retrieve_response_code($resp);
        if ($code !== 200) {
            AIEO_Exchanger_Run_Log::record('target', (int) $job['id'], 0, 0, 0, 0, 0, array(array('phase' => 'shard_fetch', 'url' => $shard_url, 'http' => $code)));
            return array('processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 1);
        }
        $body = (string) wp_remote_retrieve_body($resp);
        $shard = json_decode($body, true);
        if (!is_array($shard) || empty($shard['products'])) {
            return array('processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 0);
        }

        $shard_n = (int) ($shard['shard'] ?? 0);
        $totals  = array('processed' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => 0);
        $errors  = array();

        foreach ((array) $shard['products'] as $product) {
            if (!is_array($product)) { continue; }
            $totals['processed']++;
            $r = AIEO_Exchanger_Product_Importer::apply($product, (string) $job['match_key'], (string) $job['mode']);
            switch ($r['outcome']) {
                case 'created': $totals['created']++; break;
                case 'updated': $totals['updated']++; break;
                case 'skipped': $totals['skipped']++; break;
                case 'error':
                    $totals['errors']++;
                    if (count($errors) < 50) {
                        $errors[] = array(
                            'sku'     => $product['match']['sku'] ?? '',
                            'barcode' => $product['match']['barcode'] ?? '',
                            'error'   => (string) ($r['error'] ?? 'unknown'),
                        );
                    }
                    break;
            }
        }

        AIEO_Exchanger_Run_Log::record('target', (int) $job['id'], $shard_n, $totals['processed'], $totals['created'], $totals['updated'], $totals['skipped'], $errors);
        return $totals;
    }

    
    public static function fetch_manifest(array $job) {
        $resp = wp_remote_get((string) $job['source_url'], array(
            'timeout' => 30,
            'headers' => array(
                'Authorization' => 'Bearer ' . (string) $job['feed_token'],
                'Accept'        => 'application/json',
            ),
        ));
        if (is_wp_error($resp)) { return $resp; }
        $code = (int) wp_remote_retrieve_response_code($resp);
        if ($code !== 200) {
            
            return new WP_Error('manifest_http', sprintf(__('HTTP %d', 'ai-eshop-optimizer'), $code));
        }
        $body = (string) wp_remote_retrieve_body($resp);
        $json = json_decode($body, true);
        if (!is_array($json) || empty($json['shards'])) {
            return new WP_Error('manifest_shape', __('Missing shards array.', 'ai-eshop-optimizer'));
        }
        return $json;
    }
}
