<?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;

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;
                }
            }
        }
        // 减子商品库存
        if ($combinationGoodsIds) {
            $combinationGoods = CombinationGood::query()
                ->with('goodsSku:id,stock')
                ->whereIn('goods_sku_id', $combinationGoodsIds)
                ->get();
            foreach ($combinationGoods as $item) {
                $goodsSku = GoodsSku::query()->find($item['item_id']);
                $stock = $goodsSku->stock - $item['item_num'];
                [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock);
                $goodsSku->status = $status;
                $goodsSku->stock = $stock;
                $goodsSku->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')
                    ->where('goods_sku_id', $goodsSkuId)
                    ->get();
                $stock = [];
                foreach ($combinationGoods as $goods) {
                    $stock[] = (int)($goods['goodsSkuItem']['stock'] / $goods['item_num']);
                }
                $stock = min($stock);
                $goodsSku = GoodsSku::query()->find($goodsSkuId);
                [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock);
                $goodsSku->status = $status;
                $goodsSku->stock = $stock;
                $goodsSku->save();
                $updateIds[] = $goodsSkuId;
            }
        }
        if ($updateIds) {
            $updateIds = array_unique($updateIds);
            // 批量更新
            event(new BatchStockUpdateEvent($updateIds, false));
        }
    }

    private function checkStatusAndStock($goodsSku, $stock)
    {
        if (0 >= $stock) {
            $status = GoodsSku::$STATUS_DOWN;
        } else {
            $status = GoodsSku::$STATUS_ON_SALE;
        }
        $arrivedTodayNum = DailyStockRecord::query()
            ->where('day', DateTimeUtils::getToday())
            ->where('sku_id', $goodsSku->id)
            ->value('arrived_today_num');
        if (20 < $arrivedTodayNum + $goodsSku->yesterday_num && 4 > $stock) {
            $status = GoodsSku::$STATUS_DOWN;
            $stock = 0;
        }

        return [$status, $stock];
    }
}
