<?php

namespace auctionforge\inc\sync;

use auctionforge\inc\abs\Importer;
use auctionforge\inc\controllers\MultiLanguageSupport;
use auctionforge\inc\controllers\PolylangSupport;
use auctionforge\inc\controllers\HummingbirdSupport;
use auctionforge\inc\Debug;
use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\model\Auction;
use auctionforge\inc\import\InsertLotsBS;
use auctionforge\inc\model\Lot;
use auctionforge\inc\InstanceDB;

class ItemUpdateWorker
{
    /**
     * Process an item_update job.
     * Reuses the same logic as AuctionsAPI::itemsUpdated() but runs from the queue.
     *
     * @param object $job  The queue job row from af_sync_queue
     * @return array  ['updated' => bool, 'errors' => array]
     */
    public static function process($job)
    {
        $auctionId = $job->auction_id;
        $startTime = microtime(true);
        $result = ['updated' => false, 'errors' => []];

        SyncLogger::log('worker', "▶ Starting item_update for auction {$auctionId}", 'info', $auctionId, $job->id);

        try {
            // Stage 1: Parse payload
            SyncLogger::log('worker', "  [1/4] Parsing webhook payload...", 'info', $auctionId, $job->id);
            $payload = json_decode($job->payload);
            if (empty($payload) || empty($payload->itemsByLanguage)) {
                SyncLogger::log('worker', "  [1/4] No itemsByLanguage in payload — skipping", 'warning', $auctionId, $job->id);
                return $result;
            }

            // Stage 2: Extract item data from languages
            $langCode = SettingsHelper::getOption("lang", 'en');
            SyncLogger::log('worker', "  [2/4] Extracting item data (lang: {$langCode})...", 'info', $auctionId, $job->id);
            $response = $payload->itemsByLanguage;
            $item = new \stdClass();
            $itemSecond = new \stdClass();

            if (PolylangSupport::isPolylangActive() && PolylangSupport::isFullSupport()) {
                $secondLangCode = MultiLanguageSupport::getSecondLangCode();
                if (!empty($response->{$secondLangCode})) {
                    $secondObj = (array) $response->{$secondLangCode};
                    $itemSecond = $secondObj[0]->item;
                    SyncLogger::log('worker', "  [2/4] Second language ({$secondLangCode}) data loaded", 'info', $auctionId, $job->id);
                }
            }

            if (!empty($response->{$langCode})) {
                $obj = (array) $response->{$langCode};
                $item = $obj[0]->item;

                if (!empty($obj[0]->leadingBid)) {
                    if (isset($obj[0]->leadingBid->price)) {
                        $item->leadingBid = $obj[0]->leadingBid->price;
                    }
                }

                if (!empty($obj[0]->soldBid)) {
                    if (isset($obj[0]->soldBid->price)) {
                        $item->soldBid = $obj[0]->soldBid->price;
                    }
                }

                if (!empty($obj[0]->paddedIndex)) {
                    $item->paddedIndex = $obj[0]->paddedIndex;
                }
            }

            if (is_null($item) || empty($item->id)) {
                SyncLogger::log('worker', "  [2/4] Item data is null/empty — skipping", 'warning', $auctionId, $job->id);
                return $result;
            }

            $itemName = $item->name ?? 'unnamed';
            $bidInfo = '';
            if (!empty($item->leadingBid)) $bidInfo .= " leading={$item->leadingBid}";
            if (!empty($item->soldBid)) $bidInfo .= " sold={$item->soldBid}";
            SyncLogger::log('worker', "  [2/4] Item #{$item->id}: \"{$itemName}\"{$bidInfo}", 'info', $auctionId, $job->id);

            // Stage 3: Build attributes + save
            SyncLogger::log('worker', "  [3/4] Building lot attributes and saving to WordPress...", 'info', $auctionId, $job->id);
            $item->lotId = $item->id;
            $item->auctionSlug = $item->auctionId ?? $auctionId;
            $item->syncTimes = 0;
            $item->priority = 1;
            $item->createDatetime = date(Importer::DATE_FORMAT);

            if (isset($itemSecond->name)) {
                $item->nameL2 = $itemSecond->name;
            } else {
                $item->nameL2 = $item->name ?? '';
            }
            if (isset($itemSecond->description)) {
                $item->descriptionL2 = $itemSecond->description;
            } else {
                $item->descriptionL2 = $item->description ?? '';
            }
            if (isset($itemSecond->author)) {
                $item->authorL2 = $itemSecond->author;
            } else {
                $item->authorL2 = $item->author ?? '';
            }

            $lot = new Lot();
            $lot->loadAttributes($item);
            $lot->setPriority(1);
            $lots = [$lot];
            $saveResult = Lot::bulkSave($lots);

            if ($saveResult) {
                SyncLogger::log('worker', "  [3/5] Staged to import_history", 'info', $auctionId, $job->id);

                // Stage 4: Process staging → WP posts + bp_meta_data
                $db = InstanceDB::getInstanceDB();
                $db->query('COMMIT;');
                $db->query('SET autocommit = 1;');

                SyncLogger::log('worker', "  [4/5] Processing staged data → WP post + meta...", 'info', $auctionId, $job->id);
                $insertLots = new InsertLotsBS();
                $insertLots->init(['limit' => 10]);
                $insertInfo = $insertLots->getLoggedInfo();
                $batchCount = isset($insertInfo['updated lots']) ? (int) $insertInfo['updated lots'] : 0;

                $result['updated'] = true;
                $postId = $lot->getId();
                SyncLogger::log('worker', "  [4/5] Processed {$batchCount} lot(s) into WP", 'info', $auctionId, $job->id);

                // Stage 5: Clear cache
                SyncLogger::log('worker', "  [5/5] Clearing cache for post #{$postId}...", 'info', $auctionId, $job->id);
                HummingbirdSupport::clearCacheByUrl(get_permalink($postId));
                Auction::doClearCacheForAuctionPages();

                $duration = round(microtime(true) - $startTime, 2);
                SyncLogger::log('worker', "✓ Item updated: lot #{$item->lotId} \"{$itemName}\" → post #{$postId} ({$duration}s)", 'success', $auctionId, $job->id);
            } else {
                $duration = round(microtime(true) - $startTime, 2);
                SyncLogger::log('worker', "⚠ Lot::bulkSave returned false for lot #{$item->lotId} ({$duration}s)", 'warning', $auctionId, $job->id);
            }

        } catch (\Exception $e) {
            $result['errors'][] = $e->getMessage();
            $duration = round(microtime(true) - $startTime, 2);
            SyncLogger::log('worker', "✗ Exception in item_update after {$duration}s: " . $e->getMessage(), 'error', $auctionId, $job->id);
        } catch (\Throwable $t) {
            $result['errors'][] = $t->getMessage();
            $duration = round(microtime(true) - $startTime, 2);
            SyncLogger::log('worker', "✗ Fatal in item_update after {$duration}s: " . $t->getMessage(), 'error', $auctionId, $job->id);
        }

        return $result;
    }
}
