<?php

namespace App\Services;

use App\Services\common\BatchUpdateService;
use App\Services\common\DataHandlerService;
use App\Store;
use App\StoreItems;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

Class StoreItemService
{
    public function insert(array $params)
    {
        return StoreItems::query()->insert($params);
    }

    public function storeItemCreateByWms($asnHerders)
    {
        if ($asnHerders->isEmpty()) return null;
        $asnDetails = $this->getAsnDetailsByAsnHerder($asnHerders);
        $this->createStoreItem($asnDetails);
    }

    public function storeItemUpdateByWms($asnHerders)
    {
        if ($asnHerders->isEmpty()) return null;
        $asnDetails = $this->getAsnDetailsByAsnHerder($asnHerders);
        $this->updateStoreItem($asnDetails);
    }

    public function getAsnDetailsByAsnHerder($asnHerders)
    {
        $asnDetails = collect();
        $asnHerders->each(function ($asnHeader) use ($asnDetails) {
            $asnHeader->asnDetails->each(function ($asnDetail) use ($asnDetails) {
                $asnDetails->add($asnDetail);
            });
        });
        return $asnDetails;
    }

    public function createStoreItem($asnDetails)
    {
        if ($asnDetails->isEmpty()) return null;
        ini_set('memory_limit','512M');
        $stores = Store::query()->whereIn('asn_code', array_unique(data_get($asnDetails, '*.asnno')))->get();
        $store_asn_code_map = [];
        foreach ($stores as $store) {
            $store_asn_code_map[$store->asn_code] = $store;
        }
        $params = $this->getParamsByAsnDetails($asnDetails, $store_asn_code_map);
        if (count($params) > 0) {
                $this->insertStoreItem($params);
        }
    }

    public function getParamsByAsnDetails($asnDetails, $store_asn_code_map)
    {
        /** @var DataHandlerService $dataHandlerService */
        $dataHandlerService = app(DataHandlerService::class);
        $storeItems = $this->getByWms($asnDetails);
        $storeItem_map = $dataHandlerService->dataHeader(['store_asn_code', 'asn_line_code', 'sku'], $storeItems);
        $params = [];
        foreach ($asnDetails as $asnDetail) {
            $storeItem = $dataHandlerService
                ->getKeyValue(['store_asn_code' => $asnDetail->asnno, 'asn_line_code' => $asnDetail->asnlineno, 'sku' => $asnDetail->sku], $storeItem_map);
            if ($storeItem ?? false) continue;
            $params[] = [
                'store_id' => $store_asn_code_map[$asnDetail->asnno]['id'],
                'asn_line_code' => $asnDetail->asnlineno,
                'name' => $asnDetail->skudescrc,
                'sku' => $asnDetail->sku,
                'barcode' => $asnDetail->basSku ? $asnDetail->basSku->alternate_sku1 : '',
                'amount' => $asnDetail->receivedqty ?? 0,
                'quality' => $asnDetail->qualityStatus ? $asnDetail->qualityStatus->codename_c : '',
                'status' => $asnDetail->lineStatus ? $asnDetail->lineStatus->codename_c : '',
                'created_at' => $asnDetail->addtime ?? null,
                'updated_at' => $asnDetail->edittime ?? null,
            ];
        }
        return $params;
    }

    public function insertStoreItem(array $params)
    {
        if (count($params) === 0) return [];
        try {
            $this->insert($params);
            LogService::log(__METHOD__, __FUNCTION__, '批量创建 store_item success' . count($params) . json_encode($params));
        } catch (\Exception $e) {
            LogService::log(__METHOD__, __FUNCTION__, '批量创建 store_item error' . json_encode($params) . '||' . $e->getMessage() . '||' . $e->getTraceAsString());
        }
    }

    public function updateStoreItem($asnDetails)
    {
        if (!$asnDetails || $asnDetails->count() == 0) {
            return null;
        }
        /** @var DataHandlerService $dataHandlerService */
        $dataHandlerService = app(DataHandlerService::class);
        $storeItems = $this->getByWms($asnDetails);
        $asnDetails_map = $dataHandlerService->dataHeader(['asnno', 'asnlineno', 'sku'], $asnDetails);
        $updateParams = [[
           /* 'id',*/ 'store_id', 'asn_line_code', 'name', 'sku', 'barcode', 'amount', 'quality', 'status', 'created_at', 'updated_at'
        ]];
        $delete_storeItems = [];
        foreach ($storeItems as $storeItem) {
            $asnDetail = $dataHandlerService
                ->getKeyValue(['asnno' => $storeItem->store_asn_code, 'asnlineno' => $storeItem->asn_line_code, 'sku' => $storeItem->sku], $asnDetails_map);
            if (!$asnDetail) {
                array_push($delete_storeItems, $storeItem);
                continue;
            }
            if ($storeItem->asn_line_code != $asnDetail['asnlineno'] ||
                $storeItem->name != $asnDetail['skudescrc'] ||
                $storeItem->sku != $asnDetail['sku'] ||
                $storeItem->barcode != $asnDetail['basSku']['alternate_sku1'] ||
                $storeItem->amount != $asnDetail['receivedqty'] ||
                $storeItem->quality != $asnDetail['qualityStatus'] ?? $asnDetail['qualityStatus']['codename_c'] ||
                $storeItem->status != $asnDetail['lineStatus'] ?? $asnDetail['lineStatus']['codename_c'] ||
                $storeItem->created_at != $asnDetail['addtime'] ||
                $storeItem->updated_at != $asnDetail['edittime']) {
                $updateParams[] = [
                   /* 'id' => $storeItem->id,*/
                    'store_id' => $storeItem->store->id,
                    'asn_line_code' => $asnDetail['asnlineno'],
                    'name' => $asnDetail['skudescrc'],
                    'sku' => $asnDetail['sku'],
                    'barcode' => $asnDetail['basSku'] ? $asnDetail['basSku']['alternate_sku1'] : '',
                    'amount' => $asnDetail['receivedqty'] ?? 0,
                    'quality' => $asnDetail['qualityStatus'] ? $asnDetail['qualityStatus']['codename_c'] : '',
                    'status' => $asnDetail['lineStatus'] ? $asnDetail['lineStatus']['codename_c'] : '',
                    'created_at' => $asnDetail['addtime'] ?? null,
                    'updated_at' => $asnDetail['edittime'],
                ];
            }
        }
        if (count($updateParams) > 1) {
            $this->batchUpdate($updateParams);
        }
        if (count($delete_storeItems) > 0) $this->deleteStoreItem($delete_storeItems);
        unset($updateParams, $asnDetails, $delete_storeItems);
    }

    public function batchUpdate($params)
    {
        return app(BatchUpdateService::class)->batchUpdate('store_items', $params);
    }

    public function getByWms($asnDetails)
    {
        if (!$asnDetails) {
            return null;
        }
        return StoreItems::query()->with('store')->whereHas('store', function ($query) use ($asnDetails) {
            $query->whereIn('asn_code', array_unique(data_get($asnDetails, '*.asnno')));
        })->get();
    }

    public function deleteStoreItem(array $delete_storeItems)
    {
        $storeItemIds = [];
        foreach ($delete_storeItems as $delete_storeItem) {
            array_push($storeItemIds, $delete_storeItem->id);
        }
        try {
            StoreItems::query()->whereIn('id', $storeItemIds)->delete();
            LogService::log(__METHOD__, __FUNCTION__, '删除多余StoreItems ' . count($delete_storeItems) . json_encode($delete_storeItems), null);
        } catch (\Exception $e) {
            LogService::log(__METHOD__, __FUNCTION__, '删除多余StoreItems error' . count($delete_storeItems) . json_encode($delete_storeItems) . $e->getMessage() . $e->getTraceAsString(), null);
        }
    }
}
