<?php

namespace App\Imports;

use App\Http\Controllers\CommodityController;
use App\Services\CommodityBarcodeService;
use App\Services\CommodityService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Imports\HeadingRowFormatter;

HeadingRowFormatter::default('none');
class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
{
    /**
     * @param Collection $collection
     * @return bool
     * @throws \Exception
    */
    public function collection(Collection $collection)
    {
        $row = $collection->first();
        $header = [
            "货主","SKU","商品名称","条码","数量","生产日期","失效日期","批号","唯一码"
        ];
        foreach ($header as $str){
            if (!isset($row[$str])){
                Cache::put("storeCheckingReceive",["success"=>false, "data"=>"表头不存在“".$str."”"],86400);
                return false;
            }
        }
        $owner_name = null;
        $items = [];
        $errors = [];
        $commodities = [];
        $barcodes = [];
        //去重 筛选 错误
        foreach ($collection as $index => $item){
            if (!$owner_name && $item["货主"]) $owner_name = $item["货主"];
            if (!$item["条码"] || !is_numeric($item["数量"])){
                array_push($errors,($index+2)." 行：条码或数量不存在");
                continue;
            }
            if ($item["生产日期"]){
                if (is_numeric($item["生产日期"])){
                    $diff = intval($item["生产日期"]);
                    $today=new Carbon('1900-01-01');
                    $day = $today->addDays($diff-2);
                    $item["生产日期"] = $day;
                }else{
                    if (!(strtotime($item["生产日期"]) ? true : false)){
                        array_push($errors,($index+2)." 行：生产日期格式错误");
                        continue;
                    }
                }
            }
            if ($item["失效日期"] && !(strtotime($item["失效日期"]) ? true : false)){
                if (is_numeric($item["失效日期"])){
                    $diff = intval($item["失效日期"]);
                    $today=new Carbon('1900-01-01');
                    $day = $today->addDays($diff-2);
                    $item["失效日期"] = $day;
                }else{
                    if (!(strtotime($item["失效日期"]) ? true : false)){
                        array_push($errors,($index+2)." 行：失效日期格式错误");
                        continue;
                    }
                }
            }
            $isUniqueCommodity = isset($commodities[$item["条码"]]);
            if ($isUniqueCommodity){
                $sign = false;
                foreach ($commodities[$item["条码"]] as $i){
                    $line = &$items[$i];
                    if ($line["produced_at"] == $item["生产日期"] && $line["invalid_at"] == $item["失效日期"]
                        && $line["batch_code"] == $item["批号"] && $line["unique_code"] == $item["唯一码"]) {
                        $line["imported_amount"] += $item["数量"];
                        array_push($errors, ($index + 2) . " 行：重复数据已合并数量");
                        $sign = true;
                        break;
                    }
                }
                if ($sign) continue;
            }
            array_push($items,[
                "imported_amount" => $item["数量"],
                "produced_at" => $item["生产日期"],
                "invalid_at" => $item["失效日期"],
                "batch_code" => $item["批号"],
                "unique_code" => $item["唯一码"],
                "SKU" => $item["SKU"],
                "商品名称" => $item["商品名称"],
                "条码" => $item["条码"],
            ]);
            if ($isUniqueCommodity){
                array_push($commodities[$item["条码"]], count($items)-1);
            }else{
                $commodities[$item["条码"]] = [count($items)-1] ;
                array_push($barcodes,$item["条码"]);
            }
        }

        //不存在货主
        if (!$owner_name){
            Cache::put("storeCheckingReceive",["success"=>false, "data"=>"货主为空，不允许录入，至少为一行标明货主！"],86400);
            return false;
        }
        $owner = app('OwnerService')->first(["code"=>$owner_name,"name"=>$owner_name],["name"=>"or"]);
        if (!$owner) $owner = app('OwnerService')->create(["name"=>$owner_name, "code"=>$owner_name]);

        //使用条码同步
        $commodityController = new CommodityController();
        $commodityController->syncOwnerCommodities($owner->id, $owner->code, null,$barcodes);

        //使用条码获取商品ID,筛选出需要录入条码项
        /** @var CommodityBarcodeService $commodityBarcodeService */
        $commodityBarcodeService = app('CommodityBarcodeService');
        $commodityBarCodes = $commodityBarcodeService->getCommodities($barcodes, $owner->id);
        foreach ($commodityBarCodes as $barcode){
            if(!isset($commodities[$barcode->code]))continue;
            foreach ($commodities[$barcode->code] as $index){
                $items[$index]["commodity_id"] = $barcode->commodity_id;
                unset($items[$index]["SKU"]);
                unset($items[$index]["商品名称"]);
                unset($items[$index]["条码"]);
            }
            unset($commodities[$barcode->code]);
        }

        if (count($commodities) > 0){
            //获取SKU，将已存在的商品补录条码
            $skus = [];
            $skuMap = [];
            foreach ($commodities as $arr){
                foreach ($arr as $index){
                    $item = $items[$index];
                    if ($item['SKU']){
                        $skus[] = $item['SKU'];
                        //sku对应多个条码
                        if (isset($skuMap[$item['SKU']]))$skuMap[$item['SKU']][] = $item['条码'];
                        else $skuMap[$item['SKU']] = [$item['条码']];
                    } else {
                        $skus[] = $item['条码'];
                        //sku对应多个条码
                        if (isset($skuMap[$item['条码']]))$skuMap[$item['SKU']][] = $item['条码'];
                        else $skuMap[$item['条码']] = [$item['条码']];
                    }
                }
            }
            $commoditiesTem = app('CommodityService')->get(['owner_id'=>$owner->id, 'sku'=>$skus]);

            if (count($commoditiesTem) > 0){
                $barcodes = [];
                $date = Carbon::now();
                foreach ($commoditiesTem as $item){
                    //对比本地与导入的存在商品中条码差异 补充数据库
                    foreach (array_unique(array_diff($skuMap[$item->sku], $item->barcodes->toArray())) as $code){
                        $barcodes[] = [
                            'commodity_id' => $item->id,
                            'code' => $code,
                            'created_at' => $date,
                        ];
                        foreach ($commodities[$code] as $index){
                            $items[$index]["commodity_id"] = $item->id;
                            unset($items[$index]["SKU"]);
                            unset($items[$index]["商品名称"]);
                            unset($items[$index]["条码"]);
                        }
                        unset($commodities[$code]);
                    }
                }
                if (count($barcodes) > 0){
                    $commodityBarcodeService->insert($barcodes);
                    app('LogService')->log(__METHOD__,"盘收导入补录条码",json_encode($barcodes));
                }
            }

            //WMS与本地皆不存在的商品 录入为临时商品
            if (count($commodities) > 0){
                $createCommodities = [];
                $skus = [];
                $skuMap = [];
                $date = Carbon::now()->toDateTimeString();
                foreach ($commodities as $arr){
                    foreach ($arr as $index){
                        $item = $items[$index];
                        if ($item["SKU"]) $sku = $item["SKU"];
                        else $sku = $item["条码"];

                        if (isset($skuMap[$sku])) $skuMap[$sku][] = $index;
                        else {
                            $skuMap[$sku] = [$index];
                            $skus[] = $sku;

                            $commodity = [
                                "name" => $item["商品名称"],
                                "sku" => $sku,
                                "owner_id" => $owner->id,
                                "type" => "临时",
                                "created_at" => $date,
                            ];
                            $createCommodities[] = $commodity;
                        }
                    }
                }

                //录入商品
                if (count($createCommodities) > 0){
                    /** @var CommodityService $commodityService */
                    $commodityService = app('CommodityService');
                    $commodityService->insert($createCommodities);
                    app('LogService')->log(__METHOD__,"盘收录入临时商品",json_encode($createCommodities,JSON_UNESCAPED_UNICODE));

                    //拿到商品ID录入条码
                    $barcodes = [];
                    $date = Carbon::now()->toDateTimeString();
                    $commoditiesTem = $commodityService->get(['owner_id'=>$owner->id, 'sku'=>$skus]);
                    $exist = [];
                    foreach ($commoditiesTem as $item){
                        foreach ($skuMap[$item->sku] as $index){
                            if (!isset($exist[$item->id."_".$items[$index]["条码"]])){
                                $barcodes[] = [
                                    'commodity_id' => $item->id,
                                    'code' => $items[$index]["条码"],
                                    'created_at' => $date,
                                ];
                                $exist[$item->id."_".$items[$index]["条码"]] = true;
                            }
                            $items[$index]["commodity_id"] = $item->id;
                            unset($items[$index]["SKU"]);
                            unset($items[$index]["商品名称"]);
                            unset($items[$index]["条码"]);
                        }
                    }
                    if (count($barcodes) > 0){
                        $commodityBarcodeService->insert($barcodes);
                        app('LogService')->log(__METHOD__,"盘收导入录入条码",json_encode($barcodes));
                    }
                }
            }
        }
        if (count($items) < 1){
            Cache::put("storeCheckingReceive",["success"=>false, "errors"=>$errors],86400);
            return false;
        }
        $storeCheckingReceive = app('StoreCheckingReceiveService')->create([
            "owner_id" => $owner->id,
            "created_at" => date('Y-m-d H:i:s'),
            'status' => "已导入",
        ]);
        $storeCheckingReceive->owner_name = $owner->name;

        app('LogService')->log(__METHOD__,"导入盘收任务-录入盘收任务",json_encode($storeCheckingReceive,JSON_UNESCAPED_UNICODE));
        foreach ($items as &$it){
            $it["store_checking_receive_id"] = $storeCheckingReceive->id;
        }
        app('StoreCheckingReceiveItemService')->insert($items);
        app('LogService')->log(__METHOD__,"导入盘收任务-批量录入盘收记录",json_encode($items,JSON_UNESCAPED_UNICODE));

        Cache::put("storeCheckingReceive",["success"=>true,"data"=>$storeCheckingReceive,"errors"=>$errors],86400);
        return true;
    }
}
