<?php

namespace App\Http\Controllers\Supplier;

use App\Events\BatchStockUpdateEvent;
use App\Http\Controllers\Controller;
use App\Http\Enum\ExcelKeyEnum;
use App\Http\Enum\Purchase\PurchaseConfigEnum;
use App\Http\Enum\Purchase\PurchaseStatusEnum;
use App\Http\Enum\TargetTypeEnum;
use App\Http\Resources\GoodsSkuResource;
use App\Http\Resources\RolesResource;
use App\Imports\PurchaseImport;
use App\Models\GoodsSku;
use App\Models\Log;
use App\Models\Log as LogModel;
use App\Models\PurchaseRecords;
use App\Models\Suppliers;
use App\Models\User;
use App\Services\DeveloperConfig\DeveloperConfigService;
use App\Services\GoodSku\GoodSkuService;
use App\Utils\DateTimeUtils;
use App\Utils\GeneratorUtils;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;

class PurchaseRecordController extends Controller
{
    public $isAutoCheck = 0;

    public function __construct(Request $request)
    {
        $this->log = new LogModel([
            'module' => 'supplier',
            'action' => $request->getMethod(),
            'target_type' => 'purchase_record',
        ]);
    }

    public function index(Request $request)
    {
        $builder = PurchaseRecords::query()->filter()->with("goodsSku:id,name,external_sku_id,title");
        if (!empty($request->start_time) && !empty($request->end_time)) {
            $builder->whereBetween('created_at', [$request->start_time, $request->end_time]);
        }
        if (!empty($request->date_start_time) && !empty($request->date_end_time)) {
            $dateStart = Carbon::parse($request->date_start_time)->toDateString();
            $dateEnd = Carbon::parse($request->date_end_time)->subDay()->toDateString();
            $builder->whereBetween('date', [$dateStart, $dateEnd]);
        }
        if (!empty($request->title)) {
            $builder->whereHas('goodsSku', function ($query) use ($request) {
                $query->where('name', 'like', '%' . $request->title . '%');
            });
        }
        $dailyStockRecord = $builder->orderByDesc("id")->paginate($request->get('per_page'));
        return JsonResource::collection($dailyStockRecord);
    }

    public function store(Request $request)
    {
        //获取所有参数
        $allParams = $request->all();
        //进行校验验证
        $validator = Validator::make($allParams, [
            'external_sku_id' => 'required|string',
            'num' => 'required|integer',
        ]);
        if ($validator->fails()) {
            //校验失败返回异常
            $this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
            return response($this->res, $this->res['httpCode']);
        }
        $goodsSku = GoodsSku::query()->where('external_sku_id', "=", $request->external_sku_id)->first();
        if (!empty($goodsSku)) {
            $expireDay = DeveloperConfigService::getDefaultExpireDay();
            $today = DateTimeUtils::getToday();
            if (empty($allParams['buyer_user_id'])) {
                $buyerUserId = User::query()->where("name", $allParams['buyer_name'] ?? '')
                    ->pluck("id")->first();
            }
            if (empty($allParams['supplier_id'])) {
                $supplierId = Suppliers::query()->where("supplier_name", $allParams['supplier_name'] ?? '')
                    ->pluck("id")->first();
            }

            //保存記錄
            $purchaseRecords = new PurchaseRecords();
            $purchaseRecords->external_sku_id = $allParams['external_sku_id'];
            $purchaseRecords->batch_number = GeneratorUtils::generateBatchNumber();
            $purchaseRecords->num = $allParams['num'];
            $purchaseRecords->cost = $allParams['cost'];
            $purchaseRecords->date = $today;
            $purchaseRecords->buyer_user_id = $allParams['buyer_user_id'] ?? ($buyerUserId ?? 0);
            $purchaseRecords->buyer_name = $allParams['buyer_name'] ?? '';
            $purchaseRecords->supplier_name = $allParams['supplier_name'] ?? '';
            $purchaseRecords->supplier_id = $allParams['supplier_id'] ?? ($supplierId ?? 0);
            if (!empty($allParams['expire_time'])) {
                $purchaseRecords->expire_time = Carbon::parse($allParams['expire_time'])->toDateTimeString();
            } else {
                $purchaseRecords->expire_time = Carbon::now()->addDays($expireDay)->toDateTimeString();
            }
            $purchaseRecords->save();
            if (PurchaseConfigEnum::IS_AUTO_CHECK) {
                $allParams['user_id'] = $request->user()->id;
                $updateIds = GoodSkuService::computeSkuStock($goodsSku->toArray(), $allParams, TargetTypeEnum::PURCHASE);
                event(new BatchStockUpdateEvent($updateIds));
            }
        } else {
            $this->res = [
                'httpCode' => 400,
                'message' => '查询不到sku信息',
                'errorCode' => "ERP001",
                'errorMessage' => '查询不到sku信息',
            ];
        }

        return response($this->res, $this->res['httpCode']);
    }


    public function update($id, Request $request)
    {
        //获取所有参数
        $allParams = $request->all();
        //进行校验验证
        $validator = Validator::make($allParams, [
            'buyer_name' => 'sometimes|string',
            'supplier_name' => 'sometimes|string',
            "expire_time" => 'sometimes|string'
        ]);
        if ($validator->fails()) {
            //校验失败返回异常
            $this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
            return response($this->res, $this->res['httpCode']);
        }
        $goodsSku = GoodsSku::query()->where('id', "=", $id)->get();
        if (!empty($goodsSku)) {
            //可以修改的記錄
            $purchaseRecords = PurchaseRecords::query()->find($id);
            $purchaseRecords->buyer_user_id = $allParams['buyer_user_id'] ?? 0;
            $purchaseRecords->buyer_name = $allParams['buyer_name'] ?? '';
            $purchaseRecords->supplier_name = $allParams['supplier_name'] ?? '';
            $purchaseRecords->supplier_id = $allParams['supplier_id'] ?? 0;
            if ($purchaseRecords->status == PurchaseStatusEnum::WAIT_CHECK) {
                $purchaseRecords->cost = $allParams['cost'] ?? 0;
                $purchaseRecords->num = $allParams['num'] ?? 0;
            }
            if (!empty($allParams['expire_time'])) {
                $purchaseRecords->expire_time = Carbon::parse($allParams['expire_time'])->toDateTimeString();
            }
            if (!empty($allParams['date'])) {
                $purchaseRecords->date = Carbon::parse($allParams['date'])->toDateString();
            }
            if (!empty($allParams['arrived_time'])) {
                $purchaseRecords->arrived_time = Carbon::parse($allParams['arrived_time'])->toDateTimeString();
            }

            $purchaseRecords->save();

        } else {
            $this->res = [
                'httpCode' => 400,
                'message' => '查询不到sku信息',
                'errorCode' => "ERP001",
                'errorMessage' => '查询不到sku信息',
            ];
        }

        return response($this->res, $this->res['httpCode']);
    }

    /**
     * 采购单后台批量存储
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void
     */
    public function purchaseBatchStore(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'purchaseOrders' => 'required|array',
            'purchaseOrders.*.external_sku_id' => 'required|string',
            'purchaseOrders.*.num' => 'required|integer',
            'purchaseOrders.*.cost' => 'required',]);
        //参数校验
        if ($validator->fails()) {
            $this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
            return response($this->res, $this->res['httpCode']);
        }
        $purchaseOrders = $request->input('purchaseOrders') ?? [];
        $externalSkuIds = collect($purchaseOrders)->pluck("external_sku_id")->toArray();
        $goodsSku = GoodsSku::query()->whereIn('external_sku_id', $externalSkuIds)->get();
        if (collect($externalSkuIds)->diff($goodsSku->pluck("external_sku_id"))->isNotEmpty()) {
            $content = implode(',', collect($externalSkuIds)->diff($goodsSku->pluck("external_sku_id"))->toArray());
            $content .= "以上sku编码数据库中不存在";
            return response($content, 400);
        }
        $goodsSkuMap = $goodsSku->pluck(null, 'external_sku_id')->toArray();
        $allUpdateIds = [];
        $expireDay = DeveloperConfigService::getDefaultExpireDay();
        $today = DateTimeUtils::getToday();
        $batchNumber = GeneratorUtils::generateBatchNumber();
        //开始保存数据
        foreach ($purchaseOrders as $v) {
            $goodsSkuItem = $goodsSkuMap[$v['external_sku_id']];
            //保存記錄
            $purchaseRecords = new PurchaseRecords();
            $purchaseRecords->batch_number = $batchNumber;
            $purchaseRecords->external_sku_id = $v['external_sku_id'];
            $purchaseRecords->num = $v['num'];
            $purchaseRecords->cost = $v['cost'];
            $purchaseRecords->date = $v['date'] ?? $today;
            $purchaseRecords->buyer_user_id = $v['buyer_user_id'] ?? 0;
            $purchaseRecords->buyer_name = $v['buyer_name'] ?? '';
            $purchaseRecords->supplier_name = $v['supplier_name'] ?? '';
            $purchaseRecords->supplier_id = $v['supplier_id'] ?? 0;
            $purchaseRecords->arrived_time = $v['arrived_time'] ?? Carbon::now()->toDateTimeString();
            $purchaseRecords->expire_time = Carbon::now()->addDays($expireDay)->toDateTimeString();
            $purchaseRecords->save();
            if (PurchaseConfigEnum::IS_AUTO_CHECK) {
                $v['user_id'] = $request->user()->id;
                $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, $v, TargetTypeEnum::PURCHASE);
                $allUpdateIds = array_merge($allUpdateIds, $updateIds);
            }

        }
        if (PurchaseConfigEnum::IS_AUTO_CHECK) {
            //如果是組合商品会触发重算逻辑
            event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray()));
        }

        return response($this->res, $this->res['httpCode']);
    }

    /**
     * 报损单后台批量存储
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void
     */
    public function purchaseImport(Request $request)
    {
        if (!$request->hasFile(ExcelKeyEnum::PURCHASE_KEY)) {
            $this->res = [
                'httpCode' => 404,
                'errorCode' => 404404,
                'errorMessage' => 'not found purchase file',
            ];
        }
        try {
            $import = new PurchaseImport();
            $path = $request->file(ExcelKeyEnum::PURCHASE_KEY);
            Excel::import($import, $path);
            $this->addLog(0, 'import', ExcelKeyEnum::PURCHASE_KEY);
        } catch (ValidationException $exception) {
            $this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
        }

        return response($this->res, $this->res['httpCode']);
    }

    /**
     * 报损单后台批量存储
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void
     */
    public function purchaseBatchCheck(Request $request)
    {
        $params = $request->validate([
            'purchaseOrders' => 'required|array',
            'purchaseOrders.*.id' => 'required|integer',
            'purchaseOrders.*.status' => 'required|in:1,2',
            'purchaseOrders.*.num' => 'sometimes|integer',
        ]);
        $allUpdateIds = [];
        $now = Carbon::now()->toDateTimeString();
        foreach ($params['purchaseOrders'] as $v) {
            $purchaseRecordBuilder = PurchaseRecords::query()->with("goodsSku")->where("id", $v['id'])->first();
            if (empty($purchaseRecordBuilder)) {
                continue;
            }
            $purchaseRecords = $purchaseRecordBuilder->toArray();
            if (empty($purchaseRecords['goods_sku'])) {
                continue;
            }
            if ($purchaseRecords['status'] == $v['status']) {
                continue;
            }
            if (!empty($v['num'])) {
                $purchaseRecordBuilder->num = $v['num'];
                $purchaseRecords['num'] = $v['num'];
            }

            DB::beginTransaction();
            try {
                if (PurchaseStatusEnum::CHECK_SUCCESS == $v['status']) {
                    $updateIds = GoodSkuService::computeSkuStock($purchaseRecords['goods_sku'], $purchaseRecords, TargetTypeEnum::PURCHASE);
                    $allUpdateIds = array_merge($allUpdateIds, $updateIds);
                }
                $purchaseRecordBuilder->status = $v['status'];
                $purchaseRecordBuilder->check_time = $now;
                $purchaseRecordBuilder->save();
                DB::commit();
            } catch (\Exception $exception) {
                DB::rollBack();
                \Illuminate\Support\Facades\Log::error("质检审核事务异常", ["error" => $exception->getMessage()]);
            }
        }
        if (!empty($allUpdateIds)) {
            event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray()));
        }
        return response($this->res, $this->res['httpCode']);
    }


}
