<?php

namespace App\Listeners;

use App\Models\CombinationGood;
use App\Models\DailyStockRecord;
use App\Models\GoodsSku;
use App\Utils\DateTimeUtils;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use App\Events\BatchStockUpdateEvent;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class CombinationGoodsStockUpdateListener implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  $event
     * @return void
     */
    public function handle($event)
    {
        if (!$event->combinationGoodsUpdate) {
            return false;
        }
        $updateIds = $combinationGoodsIds = $combinationGoodsItemIds = [];
        if (!empty($event->goodsSku)) {
            if ($event->goodsSku->is_combination) {
                $combinationGoodsIds[] = $event->goodsSku->id;
            } else {
                $combinationGoodsItemIds[] = $event->goodsSku->id;
            }
        }

        if (!empty($event->goodsSkus)) {
            foreach ($event->goodsSkus as $sku) {
                if ($sku->is_combination) {
                    $combinationGoodsIds[] = $sku->id;
                } else {
                    $combinationGoodsItemIds[] = $sku->id;
                }
            }
        }
        $updateIds = [];
        //拉取三分订单时可能出现组合订单的情况 需要同步扣减库存
        if ($combinationGoodsIds) {
            $combinationGoods = CombinationGood::query()
                ->with('goodsSku:id,stock')
                ->whereIn('goods_sku_id', $combinationGoodsIds)
                ->get();
            $num = !empty($event->num) ? $event->num : -1;
            foreach ($combinationGoods as $item) {
                DB::transaction(function () use ($item, &$updateIds, $num) {
                    $goodsSku = GoodsSku::query()->find($item['item_id']);
                    $stock = $goodsSku->stock + $item['item_num'] * $num;
                    //新增逻辑 在线库存同步扣减
                    $saleStock = max($goodsSku->sale_stock + $item['item_num'] * $num, 0);
                    [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock, $saleStock);
                    $goodsSku->status = $status;
                    $goodsSku->stock = $stock;
                    $goodsSku->sale_stock = $saleStock;
                    $goodsSku->save();
                    Log::info("sku 业务订单库存更:{$goodsSku->id},num:{$num}", [$stock, $saleStock]);
                    $mainGoodsSku = GoodsSku::query()->find($item['goods_sku_id']);
                    $mainGoodsSku->stock = min($mainGoodsSku->stock, (int)($stock / $item['item_num']));
                    $mainGoodsSku->sale_stock = min($mainGoodsSku->sale_stock, (int)($saleStock / $item['item_num']));
                    $mainGoodsSku->save();
                    $updateIds[] = $goodsSku->id;
                });
            }
        }
        // 计算主商品库存
        if ($combinationGoodsItemIds) {
            $goodsSkuIds = CombinationGood::query()
                ->whereIn('item_id', $combinationGoodsItemIds)
                ->pluck('goods_sku_id');
            foreach ($goodsSkuIds as $goodsSkuId) {
                $combinationGoods = CombinationGood::query()
                    ->with('goodsSkuItem:id,stock,sale_stock')
                    ->where('goods_sku_id', $goodsSkuId)
                    ->get();

                $stock = [];
                $saleStock = [];
                foreach ($combinationGoods as $goods) {
                    $stock[] = (int)($goods['goodsSkuItem']['stock'] / $goods['item_num']);
                    $saleStock[] = (int)($goods['goodsSkuItem']['sale_stock'] / $goods['item_num']);
                }
                //库存和在线可售库存都是通过子商品维护的
                $stock = min($stock);
                $saleStock = min($saleStock);
                $goodsSku = GoodsSku::query()->find($goodsSkuId);
                //新增在线可售逻辑判断 前置已经完成逻辑扣减或者增加
                [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock, $saleStock);
                $goodsSku->status = $status;
                $goodsSku->stock = $stock;
                $goodsSku->sale_stock = $saleStock;
                $goodsSku->save();
                $updateIds[] = $goodsSkuId;
            }
        }

        if ($updateIds) {
            $updateIds = array_unique($updateIds);
            // 批量更新
            event(new BatchStockUpdateEvent($updateIds, false));
        }
    }

    private function checkStatusAndStock($goodsSku, $stock, $saleStock)
    {
        //下线库存判断以在线可售库存为准
        if (0 >= $saleStock) {
            $status = GoodsSku::$STATUS_DOWN;
        } else {
            $status = GoodsSku::$STATUS_ON_SALE;
        }

        return [$status, $stock];
    }
}
