<?php

namespace App\Http\Controllers\api\thirdPart\weixin;

use App\Components\ApiProcurementResponse;
use App\Http\Controllers\Controller;
use App\Procurement;
use App\ProcurementCheckSheet;
use App\ProcurementDeliverie;
use App\ProcurementQuotation;
use App\ProcurementTotalBill;
use App\Services\api\UserService;
use App\Services\ProcurementService;
use App\Services\SupplierService;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ProcurementController extends Controller
{
    use ApiProcurementResponse;

    public function getWaitQuotation(Request $request): \Illuminate\Http\JsonResponse
    {
        $user=Auth::user();
        /**@var SupplierService $supplierService*/
        $supplierService=app(SupplierService::class);
        $supplier_ids=$supplierService->screenSupplierIds();
        $status=$request->input('status');//0:待报价,2:待接单
        switch ($status){
            case 0:
                $procurements=Procurement::query()
                    ->withCount('procurementQuotations')
                    ->with('ownerMaterial.material')
                    ->where('status',$status)
                    ->whereHas("ownerMaterial",function (Builder $query)use($supplier_ids){
                        $query->whereHas("material",function (Builder $query)use($supplier_ids){
                            $query->whereHas("supplier",function (Builder $query)use($supplier_ids){
                                $query->whereIn('id',$supplier_ids);
                            });
                        });
                    })
                    ->get();
                break;
            case 2:
                $procurements=Procurement::query()
                    ->withCount('procurementQuotations')
                    ->with('ownerMaterial.material')
                    ->where('status',$status)
                    ->whereIn('supplier_id',$supplier_ids)
                    ->get();
                break;
        }
        if (!isset($procurements))return $this->error('未查到相应单据');
        foreach ($procurements as $key=>$procurement){
            if ($status==0 && $procurement->procurement_quotations_count>0 && !$user->isSuperAdmin()){
                foreach ($procurement->procurementQuotations as $procurementQuotation){
                    if (in_array($procurementQuotation->supplier_id,$supplier_ids))unset($procurements[$key]);
                }
            }
            if ($procurement->type==2 && $procurement->supplier_id )unset($procurements[$key]);
            if (Carbon::parse($procurement->deadline)->gt(Carbon::now())) $procurement->deadline=Carbon::parse($procurement->deadline)->diffInMilliseconds();
            else $procurement->deadline=0;
        }
        if (!empty($procurements)) return $this->success($procurements);
    }

    public function getQuotationDetailById(Request $request): \Illuminate\Http\JsonResponse
    {
        $id=$request->input('id');
        $procurement=Procurement::query()
            ->with(['ownerMaterial.material','ownerMaterial.owner','ownerMaterial.file'])
            ->find($id);
        $procurement->deadline=Carbon::parse($procurement->deadline)->diffInMilliseconds(Carbon::now());
        if ($procurement) return $this->success($procurement);
    }
    //报价
    public function setOffer(Request $request): \Illuminate\Http\JsonResponse
    {
        $param=$request->all(['id','offer']);
        $user= Auth::user();
        $procurement=Procurement::query()->with('ownerMaterial.material')->find($param['id']);
        $material=$procurement->ownerMaterial->material;
        /** @var ProcurementService $procurementService*/
        $procurementService=app(ProcurementService::class);
        $supplier=$procurementService->screenSupplier($user,$material);
        $procurementQuotation=ProcurementQuotation::query()->create([
            'procurement_id'=>$param['id'],
            'offer'=>$param['offer'],
            'operator'=>$user->id,
            'supplier_id'=>$supplier->id,
            'quoted_at'=>Carbon::now()->toDateTimeString(),
            'status'=>1,//1:已报价
        ]);
        DB::transaction(function ()use($procurement,$param,$supplier){
            if (!$procurement->supplier_id)$procurement->update([
                "supplier_id" => $supplier->id,
//                "status" =>1,
                "cost_price" =>$param['offer'],
            ]);
            DB::commit();
        });
        if ($procurementQuotation) return $this->success($procurementQuotation);
    }
    //接单
    public function accept(Request $request): \Illuminate\Http\JsonResponse
    {
        $id=$request->input('id');
        $user= Auth::user();
        $procurement=Procurement::query()->with('ownerMaterial.material')->find($id);
        if ($procurement->type==2){
            $material=$procurement->ownerMaterial->material;
            /** @var ProcurementService $procurementService*/
            $procurementService=app(ProcurementService::class);
            $supplier=$procurementService->screenSupplier($user,$material);
            $procurement->update(['status'=>4,'supplier_id'=>$supplier->id,'deadline'=>Carbon::now()->toDateTimeString()]);//4:生产中
        }else{
            $procurement->update(['status'=>4,'deadline'=>Carbon::now()->toDateTimeString()]);//4:生产中
        }
        if ($procurement) return $this->success($procurement);
    }
    //生产中的订单
    public function getProductionProcurement(): \Illuminate\Http\JsonResponse
    {
        /**@var SupplierService $supplierService*/
        $supplierService=app(SupplierService::class);
        $supplier_ids=$supplierService->screenSupplierIds();
        $procurements=Procurement::query()
            ->with('ownerMaterial.material')
            ->whereIn('type',[0,2])
            ->where('status',4) //4:生产中
            ->whereIn('supplier_id',$supplier_ids)
            ->get();
        if ($procurements) return $this->success($procurements);
    }
    //结束生产
    public function finishProductionProcurement(Request $request): \Illuminate\Http\JsonResponse
    {
        $id=$request->input('id');
        $procurement=Procurement::query()->find($id)->update(['status'=>5]);//  5 => "待收货",
        if ($procurement) return $this->success($procurement);
    }
    //取消生产
    public function cancelProcurement(Request $request): \Illuminate\Http\JsonResponse
    {
        $id=$request->input('id');
        $procurement=Procurement::query()->find($id)->update(['status'=>10]);//  10 => "订单取消",
        if ($procurement) return $this->success($procurement);
    }

    public function getProcurementDeliveries(): \Illuminate\Http\JsonResponse
    {
        /**@var SupplierService $supplierService*/
        $supplierService=app(SupplierService::class);
        $supplier_ids=$supplierService->screenSupplierIds();
        $procurementDeliveries=ProcurementDeliverie::query()
            ->with('procurement.ownerMaterial.material')
            ->whereIn('status',[0,1])//1:待送货,2:送货中
            ->whereHas('procurement',function (Builder $query)use($supplier_ids){
                $query->whereIn('supplier_id',$supplier_ids);
            })
            ->get();
        $procurementDeliveries=$procurementDeliveries->filter(function ($item){
            return isset($item->procurement);
        });
        if ($procurementDeliveries) return $this->success($procurementDeliveries);
    }
    public function makeProcurementDelivery(Request $request): \Illuminate\Http\JsonResponse
    {
        $param=$request->all(['id','deliverAmount']);
        $procurement=Procurement::query()
            ->with('procurementDeliveries')
            ->find($param['id']);
        $deliveryAmount=$param['deliverAmount'];
        if (!empty($procurement->procurementDeliveries)){
            foreach ($procurement->procurementDeliveries as $delivery){
                if (!$delivery->amount)continue;
                $deliveryAmount=$deliveryAmount+$delivery->amount;
            }
        }
        if ((int)$deliveryAmount>(int)$procurement->quantity) return  response()->json(['status'=>0,'message' => '当前送货数量叠加已送货数量大于采购数量','data'=>$deliveryAmount], 401);
        //生成送货单
        $procurementDelivery=new ProcurementDeliverie();
        $procurementDelivery['procurement_id']=$param['id'];
        $procurementDelivery['amount']=$param['deliverAmount'];
        $procurementDelivery['initiator']=Auth::user()['id'];
        $procurementDelivery['signer']=$procurement->initiator ?? 0;
        $procurementDelivery['created_at']=Carbon::now()->toDateTimeString();
        $procurementDelivery['updated_at']=Carbon::now()->toDateTimeString();
        $procurementDelivery->save();
        $procurementDelivery->loadMissing( 'procurement.ownerMaterial.material');
        //当前采购单不是打样单生成对账单
        if ($procurement->type!=2)ProcurementCheckSheet::query()->create(['procurement_delivery_id'=>$procurementDelivery->id,'account_payable'=>$procurementDelivery->receipt_amount*$procurement->cost_price,'auditor'=>0]);
        if ($procurementDelivery) return $this->success($procurementDelivery);
    }
    public function getProcurementDeliveryById(Request $request): \Illuminate\Http\JsonResponse
    {
        $procurementDelivery=ProcurementDeliverie::query()
            ->with(['procurement.ownerMaterial.material','receiver.userDetail','procurement.ownerMaterial.owner.customer','procurement.supplier','procurement.ownerMaterial.file'])
            ->find($request->input('id'));
        if ($procurementDelivery) return $this->success($procurementDelivery);
    }
    public function updateProcurementDeliveryAmount(Request $request): \Illuminate\Http\JsonResponse
    {
        $param=$request->all(['id','delivernum']);
        $procurementDelivery=ProcurementDeliverie::query()->where('id',$param['id'])->update(['amount'=>$param['delivernum']]);
        if ($procurementDelivery)return $this->success($procurementDelivery);
    }

    public function getProcurementTotalBill(): \Illuminate\Http\JsonResponse
    {
        $procurementTotalBills=ProcurementTotalBill::query()
            ->orderByDesc('id')
            ->get();
        foreach ($procurementTotalBills as $procurementTotalBill){
            /** @var  ProcurementTotalBill $procurementTotalBill */
            $procurementTotalBill->setCurrentMothProcurements();
        }
        if ($procurementTotalBills) return $this->success($procurementTotalBills);
    }
    public function markProcurementTotalBillStatus(Request $request): \Illuminate\Http\JsonResponse//供应商提交对账单
    {
        $id=$request->input('id');
        $procurementTotalBill=ProcurementTotalBill::query()->find($id);
        $procurementTotalBill->update(['status'=>1]);//1:已出账
        /** @var  ProcurementTotalBill $procurementTotalBill */
        $procurementTotalBill->setCurrentMothProcurements();
        if (isset($procurementTotalBill->procurementCheckSheets)){
            $procurementCheckSheets=$procurementTotalBill->procurementCheckSheets;
            foreach ($procurementCheckSheets as $procurementCheckSheet){
                $procurementCheckSheet->update(['status'=>2]);//2 已出账
            }
        }
        return $this->success($procurementTotalBill);
    }
    //收货员确认收货
    public function makeReceipt(Request $request): \Illuminate\Http\JsonResponse
    {
        $param=$request->all(['id','delivernum']);
        $procurementDelivery=ProcurementDeliverie::query()->with('procurement')->find($param['id']);
        if ($param['delivernum']!=0) {
            $receipt_amount=$param['delivernum'];
        }else{
            $receipt_amount=$procurementDelivery['amount'];
        }
        $procurementDelivery ->update([
            'status'=>1,
            'receipt_amount'=>$receipt_amount,
            'created_at'=>Carbon::now()->toDateTimeString(),
            'signed_at'=>Carbon::now()->toDateString()]
        );
        $procurementDelivery->procurement->update(['status'=>6]);
        if ($procurementDelivery) return $this->success($procurementDelivery);
    }
    public function supplierDeliverConfirm(Request $request): \Illuminate\Http\JsonResponse
    {
        $procurementDelivery=ProcurementDeliverie::query()
            ->with(['procurement','procurementCheckSheet'])->find($request->input('id'));
        $procurementDelivery->update(['status'=>2]);//2:送货完成
        $procurementCheckSheet=$procurementDelivery->procurementCheckSheet;
        if ($procurementDelivery->procurement
            && $procurementDelivery->procurement->type!=2
            && $procurementCheckSheet)
        $procurementCheckSheet->update(['status'=>1,'account_payable'=>($procurementDelivery->receipt_amount*$procurementDelivery->procurement->cost_price)]);
        $procurementDelivery->procurement->update(['status'=>7]);//待出账
        if ($procurementDelivery) return $this->success($procurementDelivery);
    }
}
