<?php

namespace App\Services;

use App\OracleDOCASNDetail;
use App\OracleDOCASNHeader;
use App\OracleDOCOrderDetail;
use App\OracleDOCOrderHeader;
use App\OrderIssue;
use App\OrderIssueOnTop;
use App\OrderIssueProcessLog;
use App\OrderPackage;
use App\Order;
use App\OrderPackageCommodities;
use App\RejectedBill;
use App\RejectedBillItem;
use App\Sign;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class OrderIssueService
{

    public function __construct()
    {
        app()->bind("orderService", OrderService::class);
        app()->bind("rejectedService", RejectedService::class);
        app()->bind("orderPackageCommoditiesService", OrderPackageCommoditiesService::class);
    }

    public function getQuery(Request $request, array $condition = null)
    {
        if (!isset($condition)) {
            $condition = $request->all();
        }
        $user = Auth::user();
        $owner_ids = $user ? $user->getPermittingOwnerIdsAttribute() : [];
        $order_ids = [];
        if (isset($condition['owner_id'])) {
            $owner_ids = explode(',', $condition['owner_id']);
        }

        $orderIssues = OrderIssue::whereHas('order', function ($query) use ($owner_ids) {
            $query->whereHas('owner', function ($query) use ($owner_ids) {
                return $query->whereIn('id', $owner_ids);
            });
        })->get();

        $orders = Order::select('id')->whereIn('owner_id', $owner_ids)->get();
        foreach ($orders as $order) {
            array_push($order_ids, $order['id']);
        }
        $query = OrderIssue::with(['top', 'userWorkGroup', 'issueType', 'logs' => function ($query) {
            return $query->with(['user'])->orderByDesc('created_at');
        }, 'order' => function ($query) use ($order_ids) {
            return $query->whereIn('id', $order_ids)->with(['shop', 'logistic', 'owner', 'packages' => function ($query) {
                return $query->with(['commodities' => function ($query) {
                    return $query->with('commodity');
                }]);
            }]);
        }, 'rejectedBill' => function ($query) {
            return $query->with(['items']);
        }, 'secondOrder' => function ($query) {
            return $query->with(['shop', 'logistic', 'owner', 'packages' => function ($query) {
                return $query->with(['commodities' => function ($query) {
                    return $query->with('commodity');
                }]);
            }]);
        }])->whereHas('order', function ($query) use ($owner_ids) {
            $query->whereHas('owner', function ($query) use ($owner_ids) {
                return $query->whereIn('id', $owner_ids);
            });
        });
        // ->whereIn('order_id', $order_ids)
        $query->selectRaw('order_issues.* ,order_issue_on_tops.id top_id ,order_issue_on_tops.remark,order_issue_on_tops.updated_at top_update')
            ->leftJoin('order_issue_on_tops', 'order_issue_on_tops.order_issue_id', '=', 'order_issues.id')
            ->whereNull('order_issue_on_tops.deleted_at')
            ->orderBy('order_issue_on_tops.updated_at', 'desc')
            ->orderBy('order_issues.id', 'desc');
        return $query;
    }

    public function getConditionQuery(Request $request, array $condition = null)
    {
        $query = $this->getQuery($request, $condition);
        if (!isset($condition)) {
            $condition = $request->all();
        }
        if (isset($condition['created_at_start'])) {
            $query->where('created_at', '>=', $condition['created_at_start'] . " 00:00:00");
        }
        if (isset($condition['created_at_end'])) {
            $query->where('created_at', '<=', $condition['created_at_end'] . " 23:59:59");
        }
        if (isset($condition['final_status'])) {
            $query->where('final_status', $condition['final_status']);
        }
        if (isset($condition['handle_status'])) {
            $query->where('handle_status', intval($condition['handle_status']));
        }
        if (isset($condition['logistic_indemnity_money'])) {
            $query->where('logistic_indemnity_money', $condition['logistic_indemnity_money']);
        }
        if (isset($condition['baoshi_express_remission'])) {
            $query->where('baoshi_express_remission', $condition['baoshi_express_remission']);
        }
        if (isset($condition['is_new_rejecting'])) {
            $query->where('is_new_rejecting', $condition['is_new_rejecting']);
        }
        if (isset($condition['order_issue_ids'])) {
            $orderIssuesId = $condition['order_issue_ids'];
            if (is_string($orderIssuesId)) {
                $orderIssuesId = explode(',', $orderIssuesId);
            }
            $query->whereIn('order_issues.id', $orderIssuesId);
        }
//        dd($query->toSql());
        return $query;
    }

    public function paginate(Request $request)
    {
        return $this->getConditionQuery($request)->paginate($request->input('paginate', 50));
    }

    public function orderIssueTag(Request $request)
    {
        $orderNos = $request->input('orderNos');
        $meg = ['success' => false];
        if ($this->verifyOrderIssue($request)) {
            $meg['fail_info'] = '传入订单编号中对应的订单问题已有生成';
            return $meg;
        }
        foreach ($orderNos as $orderNo) {
            $orderIssue = $this->createOrFind($orderNo);
            OrderIssueProcessLog::create(['order_issue_id' => $orderIssue['id'], 'user_id' => Auth::user()['id'], 'content' => '标记创建订单问题件', 'type' => '创建']);
        }
        $meg['success'] = true;
        return $meg;
    }

    public function createOrFind($orderNo)
    {
        $orderService = app('orderService');
        $rejectedService = app('rejectedService');
        $order = $orderService->createOrderByWMSOrderNo($orderNo);
        $arr = [
            'order_id' => $order->id,
        ];
        $orderIssue = OrderIssue::create($arr);
        if ($order->code) {
            $rejectedBill = $rejectedService->getRejectedByWMSOrderNo($order->code);
            if ($rejectedBill) {
                $orderIssue->rejected_bill_id = $rejectedBill['id'];
                $orderIssue->save();
            }
        }
        $this->judgeRejectingStatus($orderIssue);
        $orderIssue->order = $order;
        return $orderIssue;
    }

    /*    public function createOrderIssue(Request $request)
        {
            $orderService = app('orderService');
            $this->validatorCreate($request)->validate();
            $oracleOrderNo = $request->input('order_id');
            $logistic_number = $request->input('logistic_number');
            $order = $orderService->creted($oracleOrderNo);
            $this->create($request);
        }*/

    public function validatorCreate(Request $request)
    {
        return Validator::make($request->input(), [
            'rejected_bill_id' => ['nullable'],
            'order_id' => ['nullable'],
            'owner_id'=>['required'],
            'second_order_id' => ['nullable'],
            'logistic_id' => ['nullable'],
            'order_issue_type_id' => ['required'],
            'baoshi_indemnity_money' => ['numeric', 'nullable'],
            'logistic_indemnity_money' => ['numeric', 'nullable'],
            'final_status' => ['nullable'],
            'result_explain' => ['nullable']
        ], [
            'required' => ':attribute 为必填项',
            'unique' => ':attribute 已存在',
            'numeric' => ':attribute 为数组',
        ], [
            'owner_id'=>'货主',
            'rejected_bill_id' => '退回单号',
            'order_id' => '订单ID',
            'second_order_id' => '退回订单id',
            'logistic_id' => '承运人',
            'order_issue_type_id' => '问题类别',
            'baoshi_indemnity_money' => '宝时赔偿金额',
            'logistic_indemnity_money' => '承运商赔偿金额',
            'final_status' => '最终状态',
            'result_explain' => '处理结果说明',
        ]);
    }

    public function create(Request $request)
    {
        $orderIssue = OrderIssue::create($request->all());
        if (!$request->has('order_id')) {
            $order = Order::create($request->all());
            $orderIssue->order_id = $order['id'];
            $orderIssue->save();
        }
        if (!$request->filled('rejected_bill_id')) {
            $orderIssue->update(['rejecting_status' => '无']);
        } else {
            $this->judgeRejectingStatus($orderIssue);
        }
        return $orderIssue;
    }

    public function judgeRejectingStatus(OrderIssue $orderIssue)
    {
        $orderPackageCommoditiesService = new OrderPackageCommoditiesService();
        $rejectedItems = [];
        $orderItems = [];
        if ($orderIssue->rejected_bill_id) {
            $rejectedBill = RejectedBill::find($orderIssue->rejected_bill_id)->first();
            $rejectedBillItems = RejectedBillItem::where('id_rejected_bill', $rejectedBill->id)->get();
            if ($rejectedBillItems) {
                foreach ($rejectedBillItems as $item) {
                    if (!isset($rejectedItems[$item->barcode_goods])) {
                        $rejectedItems[$item->barcode_goods] = 0;
                    }
                    $rejectedItems[$item->barcode_goods] = $item->amount + $rejectedItems[$item->barcode_goods] ?? 0;
                }
            }
        } else {
            $orderIssue->update(['rejecting' => '无']);
            $orderIssue->save();
            return;
        }
        if ($orderIssue->order_id) {
            $orderPackageCommodities = $orderPackageCommoditiesService->getOrderPackageCommoditiesByOrderId($orderIssue->order_id);
            if ($orderPackageCommodities) {
                foreach ($orderPackageCommodities as $key => $item) {
                    if (!isset($orderItems[$item->commodity->sku])) {
                        Arr::add($orderItems, $item->commodity->sku, 0);
                    }
                    $orderItems[$item->commodity->sku] = $orderItems[$item->commodity->sku] ?? 0 + $item->amount;
                }
            } else {
                $orderIssue->update(['rejecting_status' => '未退回']);
                $orderIssue->save();
                return;
            }
        }

        $rejectedExcess = 0;    // 退回差异
        $rejectedReview = 0;    // 退回复核  $rejectedItems == $orderItems
        foreach ($rejectedItems as $key => $items) {
            if (!isset($orderItems[$key])) {
                $rejectedExcess++;
            } else {
                if ($rejectedItems[$key] == $orderItems[$key]) {
                    $rejectedReview++;
                }
            }
        }
        if ($rejectedExcess > 0) {
            $orderIssue->update(['rejecting_status' => '差异退回']);
            $orderIssue->save();
            return;
        }
        $isExcess = 0; // 超量 $orderItems < $rejectedItems
        $isDiff = 0;   // 部分 $orderItems > $rejectedItems
        $isAccord = 0; // 相同 $orderItems == $rejectedItems
        $isLack = 0;   // 缺少 $orderItems != $rejectedItems
        foreach ($orderItems as $key => $item) {
            if (isset($rejectedItems[$key])) {
                if ($orderItems[$key] > $rejectedItems[$key]) {
                    $isExcess++;
                } else if ($orderItems[$key] < $rejectedItems[$key]) {
                    $isDiff++;
                } else if ($orderItems[$key] == $rejectedItems[$key]) {
                    $isAccord++;
                }
            } else {
                $isLack++;
            }
        }
        if ($isAccord == $rejectedReview) {
            $orderIssue->update(['rejecting_status' => '全部退回']);
            $orderIssue->save();
            return;
        } else if ($isDiff > 0 and $isLack >= 0) {
            $orderIssue->update(['rejecting_status' => '部分退回']);
            $orderIssue->save();
            return;
        } else if ($isExcess > 0 and $isDiff == 0) {
            $orderIssue->update(['rejecting_status' => '超量退回']);
            $orderIssue->save();
            return;
        }
    }

    public function createByLogisticNumber(Request $request)
    {
        $orderService = app('orderService');
        $order = Order::create($request->all());
        $orderIssue = OrderIssue::create($request->all());
        $orderIssue->order_id = $order['id'];
        OrderPackage::create(['order_id' => $order->id, 'logistic_number' => $request->input('logistic_number_return')]);
        $orderIssue->update();
        return $orderIssue;
    }

    public function verifyOrderIssue(Request $request)
    {
        $orderIds = $request->input('orderNos');
        $orders = Order::whereIn('code', $orderIds)->get();
        if (count($orders) == 0) {
            return false;
        }
        $order_ids = [];
        foreach ($orders as $order) {
            $order_ids[] = $order->id;
        }
        $count = OrderIssue::whereIn('order_id', $order_ids)->count();
        return $count != 0;
    }

    /*    public function verifyOracleOrderNo(Request $request)
        {
            $meg = ['success' => false];
            $oracleOrderNo = $request->input('oracleOrderNo');
            $type = $request->input('type');
            $orderHeader = OracleDOCOrderHeader::where('OrderNo', trim($oracleOrderNo, "'"))->first();
            if ($orderHeader == null) {
                $meg['fail_info'] = '没有编号对应的订单信息';
            } else {
                if ($type == 'backExpressNumber') {

                    $orderASNHeader = OracleDOCASNHeader::where('ASNReference2', $orderHeader->soreference1)->first();

                    if ($orderASNHeader == null) {
                        $meg['fail_info'] = '没有对应的退件信息';
                    } else {
                        $express_number = $orderASNHeader->asnreference3; // 快递单号
                        $express_number == null ? $meg['fail_info'] = '没有对应的快递单号' : ($meg['success'] = true && $meg['expressNumber'] = $express_number);
                    }
                } else if ($type == 'verify') {
                    if (!$orderHeader) {
                        $mes['fail_info'] = '编号对应的订单信息不存在';
                    } else {
                        $mes['success'] = true;
                    }
                }
            }
            return $meg;
        }*/

    /*    public function verifyLogisticNumber(Request $request)
        {
            $logisticNumber = $request->input('logisticNumber');
            $ASNHeader = OracleDOCASNHeader::where('ASNReference2', $logisticNumber)->first();
            $orderHeader = OracleDOCOrderHeader::where('soreference1', $ASNHeader->asnreference3)->first();
            $meg = ['success' => false];
            if (!$orderHeader) {
                $meg['fail_info'] = '快递单号没有对应的订单';
            }
            return $meg['success'] = true;
        }*/

//    public function getOrderHead(Request $request)
//    {
//        $data = ['orderHeader' => null, 'orderDetails' => null, 'rejectedBill' => null];
//        $logisticNumberReturn = $request->input('logisticNumberReturn');
//        $ASNOrderHeaders = OracleDOCASNHeader::where('ASNReference3', $logisticNumberReturn)->get();
//        if (count($ASNOrderHeaders) == 0) {
//            return $data;
//        }
//        $orderHeader = OracleDOCOrderHeader::where('SOReference1', $ASNOrderHeaders->asnreference3)->get();
//        $data['orderHeader'] = $orderHeader;
//        $orderDetails = OracleDOCASNDetail::with(['sku'])->where('OrderNo', $orderHeader)->get();
//        $data['orderDetails'] = $orderDetails;
//
//        return $data;
//    }

    public function getReturnLogisticInfo(Request $request)
    {
        $logisticNumberReturn = $request->input('logisticNumberReturn');
        $ASNOrderHeaders = OracleDOCASNHeader::where('ASNReference3', $logisticNumberReturn)->get();
        $ASNNo = [];
        foreach ($ASNOrderHeaders as $ASNOrderHeader) {
            $ASNNo[] = $ASNOrderHeader->asnno;
        }
        return OracleDOCASNDetail::whereIn('asnno', $ASNNo)->get();
    }

    public function getOrderHeadByOrderNo(Request $request)
    {
        $orderNo = $request->input('orderNo');
        $orderHeader = OracleDOCOrderHeader::where('orderNo', $orderNo)->get();
        $orderDetails = OracleDOCOrderDetail::with(['sku'])->where('orderNo', $orderNo)->get();
        return ['orderHeader' => $orderHeader, 'orderDetails' => $orderDetails];
    }

    public function exportExcel(Request $request)
    {
        $result = null;
        if ($request->getMethod() == 'GET') {
// 所有页
            if ($request->has('checkAllSign')) {
                $result = $this->getConditionQuery($request, null)->get();
            }
        } else if ($request->getMethod() == 'POST') {
// 选中
            $orderIssueIds = $request->input('data');
            $ids = explode(',', $orderIssueIds);
            $result = $this->getConditionQuery($request, ['order_issue_ids' => $ids])->get();
        }
        return $result;
    }

    public function paddingData(array $row, array $rowData)
    {
        foreach ($rowData as $key => $value) {
            foreach ($row as $rowKey) {
                if (!isset($value[$rowKey])) {
                    $value[$rowKey] = '';
                }
            }
        }
        return $rowData;
    }

}
