<?php

namespace App\Domain\Inventory\Listeners;

use App\Domain\Inventory\Enums\MovementType;
use App\Domain\Inventory\Events\StockCountCompleted;
use App\Domain\Inventory\Models\Warehouse;
use App\Domain\Inventory\Services\InventoryService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;

class ProcessCountAdjustments implements ShouldQueue
{
    public function __construct(
        private InventoryService $inventoryService,
    ) {}

    public function handle(StockCountCompleted $event): void
    {
        try {
            $stockCount = $event->stockCount;
            $warehouse = $stockCount->warehouse;

            if (!$warehouse) {
                Log::warning('ProcessCountAdjustments: StockCount has no warehouse', [
                    'stock_count_id' => $stockCount->id,
                ]);
                return;
            }

            // Load items with products
            $items = $stockCount->items()->with('product')->get();

            foreach ($items as $item) {
                $product = $item->product;

                if (!$product) {
                    continue;
                }

                // Skip items where count matches system
                $discrepancy = $item->counted_quantity - $item->system_quantity;
                if ($discrepancy === 0) {
                    continue;
                }

                // Determine adjustment type based on discrepancy direction
                if ($discrepancy > 0) {
                    // Counted MORE than system — adjustment up
                    $this->inventoryService->createMovement(
                        product: $product,
                        warehouse: $warehouse,
                        type: MovementType::CountAdjustmentUp,
                        quantity: $discrepancy,
                        actor: $event->actor,
                        reference: $stockCount,
                        reason: "تسوية جرد #{$stockCount->count_number} — زيادة {$discrepancy}",
                    );
                } else {
                    // Counted LESS than system — adjustment down
                    $this->inventoryService->createMovement(
                        product: $product,
                        warehouse: $warehouse,
                        type: MovementType::CountAdjustmentDown,
                        quantity: abs($discrepancy),
                        actor: $event->actor,
                        reference: $stockCount,
                        reason: "تسوية جرد #{$stockCount->count_number} — نقص " . abs($discrepancy),
                    );
                }
            }
        } catch (\Throwable $e) {
            Log::error('ProcessCountAdjustments failed: ' . $e->getMessage(), [
                'stock_count_id' => $event->stockCount->id,
            ]);
        }
    }

    public function failed(StockCountCompleted $event, \Throwable $exception): void
    {
        Log::critical('ProcessCountAdjustments PERMANENTLY FAILED', [
            'stock_count_id' => $event->stockCount->id,
            'error' => $exception->getMessage(),
        ]);
    }
}
