<?php

namespace AC_SYNC\Includes\Classes\Async\Handlers;

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

use AC_SYNC\Includes\Classes\Async\Action_Wear_Job_Handler_Interface;
use AC_SYNC\Includes\Classes\Async\Action_Wear_Job_Result as JobResult;
use AC_SYNC\Includes\Classes\Async\Action_Wear_Job_Queue as JobQueue;
use AC_SYNC\Includes\Classes\Api\Action_Wear_Api as Api;
use AC_SYNC\Includes\Classes\Api\Action_Wear_Api_Exception as ApiException;
use AC_SYNC\Includes\Classes\Logger\Action_Wear_Log as Log;

class Action_Wear_Bulk_Price_Fetch_Handler implements Action_Wear_Job_Handler_Interface
{
    const BATCH_SIZE = 500;

    public function handle(object $job, array $payload): JobResult
    {
        global $wpdb;

        // 1. Load WC product variation SKUs
        $skus = $wpdb->get_col("
            SELECT pm.meta_value
            FROM {$wpdb->postmeta} pm
            INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
            WHERE pm.meta_key = '_sku'
            AND pm.meta_value != ''
            AND p.post_type = 'product_variation'
            AND p.post_status IN ('publish', 'private')
        ");

        if (empty($skus)) {
            Log::write("BulkPriceFetch: No WC products, skipping", Log::INFO, Log::CONTEXT_CRONJOB);
            return JobResult::success();
        }

        $skuMap = array_flip($skus);
        unset($skus);
        Log::write("BulkPriceFetch: Found " . count($skuMap) . " WC variations", Log::INFO, Log::CONTEXT_CRONJOB);

        // 2. Fetch API data
        $response = Api::external("GET", "/pricesall?compress=0&output=json", ["timeout" => 300]);

        if ($response['code'] !== 200) {
            throw new ApiException($response['code'], "API error code " . $response['code']);
        }

        // 3. Parse + filter
        $decoded = json_decode($response['body'], true);
        $priceItems = $decoded[0] ?? $decoded;

        if (!is_array($priceItems)) {
            Log::write("BulkPriceFetch: Invalid API response", Log::ERROR, Log::CONTEXT_CRONJOB);
            return JobResult::fail('Invalid API response');
        }

        $matched = [];
        foreach ($priceItems as $item) {
            $itemSkus = $item['sku'] ?? [];
            if (!is_array($itemSkus)) $itemSkus = [$itemSkus];
            foreach ($itemSkus as $sku) {
                if ($sku && isset($skuMap[$sku])) {
                    $matched[] = $item;
                    break;
                }
            }
        }
        unset($skuMap);

        Log::write("BulkPriceFetch: Matched " . count($matched) . " items", Log::INFO, Log::CONTEXT_CRONJOB);

        if (empty($matched)) {
            return JobResult::success();
        }

        // 4. Chunk and create batch jobs
        $batches = array_chunk($matched, self::BATCH_SIZE);
        unset($matched);

        foreach ($batches as $batch) {
            JobQueue::push('bulk_price_batch', ['items' => $batch], 40, null, 'price_sync');
        }

        Log::write("BulkPriceFetch: Queued " . count($batches) . " batches of " . self::BATCH_SIZE, Log::INFO, Log::CONTEXT_CRONJOB);
        update_option('_ACTIONWEAR_LAST_BULK_PRICE_SYNC', time());

        return JobResult::success();
    }
}
