<?php

namespace App\Console\Commands;

use App\Models\BusinessOrderItem;
use App\Models\DailyReport;
use App\Models\DailyStockRecord;
use App\Models\GoodsSku;
use App\Models\LossRecords;
use App\Models\PurchaseRecords;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class DailyStockRecordReport extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'daily:report:stock_record {date?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '每日商品库存记录';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $date = $this->argument('date');
        if (is_null($date)) {
            $date = Carbon::yesterday()->format('Y-m-d');
        }
        $startDateTime = Carbon::parse($date)->startOfDay()->toDateTimeString();
        $endDateTime = Carbon::parse($date)->endOfDay()->toDateTimeString();
        //统计订单数量
        $orderItems = BusinessOrderItem::query()
            ->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
            ->select("business_order_items.external_sku_id"
                , DB::raw("sum(goods_number-already_cancel_number) as goods_total")
                , DB::raw("ROUND(sum(goods_amount) / 100,2) as order_total_amount"))
            ->where('b.confirm_at', '>=', Carbon::parse($startDateTime)->getPreciseTimestamp(3))
            ->where('b.confirm_at', '<=', Carbon::parse($endDateTime)->getPreciseTimestamp(3))
            ->where("business_order_items.cancel_status", "=", 0)
            ->groupBy('external_sku_id')->get()->pluck(null, "external_sku_id")->toArray();

        //统计采购单数量
        $purchaseRecords = PurchaseRecords::query()
            ->select(DB::raw("sum(num) as arrived_today_num"), "external_sku_id")
            ->whereBetween("check_time", [$startDateTime, $endDateTime])
            ->where("status",1)
            ->groupBy("external_sku_id")->get()->pluck(null, "external_sku_id")->toArray();
        //统计报损数量
        $lossRecords = LossRecords::query()
            ->select(DB::raw("sum(num) as loss_num"), "external_sku_id")
            ->whereBetween("created_at", [$startDateTime, $endDateTime])
            ->groupBy("external_sku_id")->get()->pluck(null, "external_sku_id")->toArray();
        Log::info("{$date}每日库存记录", ["orderItems" => $orderItems
            , "purchaseRecords" => $purchaseRecords, "lossRecords" => $lossRecords]);
        $needUpdateExternalSkuIds = array_merge(array_keys($orderItems), array_keys($purchaseRecords), array_keys($lossRecords));
        //开始更新数据
        if (!empty($needUpdateExternalSkuIds)) {
            $needUpdateSkuIdsMap = GoodsSku::query()->whereIn("external_sku_id", $needUpdateExternalSkuIds)->pluck("external_sku_id", 'id')->toArray();

            collect($needUpdateSkuIdsMap)->each(function ($externalSkuId,$skuId) use ($date, $orderItems, $purchaseRecords, $lossRecords) {
                $record = DailyStockRecord::query()->firstOrNew([
                    'sku_id' => $skuId,
                    'day' => $date,
                ]);
                $record->arrived_today_num = !empty($purchaseRecords[$externalSkuId]["arrived_today_num"])
                    ? $purchaseRecords[$externalSkuId]["arrived_today_num"] : 0;
                $record->loss_num = !empty($lossRecords[$externalSkuId]["loss_num"])
                    ? $lossRecords[$externalSkuId]["loss_num"] : 0;
                $record->order_goods_num = !empty($orderItems[$externalSkuId]["goods_total"])
                    ? $orderItems[$externalSkuId]["goods_total"] : 0;
                $record->order_total_amount = !empty($orderItems[$externalSkuId]["order_total_amount"])
                    ? $orderItems[$externalSkuId]["order_total_amount"] : 0;
                $record->save();
            });
        }
    }
}
