<?php


namespace App\Services\goods;


use Api\PhpServices\Idgen\Idgen;
use App\Exception\custom\GoodsException;
use App\Models\goods\mysql\GoodsOperationRecord;
use App\Models\goods\mysql\GoodsSku;
use App\Models\goods\mysql\GoodsSpu;
use App\Models\goods\mysql\Shop;

class GoodsService
{
    /**
     * 通过发号器拿 id （非雪花）
     * number，获取店铺shop_id用生活号id后两位，商品相关的这里是shop_id的后两位
     * @param $number
     * @param $type
     * @param int $count
     * @return array|mixed
     */
    public static function getIdgenId($number, $type, $count = 1)
    {
        $res = Idgen::get(appConfig('idgen.partner'), appConfig('idgen.key'), [], [[
            "type" => $type,
            'number' => (int)$number,
            "count" => $count]]);
        return $res['id_datetime'][$type] ?? [];
    }

    public static function getSnowIdgenId($type, $count = 1)
    {
        $res = Idgen::get(appConfig('idgen.partner'), appConfig('idgen.key'), [[
            "type" => $type,
            "count" => $count]], []);
        return $res['id_snow'][$type] ?? [];
    }

    /**
     * 添加商品
     * @param $lifeAccountId
     * @param array $params
     * @return mixed
     * @throws GoodsException
     */
    public static function addGoods($lifeAccountId, $params = [])
    {
        //todo:: 获取 $lifeAccount信息
        $lifeAccount = [
            "life_account_id" => 111,
            "merchant_id" => 1,
            "life_account_name" => "测试测试",
        ];

        GoodsSpu::beginTransaction();

        $shopId = self::addShop($lifeAccount);

        $spuData = [
            "name" => $params["name"],
            "url" => $params["url"],
            "desc" => $params["desc"],
        ];
        $spuId = self::addGoodsSpu($shopId, $spuData);
        $skuId = self::addGoodsSku($spuId, $shopId, $lifeAccountId, $params);

        if (!GoodsSpu::commit()) {
            GoodsSpu::rollback();
            throw new GoodsException(["cus" => 0]);
        }
        return $skuId;
    }

    /**
     * 添加spu
     * @param $shopId
     * @param array $spuData
     * @return mixed
     * @throws GoodsException
     */
    private static function addGoodsSpu($shopId, $spuData = [])
    {
        $res = self::getIdgenId(substr($shopId, -2), "goods");
        if (empty($res)) {
            throw new GoodsException(['cus' => 2]);
        }
        $spuId = $res[0];
        GoodsSpu::save([
            "goods_spu_id" => $spuId,
            "shop_id" => $shopId,
            "name" => $spuData["name"],
            "url" => $spuData["url"],
            "desc" => $spuData["desc"],
        ]);
        return $spuId;
    }

    /**
     * 添加sku
     * @param $spuId
     * @param $shopId
     * @param $lifeAccountId
     * @param array $skuData
     * @return mixed
     * @throws GoodsException
     */
    private static function addGoodsSku($spuId, $shopId, $lifeAccountId, $skuData = [])
    {
        $res = self::getIdgenId(substr($shopId, -2), "goods");
        if (empty($res)) {
            throw new GoodsException(['cus' => 2]);
        }
        $skuId = $res[0];
        GoodsSku::save([
            "goods_spu_id" => $spuId,
            "goods_sku_id" => $skuId,
            "shop_id" => $shopId,
            "life_account_id" => $lifeAccountId,
            "category_1_id" => $skuData["category_1_id"],
            "category_2_id" => $skuData["category_2_id"],
            "name" => $skuData["name"],
            "url" => $skuData["url"],
            "desc" => $skuData["desc"],
            "expiration_time" => $skuData["expiration_time"],
            "rule_limit" => $skuData["rule_limit"],
            "rule_date_type" => $skuData["rule_date_type"],
            "rule_start_time" => $skuData["rule_start_time"],
            "rule_end_time" => $skuData["rule_end_time"],
            "rule_desc" => $skuData["rule_desc"],
            "inventory_total" => $skuData["inventory_total"],
            "original_price" => $skuData["original_price"],
            "price" => $skuData["price"],
        ]);
        return $skuId;
    }

    /**
     * 添加商铺
     * @param $lifeAccount
     * @return mixed
     * @throws GoodsException
     */
    private static function addShop($lifeAccount)
    {
        $lifeAccountId = $lifeAccount["life_account_id"];
        $shop = Shop::getRecordMaster(['life_account_id' => $lifeAccountId]);

        if (empty($shop)) {
            $res = self::getIdgenId(substr($lifeAccountId, -2), "goods");
            if (empty($res)) {
                throw new GoodsException(['cus' => 1]);
            }
            $shopId = $res[0];
            Shop::save([
                "shop_id" => $shopId,
                "life_account_id" => $lifeAccountId,
                "merchant_id" => $lifeAccount["merchant_id"],
                "name" => $lifeAccount["life_account_name"],
                "status" => Shop::STATUS_ONLINE,
            ]);
        } else {
            $shopId = $shop[0]["shop_id"];
        }
        return $shopId;
    }

    /**
     * 审核
     * @param array $params
     * @return bool
     * @throws GoodsException
     */
    public static function audit($params = [])
    {
        $goodsSpuId = $params["goods_spu_id"];
        $status = $params["status"];
        $operatorId = $params["uid"];
        $operatorName = $params["username"];

        $goodsSpu = GoodsSpu::get("*", ["goods_spu_id" => $goodsSpuId]);
        //todo::权限判断 商品所属 life_account_id 或者 后台管理员
        //权限判断
        if (!empty($params["life_account_id"]) && $goodsSpu["life_account_id"] != $params["life_account_id"]) {
            throw new GoodsException(["cus" => 13]);
        }

        //审核状态是否正确
        if (!in_array($status, [GoodsSku::STATUS_PASS, GoodsSku::STATUS_REJECT])) {
            throw new GoodsException(["cus" => 12]);
        }
        //驳回时候要有原因
        if ($status == GoodsSku::STATUS_REJECT && empty($params["rejected_reason"])) {
            throw new GoodsException(["cus" => 9]);
        }

        GoodsSku::beginTransaction();
        $goodsSkuList = GoodsSku::select("*", ["goods_spu_id" => $goodsSpuId]);
        if (!empty($goodsSkuList)) {
            foreach ($goodsSkuList as $sku) {
                if ($sku["status"] == GoodsSku::STATUS_PASS || $sku["status"] == GoodsSku::STATUS_REJECT) {
                    throw new GoodsException(["cus" => 10]);
                }
                $goodsSkuId = $sku["goods_sku_id"];
                GoodsSku::save(["status" => $status], ["goods_sku_id" => $sku["goods_sku_id"]]);

                //todo:: info to es
                //商品操作记录
                $res = self::getSnowIdgenId("goods");
                if (empty($res)) {
                    throw new GoodsException(['cus' => 2]);
                }
                $record = [
                    "goods_operation_record_id" => $res[0],
                    "goods_spu_id" => $goodsSpuId,
                    "goods_sku_id" => $goodsSkuId,
                    "operator_id" => $operatorId,
                    "operator_name" => $operatorName,
                    "goods_status" => $status,
                    "online_status" => $sku["online_status"],
                    "before_version" => $sku["version"],
                    "after_version" => $sku["version"],
                    "note" => empty($params["rejected_reason"]) ? "" : $params["rejected_reason"],
                ];
                GoodsOperationRecord::insertRecord($record);
            }
        }
        if (!GoodsSku::commit()) {
            GoodsSku::rollback();
            throw new GoodsException(["cus" => 11]);
        }
        return true;
    }

    /**
     * 上下架
     * @param $params
     * @return bool
     * @throws GoodsException
     */
    public static function onlineOrOffline($params)
    {
        $goodsSpuId = $params["goods_spu_id"];
        $onlineStatus = $params["online_status"];
        $operatorId = $params["uid"];
        $operatorName = $params["username"];

        $goodsSpu = GoodsSpu::get("*", ["goods_spu_id" => $goodsSpuId]);
        //todo::权限判断 商品所属 life_account_id 或者 后台管理员
        //权限判断
        if (!empty($params["life_account_id"]) && $goodsSpu["life_account_id"] != $params["life_account_id"]) {
            throw new GoodsException(["cus" => 13]);
        }

        //审核状态是否正确
        if (!in_array($onlineStatus, [GoodsSku::ONLINE_STATUS_ONLINE, GoodsSku::ONLINE_STATUS_OFFLINE])) {
            throw new GoodsException(["cus" => 12]);
        }

        GoodsSku::beginTransaction();
        $goodsSkuList = GoodsSku::select("*", ["goods_spu_id" => $goodsSpuId]);
        if (!empty($goodsSkuList)) {
            foreach ($goodsSkuList as $sku) {
                if ($sku["status"] != GoodsSku::STATUS_PASS) {
                    throw new GoodsException(["cus" => 14]);
                }
                $goodsSkuId = $sku["goods_sku_id"];
                GoodsSku::save(["online_status" => $onlineStatus], ["goods_sku_id" => $goodsSkuId]);

                //todo:: info to es
                //商品操作记录
                $res = self::getSnowIdgenId("goods");
                if (empty($res)) {
                    throw new GoodsException(['cus' => 2]);
                }
                $record = [
                    "goods_operation_record_id" => $res[0],
                    "goods_spu_id" => $goodsSpuId,
                    "goods_sku_id" => $goodsSkuId,
                    "operator_id" => $operatorId,
                    "operator_name" => $operatorName,
                    "goods_status" => $sku["status"],
                    "online_status" => $onlineStatus,
                    "before_version" => $sku["version"],
                    "after_version" => $sku["version"],
                    "note" => empty($params["rejected_reason"]) ? "" : $params["rejected_reason"],
                ];
                GoodsOperationRecord::insertRecord($record);
            }
        }
        if (!GoodsSku::commit()) {
            GoodsSku::rollback();
            throw new GoodsException(["cus" => 11]);
        }
        return true;
    }

    public static function checkGoodsName($goodsName)
    {

    }
}