<?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\Logger\Action_Wear_Log as Log;
use AC_SYNC\Includes\Classes\Price\Action_Wear_Price_Recharger as PriceRecharger;

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

        $batch = $payload['items'] ?? [];
        if (empty($batch)) {
            return JobResult::success();
        }

        // 1. Collect all SKUs from the batch
        $skuPriceMap = [];
        foreach ($batch as $priceItem) {
            $skus = $priceItem['sku'] ?? [];
            if (!is_array($skus)) $skus = [$skus];
            $basePrice = isset($priceItem['prezzo unita'])
                ? floatval(str_replace(',', '.', $priceItem['prezzo unita']))
                : null;
            if ($basePrice !== null) {
                foreach ($skus as $sku) {
                    if ($sku) {
                        $skuPriceMap[$sku] = $basePrice;
                    }
                }
            }
        }

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

        $allSkus = array_keys($skuPriceMap);
        $placeholders = implode(',', array_fill(0, count($allSkus), '%s'));

        // 2. Batch SKU -> post_id lookup
        $skuToPostId = [];
        $results = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT pm.meta_value AS sku, pm.post_id
                FROM {$wpdb->postmeta} pm
                INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
                WHERE pm.meta_key = '_sku'
                AND p.post_type = 'product_variation'
                AND pm.meta_value IN ($placeholders)",
                ...$allSkus
            )
        );
        foreach ($results as $row) {
            $skuToPostId[$row->sku] = (int) $row->post_id;
        }

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

        $postIds = array_values($skuToPostId);
        $idPlaceholders = implode(',', array_fill(0, count($postIds), '%d'));

        // 3. Batch meta pre-fetch
        $metaMap = [];
        $metaResults = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT post_id, meta_key, meta_value
                FROM {$wpdb->postmeta}
                WHERE post_id IN ($idPlaceholders)
                AND meta_key IN ('brand_id', 'cat_ids')",
                ...$postIds
            )
        );
        foreach ($metaResults as $meta) {
            $metaMap[$meta->post_id][$meta->meta_key] = $meta->meta_value;
        }

        // 4. Process each item
        $updatedIds = [];
        foreach ($skuToPostId as $sku => $postId) {
            try {
                $basePrice = $skuPriceMap[$sku];
                $brandId = (int) ($metaMap[$postId]['brand_id'] ?? 0);
                $catIds = json_decode($metaMap[$postId]['cat_ids'] ?? '[]', true) ?? [];

                $priceRecharger = new PriceRecharger($basePrice);
                $finalPrice = $priceRecharger->getPrice($brandId, $catIds);

                if ((float) $finalPrice > 0) {
                    $formattedPrice = wc_format_decimal($finalPrice);
                    update_post_meta($postId, '_regular_price', $formattedPrice);
                    update_post_meta($postId, '_price', $formattedPrice);
                    update_post_meta($postId, 'original_base_price', $basePrice);
                    delete_post_meta($postId, '_needs_price_sync');

                    $wpdb->update(
                        $wpdb->prefix . 'wc_product_meta_lookup',
                        ['min_price' => $formattedPrice, 'max_price' => $formattedPrice],
                        ['product_id' => $postId],
                        ['%s', '%s'],
                        ['%d']
                    );
                    $updatedIds[] = $postId;
                }
            } catch (\Throwable $e) {
                Log::write("BulkPriceBatch: Error processing SKU {$sku}: " . $e->getMessage(), Log::ERROR, Log::CONTEXT_CRONJOB);
            }
        }

        // 5. Sync parent product lookup tables + invalidate caches
        if (!empty($updatedIds)) {
            $parentIds = [];
            foreach ($updatedIds as $variationId) {
                $parentId = wp_get_post_parent_id($variationId);
                if ($parentId) {
                    $parentIds[$parentId] = true;
                }
                wc_delete_product_transients($variationId);
            }

            foreach (array_keys($parentIds) as $parentId) {
                if (function_exists('wc_update_product_lookup_tables_column')) {
                    wc_update_product_lookup_tables_column($parentId, 'min_max_price');
                }
                wc_delete_product_transients($parentId);
            }
        }

        // On final batch, reset cache and update timestamp
        if (!JobQueue::hasPending('bulk_price_batch')) {
            PriceRecharger::resetCache();
            update_option('_ACTIONWEAR_LAST_BULK_PRICE_SYNC_COMPLETED', time());
            Log::write("BulkPriceBatch: All batches completed", Log::INFO, Log::CONTEXT_CRONJOB);
        }

        return JobResult::success();
    }
}
