<?php
/**
 * 首页概况缓存
 * Created by PhpStorm.
 * User: wxj
 * Date: 2019/11/5
 * Time: 10:14
 */

namespace JinDouYun\Cache;

use http\Exception;
use JinDouYun\Dao\Customer\DCustomer;
use JinDouYun\Dao\Purchase\DSupplier;
use Mall\Framework\Cache\Redis;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Factory;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\ErrorCode;

class OverviewCache
{
    /**
     * @var Redis
     */
    private $cache;
    private $expireTime = 86400;
    private $orderDay = 7;//近7天订单趋势
    protected $aggregateStatisticsKey = 'aggregateStatistics';//总数统计 区分企业
    protected $businessOverviewEnterpriseKey = 'businessOverviewEnterprise';//经营概况_日期_企业Id_(全店)
    protected $businessOverviewEnterpriseShopKey = 'businessOverviewEnterpriseShop';//经营概况_日期_企业Id_商铺id
    protected $rankingEnterpriseKey = 'rankingEnterprise';//销量排行榜_日期_企业Id_(全店)
    protected $rankingEnterpriseShopKey = 'rankingEnterpriseShop';//销量排行榜_日期_企业Id_商铺id
    protected $salesMoneyRankingEnterpriseKey = 'salesMoneyRankingEnterprise';//销额排行榜_日期_企业Id_(全店)
    protected $salesMoneyRankingEnterpriseShopKey = 'salesMoneyRankingEnterpriseShop';//销额排行榜_日期_企业Id_商铺id
    protected $orderTrendKey = 'orderTrend';//近7天订单趋势_企业Id

    public function __construct()
    {
        $this->cache = Factory::cache('finance');
    }

    /**
     * 总数统计
     * @param $enterpriseId
     * @param string $key
     * @param $change_num
     * @return ResultWrapper
     */
    public function saveAggregateStatistics($enterpriseId, $key = 'totalShouldReceive', $change_num)
    {
        if (empty($key)) {
            return ResultWrapper::fail('要缓存的数据为空', ErrorCode::$paramError);
        }
        $new = 0;
        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->aggregateStatisticsKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        $ttl = $this->cache->ttl($Key);

//        $old = self::getAggregateStatistics($enterpriseId,$key);

        $objDCustomer = new DCustomer();
        $objDSupplier = new DSupplier();
        $objDCustomer->setTable('qianniao_customer_'.$enterpriseId);
        $objDSupplier->setTable('qianniao_supplier_'.$enterpriseId);
        if($key == 'totalShouldReceive'){
            $tmpNew = $objDCustomer->query('select sum(money) as sum from '.$objDCustomer->get_Table().' where deleteStatus = '.StatusCode::$standard.' and enableStatus = '.StatusCode::$standard);
        }
        if($key == 'totalShouldPay'){
            $tmpNew = $objDSupplier->query('select sum(money) as sum from '.$objDSupplier->get_Table().' where deleteStatus = '.StatusCode::$standard.' and enableStatus = '.StatusCode::$standard);
        }
        if(empty($tmpNew)){
            $tmpNew[0]['sum'] = 0;
        }
        $this->cache->hset($Key , $key, bcadd($new,$tmpNew[0]['sum'],2));
        //如果键没有设置,那么设置过期时间
        if ($ttl == -2) {
            $this->cache->expire($Key, $this->expireTime);
        }
    }

    /**
     * @param $enterpriseId
     * @param $key
     * @param $change_num
     */
    public function setAggregateStatistics($enterpriseId, $key, $change_num)
    {
        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->aggregateStatisticsKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        $ttl = $this->cache->ttl($Key);

        $this->cache->hset($Key , $key, $change_num);
        //如果键没有设置,那么设置过期时间
        if ($ttl == -2) {
            $this->cache->expire($Key, $this->expireTime);
        }
    }

    /**
     * 获取总数统计
     * @param $enterpriseId
     * @param $key
     * @return array
     */
    public function getAggregateStatistics($enterpriseId, $key = 'totalShouldReceive')
    {
        $Key = $this->aggregateStatisticsKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        $result = $this->cache->hget($Key, $key);
//        if(empty($result)){
//            $objDCustomer = new DCustomer();
//            $objDSupplier = new DSupplier();
//            $objDCustomer->setTable('qianniao_customer_'.$enterpriseId);
//            $objDSupplier->setTable('qianniao_supplier_'.$enterpriseId);
//            if($key = 'totalShouldReceive'){
//                $new = $objDCustomer->query('select sum(money) as sum from '.$objDCustomer->get_Table().' where deleteStatus = '.StatusCode::$standard.' and enableStatus = '.StatusCode::$standard);
//            }
//            if($key = 'totalShouldPay'){
//                $new = $objDCustomer->query('select sum(money) as sum from '.$objDSupplier->get_Table().' where deleteStatus = '.StatusCode::$standard.' and enableStatus = '.StatusCode::$standard);
//            }
//            self::setAggregateStatistics($enterpriseId,$key, $new[0]['sum']);
//        }
        return $result ? $result : 0;
    }

    /**
     * 删除总数统计
     * @param $enterpriseId
     * @param $key
     * @return array
     */
    public function delAggregateStatistics($enterpriseId, $key = 'totalShouldReceive')
    {
        $Key = $this->aggregateStatisticsKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        return $this->cache->hdel($Key, $key);
    }

    /**************************经营概况 start**********************************/
    /**
     * 经营概况
     * @param $enterpriseId
     * @param string $key
     * @param $change_num
     * @param null $shopId
     * @return ResultWrapper
     */
    public function saveBusinessOverview($enterpriseId, $key = 'orderTotalMoney', $change_num, $shopId = null)
    {
        if (empty($key)) {
            return ResultWrapper::fail('要缓存的数据为空', ErrorCode::$paramError);
        }

        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->businessOverviewEnterpriseKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->businessOverviewEnterpriseShopKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId . '::ShopId_' . $shopId;
        }

        $ttl = $this->cache->ttl($Key);

        $old = self::getBusinessOverview($enterpriseId, $key, $shopId);
        $this->cache->hset($Key, $key, $old + $change_num);

        //如果键没有设置,那么设置过期时间
        if ($ttl == -2) {
            $this->cache->expire($Key, $this->expireTime);
        }
    }

    /**
     * @param int $enterpriseId
     * @param string $key
     * @param string $change_num
     * @param null $shopId
     * @return bool
     */
    public function setBusinessOverview(int $enterpriseId,string $key,string $change_num, $shopId = null)
    {
        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->businessOverviewEnterpriseKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->businessOverviewEnterpriseShopKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId . '::ShopId_' . $shopId;
        }
        $ttl = $this->cache->ttl($Key);
        $this->cache->hset($Key, $key, $change_num);
        //如果键没有设置,那么设置过期时间
        if ($ttl == -2) {
            $this->cache->expire($Key, $this->expireTime);
        }
        return true;
    }

    /**
     * 获取经营概况数字
     * @param $enterpriseId
     * @param string $key
     * @param null $shopId
     * @return ResultWrapper
     */
    public function getBusinessOverview($enterpriseId, $key = 'totalShouldReceive', $shopId = null)
    {
        if (empty($key)) {
            return ResultWrapper::fail('要获取的key不存在', ErrorCode::$paramError);
        }

        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->businessOverviewEnterpriseKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->businessOverviewEnterpriseShopKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId . '::ShopId_' . $shopId;
        }

        $result = $this->cache->hget($Key, $key);
        return $result ? $result : 0;
    }

    /**
     * 删除经营概况统计
     * @param $enterpriseId
     * @param string $key
     * @param null $shopId
     * @return mixed
     */
    public function delBusinessOverview($enterpriseId, $key = 'totalShouldReceive', $shopId = null)
    {
        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->businessOverviewEnterpriseKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->businessOverviewEnterpriseShopKey . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId . '::ShopId_' . $shopId;
        }
        return $this->cache->hdel($Key, $key);
    }
    /**************************经营概况 end**********************************/

    /**************************销量排行榜 start**********************************/

    /**
     * 销量排行榜
     * @param $enterpriseId
     * @param string $suffix
     * @param string $id
     * @param $change_num
     * @param null $shopId
     * @return ResultWrapper
     */
    public function saveRanking($enterpriseId, $suffix = 'categoryRanking', $id, $change_num, $shopId = null)
    {
        if (empty($suffix) || empty($id)) {
            return ResultWrapper::fail('要缓存的数据为空', ErrorCode::$paramError);
        }

        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->rankingEnterpriseKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->rankingEnterpriseShopKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId.'::ShopId_'. $shopId;
        }

        $ttl = $this->cache->ttl($Key);

        $old = $this->cache->zscore($Key, $id);
        $old = $old ? $old : 0;
        $change_num = bcmul($change_num,100);
        $this->cache->zAdd($Key, bcadd($old, $change_num), $id);

        //如果键没有设置,那么设置过期时间
        if ($ttl == -2) {
            $this->cache->expire($Key, $this->expireTime);
        }
    }

    /**
     * 获取排行榜,按score从大到小排行
     * @param $enterpriseId
     * @param string $suffix
     * @param $id
     * @param $change_num
     * @param null $shopId
     * @return ResultWrapper
     */
    public function getRanking($enterpriseId, $suffix = 'categoryRanking', $shopId = null)
    {
        if (empty($suffix)) {
            return ResultWrapper::fail('要缓存的数据为空', ErrorCode::$paramError);
        }

        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->rankingEnterpriseKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->rankingEnterpriseShopKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId.'::ShopId_'. $shopId;
        }

        $result = $this->cache->zRevRange($Key, 0, -1, true);
        if(!empty($result)) {
            foreach ($result as $key=>$value) {
                if ($value) {
                    $result[$key] = bcdiv($value,100,2);
                }
            }
        }
        return $result ? $result : [];
    }

    /**
     * 删除排行榜 key
     * @param $enterpriseId
     * @param string $suffix
     * @param null $shopId
     * @return mixed
     */
    public function delRanking($enterpriseId, $suffix = 'categoryRanking', $shopId = null)
    {
        $Key = $this->rankingEnterpriseKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->rankingEnterpriseShopKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId.'::ShopId_'. $shopId;
        }
        return $this->cache->del($Key);
    }

    /**************************销量排行榜 end**********************************/

    /**************************销额排行榜 start**********************************/

    /**
     * 销额排行榜
     * @param $enterpriseId
     * @param string $suffix
     * @param string $id
     * @param $change_num
     * @param null $shopId
     * @return ResultWrapper
     */
    public function saveSalesMoneyRanking($enterpriseId, $suffix = 'categoryRanking', $id, $change_num, $shopId = null)
    {
        if (empty($suffix) || empty($id)) {
            return ResultWrapper::fail('要缓存的数据为空', ErrorCode::$paramError);
        }

        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->salesMoneyRankingEnterpriseKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->salesMoneyRankingEnterpriseShopKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId.'::ShopId_'. $shopId;
        }

        $ttl = $this->cache->ttl($Key);

        $old = $this->cache->zscore($Key, $id);
        $old = $old ? $old : 0;
        $change_num = bcmul($change_num,100);
        $this->cache->zAdd($Key, bcadd($old, $change_num), $id);

        //如果键没有设置,那么设置过期时间
        if ($ttl == -2) {
            $this->cache->expire($Key, $this->expireTime);
        }
    }

    /**
     * 获取排行榜,按score从大到小排行
     * @param $enterpriseId
     * @param string $suffix
     * @param $id
     * @param $change_num
     * @param null $shopId
     * @return ResultWrapper
     */
    public function getSalesMoneyRanking($enterpriseId, $suffix = 'categoryRanking', $shopId = null)
    {
        if (empty($suffix)) {
            return ResultWrapper::fail('要缓存的数据为空', ErrorCode::$paramError);
        }

        //获取Key的过期时间,大于0的话就不再设置了
        $Key = $this->salesMoneyRankingEnterpriseKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->salesMoneyRankingEnterpriseShopKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId.'::ShopId_'. $shopId;
        }

        $result = $this->cache->zRevRange($Key, 0, -1, true);
        if(!empty($result)) {
            foreach ($result as $key=>$value) {
                if ($value) {
                    $result[$key] = bcdiv($value,100,2);
                }
            }
        }
        return $result ? $result : [];
    }

    /**
     * 删除排行榜 key
     * @param $enterpriseId
     * @param string $suffix
     * @param null $shopId
     * @return mixed
     */
    public function delSalesMoneyRanking($enterpriseId, $suffix = 'categoryRanking', $shopId = null)
    {
        $Key = $this->salesMoneyRankingEnterpriseKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId;
        if (!empty($shopId)) {
            $Key = $this->salesMoneyRankingEnterpriseShopKey . '::' . $suffix . '::' . date('Y-m-d') . '::EnterpriseId_' . $enterpriseId.'::ShopId_'. $shopId;
        }
        return $this->cache->del($Key);
    }

    /**************************销额排行榜 end**********************************/


    /**************************近7天订单趋势 start**********************************/
    /**
     * 近7天订单趋势   订单审核后调用此方法
     * @param $enterpriseId
     * @param $orderMoney
     * @param $goodsNum 商品数量
     * @return void
     */
    public function saveOrderTrend($enterpriseId, $orderMoney, $goodsNum)
    {
        $Key = $this->orderTrendKey. '::EnterpriseId_' . $enterpriseId;

        //删除前30天的值
        $keys = $this->cache->hkeys($Key);
        if(!empty($keys)) {
            foreach ($keys as $k) {
                if(strtotime($k) <= strtotime('-30 days')) {
                    $this->cache->hdel($Key, $k);
                }
            }
        }

        //获取今天的值
        $oldValue = $this->cache->hget($Key, date('Y-m-d'));
        if(!empty($oldValue)) {
            $oldValue = json_decode($oldValue, true);
        }
        $newValue = [
            'orderMoney'=> $orderMoney + (isset($oldValue['orderMoney']) ? $oldValue['orderMoney'] : 0),
            'goodsNum'=> $goodsNum + (isset($oldValue['goodsNum']) ? $oldValue['goodsNum'] : 0),
            'orderNum'=> 1 + (isset($oldValue['orderNum']) ? $oldValue['orderNum'] : 0),
        ];
        $this->cache->hset($Key, date('Y-m-d'), json_encode($newValue));
    }

    /**
     * 获取近7天订单趋势
     * @param $enterpriseId
     * @return ResultWrapper
     */
    public function getOrderTrend($enterpriseId)
    {
        $Key = $this->orderTrendKey. '::EnterpriseId_' . $enterpriseId;
        $result = [];
        for($i=6; $i>=0; $i--) {
            $date = date('Y-m-d',strtotime("-$i days"));
            $value = $this->cache->hget($Key, $date);

            $value = empty($value) ? [] : json_decode($value, true);

            $result[] = [
                'date'       => $date,
                'orderMoney' => isset($value['orderMoney']) ? $value['orderMoney'] : 0,
                'goodsNum'   => isset($value['goodsNum']) ? $value['goodsNum'] : 0,
                'orderNum'   => isset($value['orderNum']) ? $value['orderNum'] : 0,
            ];
        }

        return $result;
    }

    /**************************近7天订单趋势 end**********************************/

    /**
     * 未出库订单总数
     * shopId为键 count为值
     * @param $enterpriseId
     * @param $shopId
     * @param $count
     * @return bool
     */
    public function setStatisticsCountInventoryOut($enterpriseId, $shopId, $count)
    {
        $key = $this->businessOverviewEnterpriseKey . '::OrderNumOfNotOutOfStock::EnterpriseId_' . $enterpriseId;
         return $this->cache->zadd($key, $count, $shopId);
    }

    public function getStatisticsCountInventoryOut($enterpriseId, $shopId)
    {
        $key = $this->businessOverviewEnterpriseKey . '::OrderNumOfNotOutOfStock::EnterpriseId_' . $enterpriseId;
        return $this->cache->zscore($key, $shopId);
    }

    public function delStatisticsCountInventoryOut($enterpriseId, $shopId)
    {
        $key = $this->businessOverviewEnterpriseKey . '::OrderNumOfNotOutOfStock::EnterpriseId_' . $enterpriseId;
        $this->cache->zrem($key, 0);
        return $this->cache->zrem($key, $shopId);

    }





















}