<?php


namespace App\Http\Services;

use App\Http\Controllers\Filter\SkuListFilter;
use App\Model\IntracodeModel;
use App\Model\LogModel;
use App\Model\RedisModel;
use App\Model\SkuUploadLogModel;
use App\Model\SupplierChannelModel;
use App\Model\TagsModel;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

class SkuService extends BaseService
{

    const OPERATE_TYPE_PUTAWAY = 1;
    const OPERATE_TYPE_OFF_SHELVES = -1;

    const LONG_TERM_TIMESTAMP = 2051193600;

    //获取供应商列表需要统计的信息
    public function getSkuList()
    {
        $data['data']['goods_id'] = [];
        $filter = new SkuListFilter();
        $map = $filter->listFilter();
        $url = env('ES_SKU_URL', '');
        $map['show_status'] = 1;
        $map['no_rule'] = 1122;
        $return = curl($url, $map, 1);

        $data = json_decode($return, true);
        $list = [];
        if (isset($data['error_code']) && $data['error_code'] == 0) {
            $redis = new RedisModel;
            //处理供应商
            $spuRedis = Redis::connection('spu');
            foreach ($data['data']['goods_id'] as $k => $goodsId) {
                $uploadItemService = new SkuUploadItemService();
                $auditData = $uploadItemService->getSkuAuditData($data['data']['goods_id']);
                if (empty($goodsId) || $goodsId == 0) {
                    continue;
                }
                $sku = json_decode($redis->hget('sku', $goodsId), true);
                if (empty($sku)) {
                    $sku = ['goods_id' => $goodsId];
                    $list[] = $sku;
                    continue;
                }
                //赋值
                $sku['goods_id'] = $goodsId;
                $sku['update_time'] = date('Y-m-d H:i:s', $sku['update_time']);
                $sku['status_name'] = Config('field.GoodsStatus')[$sku['goods_status']];
                if (!empty($auditData[$goodsId])) {
                    $sku['audit_time'] = date('Y-m-d H:i:s', $auditData[$goodsId]['audit_time']);
                    $sku['audit_user'] = $auditData[$goodsId]['audit_name'];
                }
                //添加sku是否过期
                $sku['is_expire'] = $data['data']['status'][$goodsId] && $data['data']['status'][$goodsId] > 0 ? 0 : 1;
                $spu = json_decode($spuRedis->hget('spu', $sku['spu_id']), true);
                $sku['spu_name'] = $spu['spu_name'];
                //型号处理
                if (empty($sku['goods_name']) && !empty($spu)) {
                    $sku['goods_name'] = $spu['spu_name'];
                }
                $sku['encap'] = array_get($spu, 'encap', '');
                //制造商处理
                if (empty($sku['brand_name']) && !empty($spu)) {
                    $brand = $redis->hget('brand', $spu['brand_id']);
                    if ($brand) {
                        $sku['brand_name'] = $brand;
                    } else {
                        $brand = DB::connection('spu')->table('brand')->where('brand_id',
                            $spu['brand_id'])->lists('brand_name', 'brand_id');
                        if ($brand) {
                            $sku['brand_name'] = $brand[$spu['brand_id']];
                        }
                    }
                }
                $standardBrandId = array_get($spu, 's_brand_id');
                if ($standardBrandId) {
                    $standardBrand = $redis->hget('standard_brand', $standardBrandId);
                    $standardBrand = json_decode($standardBrand, true);
                    $sku['standard_brand_name'] = $standardBrand['brand_name'];
                }

                //获取价格
                $moqPrice = [];
                if (!empty($sku['ladder_price'])) {
                    $priceService = new PriceService();
                    $moqPrice = $priceService->getMoqPrice($sku['ladder_price']);
                    if (!is_array($sku['ladder_price'])) {
                        $sku['ladder_price'] = json_decode($sku['ladder_price'], true);
                    }
                    foreach ($sku['ladder_price'] as &$ladder) {
                        $ladder['purchases'] = $ladder['purchases'] == 0 ? $sku['moq'] : $ladder['purchases'];
                    }
                    unset($ladder);
                }
                $sku['cn_price'] = array_get($moqPrice, 'price_cn');
                $sku['us_price'] = array_get($moqPrice, 'price_us');
                //获取是否精选和标签
                $goodsTag = $this->getGoodsTag($sku['goods_id']);
                $sku['goods_label'] = array_get($goodsTag, 'goods_label', '');
                if ($this->orgId == 1) {
                    $sku['goods_label_name'] = array_get(config('field.SkuGoodsLabel'), $sku['goods_label'], '');
                } else {
                    $sku['goods_label_name'] = array_get(config('field.SkuGoodsLabelForIedge'), $sku['goods_label'], '');
                }
                $sku['tags'] = array_get($goodsTag, 'tags', []);
                if (!empty($sku['tags'])) {
                    $sku['is_prefer'] = in_array(1, $sku['tags']) ? 1 : 0;
                } else {
                    $sku['is_prefer'] = 0;
                }
                $list[] = $sku;
            }
            $intraCodeModel = new IntracodeModel();
            $encodedList = array_column($list, 'encoded');
            $encodedUsers = $intraCodeModel->getEncodedUserByEncoded($encodedList);
            $list = array_map(function ($item) use ($encodedUsers, $redis) {
                if (empty($item['goods_name'])) {
                    return $item;
                }
                $encoded = array_get($item, 'encoded', 0);
                $item['encoded_user_name'] = array_get($encodedUsers, $encoded, '');
                $item['moq'] = $item['moq'] ?: 0;
                $item['stock'] = $item['stock'] ?: 0;
                $item['cp_time'] = $item['cp_time'] ? date('Y-m-d H:i:s', $item['cp_time']) : '';
                $goodsTag = $redis->hget('goods_tag', $item['goods_id']);
                $goodsTag = $goodsTag ? json_decode($goodsTag, true) : '';
                $item['sku_tags'] = $goodsTag ? array_get($goodsTag, 'customer_tag') : '';
                //去db找出相关数据,有些数据只能去db找....
                $dbInfo = getSpuSkuDb($item['goods_id']);
                $connection = DB::connection($dbInfo["db"]);
                $table = $dbInfo['table'];
                $selectFields = ['goods_id', 'create_time', 'eccn', 'source', 'encoded', 'org_id'];
                $skuDBData = $connection->table($table)->select($selectFields)->where('goods_id', $item['goods_id'])->first();
                $skuDBData = $skuDBData ? $skuDBData : [];
                $item['source_name'] = array_get(config('field.SkuSource'), @$skuDBData['source'], '');
                $item['org_name'] = array_get(config('field.SkuOrgList'), @$skuDBData['org_id'], '');
                return $item;
            }, $list);
            $list = $this->transformInvalidSkuTag($list);
        }
        return [
            'list' => $list,
            'total' => !empty($data['data']['total']) ? $data['data']['total'] : 0
        ];
    }

    //这个是用来区分商品标签是否有效
    public function transformInvalidSkuTag($skuList)
    {
        foreach ($skuList as &$sku) {
            $validGoodsTags = TagsModel::where('tag_use', 16)->where('tag_type', 2)
                ->where('status', TagsModel::STATUS_OK)->pluck('tag_name')->toArray();
            $skuTags = !empty($sku['sku_tags']) ? explode(' ', $sku['sku_tags']) : [];
            if (empty($sku['sku_tags'])) {
                $sku['invalid_sku_tags'] = $sku['valid_sku_tags'] = '';
                continue;
            }
            $invalidSkuTags = $validSkuTags = [];
            //然后判断哪些是离职,哪些是在职的
            foreach ($skuTags as $tag) {
                if (empty($tag)) {
                    continue;
                }
                if (!in_array($tag, $validGoodsTags)) {
                    $invalidSkuTags[] = $tag;
                } else {
                    $validSkuTags[] = $tag;
                }
            }
            $sku['invalid_sku_tags'] = $invalidSkuTags ? implode(',',
                $invalidSkuTags) : '';
            $sku['valid_sku_tags'] = $validSkuTags ? implode(',',
                $validSkuTags) : '';
        }
        unset($sku);
        return $skuList;
    }

    //设置精选
    public function setPreferSku($skuIds, $prefer)
    {
        //直接操作redis的goods_tag,然后推送es的修改任务即可
        $redis = new RedisModel();
        foreach ($skuIds as $skuId) {
            $goodsTag = $redis->hget('goods_tag', $skuId);
            $goodsTag = json_decode($goodsTag, true);
            if (!empty($goodsTag)) {
                $tag = array_get($goodsTag, 'tags', []);
                $tag = $tag ?: [];
                //判断是否有精选标签(1),而且操作是取消精选
                if ($prefer == -1) {
                    if (in_array(1, $tag)) {
                        $key = array_search(1, $tag);
                        if ($key !== false) {
                            unset($goodsTag['tags'][$key]);
                        }
                    }
                } else {
                    if (!in_array(1, $tag)) {
                        $tag[] = 1;
                        $goodsTag['tags'] = $tag;
                    }
                }
                $result = $redis->hset('goods_tag', $skuId, json_encode($goodsTag));
            } else {
                //没有直接跳过
                continue;
            }
            if ($result === false) {
                return false;
            }
            $redis->lpush('update_list_sku', $skuId);
        }
        return true;
    }

    private function getGoodsTag($skuId)
    {
        $redis = new RedisModel();
        $result = $redis->hget('goods_tag', $skuId);
        return $result ? json_decode($result, true) : [];
    }

    //批量上下架队列
    public function batchOffShelfSkuQueue($data)
    {
        $conn = new AMQPStreamConnection(config('database.connections.rabbitmq2.host'),
            config('database.connections.rabbitmq2.port'),
            config('database.connections.rabbitmq2.login'),
            config('database.connections.rabbitmq2.password'));
        $channel = $conn->channel();
        $channel->queue_declare('lie_footstone_batch_downsku_queue', false, true, false, false);

        $msg = new AMQPMessage(json_encode($data),
            array('content_type' => 'text/plain'));
        $channel->basic_publish($msg, '', 'lie_footstone_batch_downsku_queue');
    }

    //批量修改内部编码
    public function batchUpdateEncodedQueue($data)
    {
        $conn = new AMQPStreamConnection(config('database.connections.rabbitmq2.host'),
            config('database.connections.rabbitmq2.port'),
            config('database.connections.rabbitmq2.login'),
            config('database.connections.rabbitmq2.password'));
        $channel = $conn->channel();
        $channel->queue_declare('lie_footstone_update_sku_info_queue', false, true, false, false);

        $msg = new AMQPMessage(json_encode($data),
            array('content_type' => 'text/plain'));
        $channel->basic_publish($msg, '', 'lie_footstone_update_sku_info_queue');
    }

    //批量修改商品信息队列
    public function batchUpdateSkuInfoQueue($data)
    {
        $conn = new AMQPStreamConnection(config('database.connections.rabbitmq2.host'),
            config('database.connections.rabbitmq2.port'),
            config('database.connections.rabbitmq2.login'),
            config('database.connections.rabbitmq2.password'));
        $channel = $conn->channel();
        $channel->queue_declare('lie_footstone_update_sku_info_queue', false, true, false, false);
        $msg = new AMQPMessage(json_encode($data),
            array('content_type' => 'text/plain'));
        $channel->basic_publish($msg, '', 'lie_footstone_update_sku_info_queue');
    }

    //批量更新sku状态,走队列的
    public function batchUpdateSkuStatus($data)
    {
        try {
            $skuIds = explode(',', $data['sku_ids']);
            //构建队列数据
            //上架
            $queueData = [];
            if ($data['operate_type'] == self::OPERATE_TYPE_PUTAWAY) {
                $queueName = 'lie_footstone_batch_upsku_queue';
                $data['cp_time'] = $data['is_long_term'] == 1 ? self::LONG_TERM_TIMESTAMP : strtotime($data['cp_time']);
                foreach ($skuIds as $skuId) {
                    $queueData[] = [
                        'sku_id' => $skuId,
                        'cp_time' => $data['cp_time'],
                    ];
                }
            } else {
                $queueName = 'lie_footstone_batch_downsku_queue';
                $queueData['down_type'] = 2;
                $queueData['data'] = $skuIds;
            }
            QueueService::publishQueueSecond($queueName, $queueData);
        } catch (\Exception $exception) {
            return $exception;
        }
        return true;
    }

    //获取第一次上传sku时间和最后一次上传sku时间
    public static function getUploadTimeBySupplierCode($supplierCode = '', $type = 'first')
    {
        if ($type == 'last') {
            $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,max(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code = ?';
        } else {
            $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,min(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code = ?';
        }

        $time = 0;
        $data = DB::connection('spu')
            ->select($rawSql, [$supplierCode]);
        foreach ($data as $item) {
            if ($item['supplier_code'] == $supplierCode) {
                $time = $item['create_time'];
            }
        }
        return $time;
    }


    //获取第一次上传sku时间和最后一次上传sku时间
    public static function getUploadTimeBySupplierCodes($supplierCodes = [], $type = 'first')
    {
        $supplierCodesTemp = array_map(function ($value) {
            return "'" . $value . "'";
        }, $supplierCodes);
        $supplierCodeInSql = implode(',', $supplierCodesTemp);
        if (empty($supplierCodeInSql)) {
            return [];
        }
        if ($type == 'last') {
            $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,max(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code IN (' . $supplierCodeInSql . ')';
        } else {
            $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,min(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code IN (' . $supplierCodeInSql . ')';
        }
        $data = DB::connection('spu')
            ->select($rawSql);
        $result = [];
        foreach ($supplierCodes as $supplierCode) {
            $result[$supplierCode] = 0;
            foreach ($data as $item) {
                if ($item['supplier_code'] == $supplierCode) {
                    $result[$supplierCode] = $item['create_time'];
                }
            }
        }
        return $result;
    }

    public function getSystemTags()
    {
        $tags = TagsModel::where('tag_use', 16)->where('tag_type', 2)->where('status', TagsModel::STATUS_OK)
            ->pluck('tag_name', 'tag_name')->toArray();
        $result = [];
        foreach ($tags as $key => $value) {
            if (empty($value)) {
                continue;
            }
            $result[] = [
                'tag_id' => $value,
                'tag_name' => $value,
            ];
        }
        return $result;
    }

    public function batchAddSkuTags($type, $supplierCode, $skuIds, $skuTags)
    {
        $skuTags = trim($skuTags, ',');
        //判断是类型1(针对商品)还是类型2(针对供应商)
        if ($type == 1) {
            $redis = new RedisModel();
            $skuIds = explode(',', $skuIds);
            $skuTags = explode(',', $skuTags);
            foreach ($skuIds as $skuId) {
                $skuId = (int)$skuId;
                $goodsTag = $redis->hget('goods_tag', $skuId);
                if ($goodsTag) {
                    $goodsTag = json_decode($goodsTag, true);
                    $goodsTag['customer_tag'] = implode(" ", $skuTags);
                } else {
                    $goodsTag = [
                        'customer_tag' => implode(" ", $skuTags),
                    ];
                }
                $redis->hset('goods_tag', $skuId, json_encode($goodsTag));
                $redis->lpush('update_list_sku', $skuId);
            }
        } else {
            $skuTags = explode(',', $skuTags);
            $data = [
                'canal' => $supplierCode,
                'customer_tag' => implode(" ", $skuTags),
            ];
            $this->batchUpdateSkuInfoQueue($data);
        }
    }

    //设置上架有效期
    public function setSupplierSkuCpTimeLimit($setType, $supplierGroup, $supplierCode, $cpTimeData)
    {
        $dayType = $cpTimeData['day_type'];
        $cpTimeDay = (int)$cpTimeData['cp_time_day'];
        $futuresDayType = $cpTimeData['futures_day_type'];
        $futuresCpTimeDay = (int)$cpTimeData['futures_cp_time_day'];
        if ($dayType == 2) {
            $cpTimeDay = -1;
        }
        if ($futuresDayType == 2) {
            $futuresCpTimeDay = -1;
        }
        $redis = new RedisModel();
        //批量设置
        if ($setType == 1) {
            $supplierIds = SupplierChannelModel::where('supplier_group', $supplierGroup)->where('is_type', 0)
                ->pluck('supplier_id')->toArray();
            $supplierIds = collect($supplierIds)->chunk(300)->toArray();
            foreach ($supplierIds as $supplierIdList) {
                $supplierIdList = array_values($supplierIdList);
                //先去批量设置过期时间限制天数
                SupplierChannelModel::whereIn('supplier_id', $supplierIdList)->update([
                    'cp_time_day' => $cpTimeDay,
                    'futures_cp_time_day' => $futuresCpTimeDay,
                ]);
                foreach ($supplierIdList as $supplierId) {
                    $ruler = $redis->hget('supplier_sku_upload_ruler_v2', $supplierId);
                    if ($ruler) {
                        $ruler = json_decode($ruler, true);
                    }
                    $ruler['upload_validity_period'] = $cpTimeDay;
                    $ruler['upload_futures_goods_validity_period'] = $futuresCpTimeDay;
                    $ruler = json_encode($ruler);
                    $redis->hset('supplier_sku_upload_ruler_v2', $supplierId, $ruler);

                }
                $cpTimeDayStr = $cpTimeDay == -1 ? '无限制' : $cpTimeDay;
                (new LogService())->BatchAddIgnoreAuditLogs($supplierIdList, LogModel::UPDATE_OPERATE, '批量配置供应商sku上架有效期', '上架有效期修改为' . $cpTimeDayStr . '天,期货有效期修改为' . $futuresCpTimeDay . '天');
            }
        }

        //单个设置
        if ($setType == 2) {
            $supplier = SupplierChannelModel::where('supplier_code', $supplierCode)->first();
            if (!empty($supplier)) {
                $supplier = $supplier->toArray();
                $supplierId = $supplier['supplier_id'];
                //先去批量设置过期时间限制天数
                SupplierChannelModel::where('supplier_id', $supplierId)->update([
                    'cp_time_day' => $cpTimeDay,
                    'futures_cp_time_day' => $futuresCpTimeDay,
                ]);
                $originDay = '[ ]';
                $originFuturesDay = '[ ]';
                $ruler = $redis->hget('supplier_sku_upload_ruler_v2', $supplierId);
                if ($ruler) {
                    $ruler = json_decode($ruler, true);
                    $originDay = array_get($ruler, 'upload_validity_period');
                    $originDay = $originDay ? $originDay . '天' : '[ ]';
                    $originFuturesDay = array_get($ruler, 'upload_futures_goods_validity_period');
                    $originFuturesDay = $originFuturesDay ? $originFuturesDay . '天' : '[ ]';
                }
                $ruler['upload_validity_period'] = $cpTimeDay;
                $ruler['upload_futures_goods_validity_period'] = $futuresCpTimeDay;
                (new SupplierService())->saveSkuCpTimeRulerToRedis($supplierId, $ruler);
                $cpTimeDay = $cpTimeDay == -1 ? '无限制' : $cpTimeDay;
                (new LogService())->AddIgnoreAuditCheckLog($supplierId, LogModel::UPDATE_OPERATE, '批量配置供应商sku上架有效期', '上架有效期修由' . $originDay . '改为' . $cpTimeDay . '天,期货有效期由' . $originFuturesDay . '改为' . $futuresCpTimeDay . '天');
            }
        }
    }

    //设置供应商相关sku的队列数据
    public function setSupplierSkuCpTimeLimitQueue($supplier)
    {

    }


    public function batchUpdateGoodsLabel($type, $supplierCode, $skuIds, $goodsLabel)
    {
        $goodsLabel = (int)$goodsLabel;
        //判断是类型1(针对商品)还是类型2(针对供应商)
        if ($type == 1) {
            self::updateGoodsLabel($skuIds, $goodsLabel);
        } else {
            $data = [
                'canal' => $supplierCode,
                'goods_label' => (int)$goodsLabel,
            ];
            $this->batchUpdateSkuInfoQueue($data);
        }
    }

    public static function updateGoodsLabel($skuIds, $goodsLabel)
    {
        if (!is_array($skuIds)) {
            $skuIds = explode(',', trim($skuIds));
        }
        $conn = new AMQPStreamConnection(config('database.connections.rabbitmqSku.host'),
            config('database.connections.rabbitmqSku.port'),
            config('database.connections.rabbitmqSku.login'),
            config('database.connections.rabbitmqSku.password'));
        foreach ($skuIds as $skuId) {
            $channel = $conn->channel();
            $channel->queue_declare('lie_footstone_update_sku_info_queue', false, true, false, false);
            if (empty($skuId)) {
                continue;
            }
            $msg = new AMQPMessage(json_encode([[
                'goods_id' => $skuId,
                'goods_label' => $goodsLabel,
            ]]),
                array('content_type' => 'text/plain'));
            $channel->basic_publish($msg, '', 'sku_update');
        }
    }
}