<?php

namespace Api\PhpUtils\Common;


class GoodsSkuId
{
    const TABLE_TAG_GENERAL = "000";//普通表 goods_sku 商品
    const TABLE_TAG_PINDAN = "001";//接龙表 pindan_goods_sku 商品

    /**
     * 生成加密后的 sku_id
     * id 非雪花算法生成的sku_id
     * category_1_id 一级分类的id，两位，不足两位在十位补零
     * category_2_id 二级分类的id，两位，不足三位在百位补零
     * goodsType 商品类型，1虚拟商品，2实体商品 占一位
     * belongType 1、（默认）第三方商品 2、自营商品 占一位
     * tableTag 数据所在表： 000: goods_sku, 001: pindan_goods_sku
     *
     * @param $id
     * @param $category1Id
     * @param $category2Id
     * @param $spuType
     * @param $goodsType
     * @param $belongType
     * @param $tableTag
     * @return string
     */
    public static function generateGoodSkuId($id, $category1Id, $category2Id, $goodsType, $belongType = 1, $tableTag = "000")
    {
        if (strlen($category1Id) == 1) {
            $category1Id = "0" . $category1Id;
        }
        if (strlen($category2Id) == 2) {
            $category2Id = "0" . $category2Id;
        }
        $idStr = $id . $category1Id . $category2Id . $goodsType . $belongType . $tableTag;
        //转62进制
        $tmp = BaseConvert::decToOther($idStr);

        $len = strlen($tmp);
        $len = $len < 6 ? 6 : $len;
        if ($len % 2 == 1) {
            $tmp = '0' . $tmp;
            $len += 1;
        }
        $tmp = str_pad(strval($tmp), $len < 6 ? 6 : $len, '0', STR_PAD_LEFT);
        $sum = 0;
        for ($i = 0; $i < $len / 2; $i++) {
            $sum *= 137;
            $sum += ord($tmp[$i]) ^ ord($tmp[$len - $i - 1]);
        }
        $code = '';
        $base = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        for ($i = 2; $i > 0; $i--) {
            $idx = $sum % 62;
            $sum = ($sum - $idx) / 62;
            $code = $base[$idx] . $code;
        }

        return $tmp . $code;
    }

    /**
     * 验证 str 是否是合法的 goods_sku_id
     * @param $str
     * @return bool
     */
    public static function validGoodSkuId($str)
    {
        $strlen = strlen($str);

        $chklen = 2;
        $code = substr($str, -$chklen);
        $str = substr($str, 0, $strlen-$chklen);
        $strlen -= $chklen;

        $base = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

        if ($strlen % 2 == 1)
        {
            $str = '0' . $str;
            $strlen += 1;
        }

        $sum = 0;
        $len = $strlen/2;

        for ($i=0; $i<$len; $i++)
        {
            $sum *= 137;
            $sum += ord($str[$i]) ^ ord($str[$strlen-$i-1]);
        }

        $ret = '';

        for ($i=$chklen; $i>0; $i--)
        {
            $idx = $sum % 62;
            $sum = ($sum-$idx) / 62;
            $ret = $base[$idx] . $ret;
        }

        return $ret === $code;
    }

    /**
     * 恢复加密前的订单号
     * @param $str
     * @return bool|int|string
     */
    public static function recoverGoodSkuId($str)
    {
        $strlen = strlen($str);

        $chklen = 2;
        $code = substr($str, -$chklen);
        $str = substr($str, 0, $strlen-$chklen);
        $strlen -= $chklen;

        $base = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

        if ($strlen % 2 == 1)
        {
            $str = '0' . $str;
            $strlen += 1;
        }

        $sum = 0;
        $len = $strlen/2;

        for ($i=0; $i<$len; $i++)
        {
            $sum *= 137;
            $sum += ord($str[$i]) ^ ord($str[$strlen-$i-1]);
        }

        $ret = '';
        for ($i=$chklen; $i>0; $i--)
        {
            $idx = $sum % 62;
            $sum = ($sum-$idx) / 62;
            $ret = $base[$idx] . $ret;
        }

        if ($ret === $code) {
            $codeLen = strlen($code);
            return BaseConvert::otherToDec($str);
        }
        return "";
    }

    /**
     * 根据skuId获取对应的参数
     * @param $goodsSkuId
     * @return array
     */
    public static function getGoodsSkuIdParams($goodsSkuId)
    {
        $goodsSkuIdNum = self::recoverGoodSkuId($goodsSkuId);
        $data = [];
        if (!empty($goodsSkuIdNum)) {
            $idgenId = substr($goodsSkuIdNum, 0, 20);
            $category1Id = substr($goodsSkuIdNum, 20, 2);
            $category2Id = substr($goodsSkuIdNum, 22, 3);
            $goodsType = substr($goodsSkuIdNum, 25, 1);
            $belongType = substr($goodsSkuIdNum, 26, 1);
            $tableTag = substr($goodsSkuIdNum, 27, 3);

            $data = [
                "idgent_id" => $idgenId,
                "category_1_id" => $category1Id,
                "category_2_id" => $category2Id,
                "goods_type" => $goodsType,
                "belong_type" => $belongType,
                "table_tag" => $tableTag,
            ];
        }
        return $data;
    }
}