<?php


namespace App\Http\Services;


use App\Http\Controllers\Filter\SupplierExaminationFilter;
use App\Http\Transformers\SupplierExaminationTransformer;
use App\Model\IntracodeModel;
use App\Model\SupplierChannelModel;
use App\Model\SupplierExaminationModel;
use App\Utils\CsvValueBinder;
use Maatwebsite\Excel\Facades\Excel;

class SupplierExaminationService
{

    public function getSupplierExaminationList($request)
    {
        $limit = $request->get('limit', 10);
        $filter = new SupplierExaminationFilter();
        $query = $filter->listFilter($request);
        $list = $query->paginate($limit)->toArray();
        $transformer = new SupplierExaminationTransformer();
        $list['data'] = $transformer->transformList($list['data']);
        return $list;
    }

    //检测是否重复,目前确定唯一的维度是通过供应商名称,型号,品牌,数量,时间五个维度判断,如果一致则判断为重复数据,进行覆盖即可
    public function checkExistsExamination($supplierName, $skuName, $brandName, $amount, $examineTime)
    {
        return SupplierExaminationModel::where('supplier_name', $supplierName)
            ->where('sku_name', $skuName)->where('brand_name', $brandName)->where('amount', $amount)
            ->where('examine_time', strtotime($examineTime))->value('id');
    }

    //保存
    public function saveSupplierExamination($data)
    {
        $data = BatchTrim($data);
        $data['examine_time'] = strtotime($data['examine_time']);
        $data['stock_in_date'] = strtotime($data['stock_in_date']);
        $existsExamination = $this->checkExistsExamination($data['supplier_name'], $data['sku_name'],
            $data['brand_name'],
            $data['amount'], $data['examine_time']);

        if (!empty($data['id']) || $existsExamination) {
            $data['update_time'] = time();
            return SupplierExaminationModel::where('id', $data['id'])->update($data);
        } else {
            $data['create_time'] = time();
            return SupplierExaminationModel::insert($data);
        }
    }

    //批量修改
    public function batchUpdateSupplierExamination($data)
    {
        $ids = explode(',', $data['ids']);
        return SupplierExaminationModel::whereIn('id',$ids)->update([
            'update_time' => time(),
            'examine_result' => $data['examine_result'],
        ]);
    }

    //删除
    public function deleteSupplierExaminations($ids)
    {
        return SupplierExaminationModel::whereIn('id', $ids)->delete();
    }

    //上传
    public function ImportSupplierExamination($filePath)
    {

        ini_set('memory_limit', -1);

        try {
            Excel::load($filePath, function ($reader) {
                $data = $reader->getSheet(0)->toArray();
                $header = $data[0];
                if (!$this->checkImportCsvHeader($header)) {
                    throw new \Exception('文件不是标准上传模板,请核对后再上传');
                }
                $dataMd5 = md5(json_encode($data));
                if (SupplierExaminationModel::where('data_md5', $dataMd5)->exists()) {
                    throw new \Exception('该文件已经上传过,请选择其它文件');
                }
                //获取所有采购员用于校验
                $channelUsers = (new IntracodeModel())->getAllEncode();
                $channelUserNames = array_column($channelUsers, 'name');
                $supplierNames = (new SupplierChannelModel())->where('is_type', 0)->pluck('supplier_name')->toArray();
                //拼装数据插入校验,校验完成插入数据库
                $insertData = [];
                $updateData = [];
                $errMsg = [];
                foreach ($data as $index => $item) {
                    if ($this->checkArrAllNull($item)) {
                        continue;
                    }
                    if ($index == 0) {
                        continue;
                    }
                    $lineNo = $index + 1;
                    $item = array_map(function ($value) {
                        return trim($value);
                    }, $item);
                    $orderSn = $item[0];
                    $purchaseSn = $item[1];
                    $examineTime = $item[2];
                    $salesName = $item[3];
                    $channelUserName = $item[4];
                    $ticketType = $item[5];
                    $supplierName = $item[6];
                    $skuName = $item[7];
                    $brandName = $item[8];
                    $amount = str_replace(',', '', $item[9]);
                    $batch = $item[10];
                    $producingArea = $item[11];
                    $stockInDate = $item[12];
                    $incomeSn = $item[13];
                    $deliverySn = $item[14];
                    $tallyRequest = $item[15];
                    $examineRequest = $item[16];
                    $unhealthyAmount = str_replace(',', '', $item[17]);
                    $abnormalLevel = $item[18];
                    $unhealthyContent = $item[19];
                    $examineResult = $item[20];
                    $remark = $item[21];
                    if (empty($supplierName)) {
                        $errMsg[] = "供应商名称不能为空! (第${lineNo}行)";
                    }
                    if (empty($examineTime)) {
                        $errMsg[] = "检货时间不能为空! (第${lineNo}行),请修改为 2022/10/10 这种格式后再次提交";
                    }

                    if (!empty($examineTime) && !isDateTime($examineTime)) {
                        $errMsg[] = "检货时间格式不规范! (第${lineNo}行),请修改为 2022/10/10 这种格式后再次提交";
                    }

                    if (!empty($stockInDate) && !isDateTime($stockInDate)) {
                        $errMsg[] = "入库日期时间格式不规范! (第${lineNo}行)";
                    }


                    if (!in_array($supplierName, $supplierNames)) {
                        $errMsg[] = "存在无效供应商(供应商系统不存在)的数据(第${lineNo}行)";
                    }
                    if (!in_array($channelUserName, $channelUserNames)) {
                        $errMsg[] = "存在无效的采购员(第${lineNo}行)";
                    }
                    if (empty($skuName)) {
                        $errMsg[] = "型号不能为空! (第${lineNo}行)";
                    }
                    if (empty($brandName)) {
                        $errMsg[] = "品牌不能为空! (第${lineNo}行)";
                    }
                    if (!is_numeric($amount) || empty($amount)) {
                        $errMsg[] = "数量只能为纯数字且不能为空! (第${lineNo}行)";
                    }

                    if (empty($examineResult) || !in_array($examineResult,
                            array_values(config('field.SupplierExamineResult')))) {
                        $errMsg[] = "检验结果只能(退货|特批入库|正常入库|待处理)其中一个且不能为空 (第${lineNo}行)";
                    }
                    if (!empty($abnormalLevel) && !in_array($abnormalLevel, [1, 2, 3])) {
                        $errMsg[] = "存在不合理的异常等级,等级必须为纯数字1,2,3或者不填 (第${lineNo}行)";
                    }

                    $item = [
                        'order_sn' => $orderSn,
                        'purchase_sn' => $purchaseSn,
                        'examine_time' => $examineTime ? strtotime($examineTime) : 0,
                        'sales_name' => $salesName,
                        'purchase_name' => $channelUserName,
                        'ticket_type' => $ticketType,
                        'supplier_name' => $supplierName,
                        'sku_name' => $skuName,
                        'brand_name' => $brandName,
                        'amount' => $amount,
                        'batch' => $batch,
                        'producing_area' => $producingArea,
                        'stock_in_date' => $stockInDate ? strtotime($stockInDate) : 0,
                        'income_sn' => $incomeSn,
                        'delivery_sn' => $deliverySn,
                        'tally_request' => $tallyRequest,
                        'examine_request' => $examineRequest,
                        'unhealthy_amount' => $unhealthyAmount,
                        'abnormal_level' => $abnormalLevel,
                        'unhealthy_content' => $unhealthyContent,
                        'examine_result' => $examineResult,
                        'remark' => $remark,
                        'create_time' => time(),
                        'data_md5' => $dataMd5,
                        'create_uid' => request()->user->userId,
                        'create_name' => request()->user->name,
                    ];

                    //判断是否已经存在,存在的话则去批量更新
                    if ($id = $this->checkExistsExamination($supplierName,$skuName,$brandName,$amount,$examineTime)){
                        $item['id'] = $id;
                        $updateData[] = $item;
                    }else{
                        $insertData[] = $item;
                    }
                }

                if ($errMsg) {
                    $errMsg = implode('&', $errMsg);
                    throw new \Exception($errMsg);
                }

                if ($insertData) {
                    $insertData = collect($insertData);
                    foreach ($insertData->chunk(50) as $chunk) {
                        SupplierExaminationModel::insert($chunk->toArray());
                    }
                }

                if ($updateData) {
                    $updateData = collect($updateData);
                    foreach ($updateData->chunk(50) as $chunk) {
                        foreach ($chunk->toArray() as $item) {
                            SupplierExaminationModel::where('id', $item['id'])->update($item);
                        }
                    }
                }
                return true;
            });
            return true;
        } catch (\Exception $exception) {
            return $exception->getMessage();
        } finally {
            unlink($filePath);
        }
    }

    public function checkArrAllNull($arr)
    {
        foreach ($arr as $item) {
            if ($item) {
                return false;
            }
        }

        return true;
    }

    private function checkImportCsvHeader($header)
    {
        $header = array_map(function ($value) {
            return trim($value, '*');
        }, $header);
        $validHeader = [
            '销售订单号',
            '采购订单号',
            '检货时间',
            '销售',
            '采购员',
            'A/B单',
            '供应商',
            '型号',
            '品牌',
            '数量',
            '批次',
            '产地',
            '入库日期',
            '来货单号',
            '送货单',
            '理货要求',
            '验货要求',
            '不良数',
            '异常等级',
            '不良现象',
            '检验结果',
            '备注'
        ];
        foreach ($header as $key => $item) {
            if ($key > count($validHeader) - 1) {
                continue;
            }
            if (strpos($item, $validHeader[$key]) === false) {
                return false;
            }
        }

        return true;
    }
}