<?php
/**
 * Created by PhpStorm.
 * User: XiaoMing
 * Date: 2020/3/19
 * Time: 12:16
 */

namespace JinDouYun\Model\System;

use JinDouYun\Cache\PageCache;
use JinDouYun\Controller\Common\Logger;
use JinDouYun\Dao\Market\DUserCoupon;
use JinDouYun\Dao\System\DPage;

use JinDouYun\Dao\System\DPageDefault;
use JinDouYun\Model\Customer\MCustomer;
use JinDouYun\Model\Goods\MGoods;
use JinDouYun\Model\Market\MActivity;
use JinDouYun\Model\Market\MCoupon;
use JinDouYun\Model\Merchant\MMerchant;
use JinDouYun\Model\Shop\MShop;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\StatusCode;

class MPage
{
    private $objDPage;

    private $onlineEnterpriseId;

    private $onlineUserId;

    private $areaCode;

    private $shopId;

    /**
     * MPage constructor.
     * @param $onlineUserId
     * @param $enterpriseId
     * @param null $areaCode
     * @throws \Exception
     */
    public function __construct($onlineUserId, $enterpriseId, $areaCode = null)
    {
        $this->onlineUserId = $onlineUserId;
        $this->onlineEnterpriseId = $enterpriseId;
        $this->areaCode = $areaCode;
        $this->objDPage = new DPage('default');
        $this->objDPage->setTable($this->objDPage->get_Table() . '_' . $this->onlineEnterpriseId);
        self::__initDefaultPage();
        self::__initEnablePage();
    }

    /**
     * 1.初始化默认模版
     */
    private function __initDefaultPage()
    {
        //查询是否有默认的模版
        $dbResult = $this->objDPage->get(['pageType' => StatusCode::$pageType['home'], 'isDefault' => StatusCode::$standard]);
        if (!empty($dbResult)) {
            return;
        }
        $objDPageDefault = new DPageDefault();//系统默认模版表
        $default = $objDPageDefault->get([
            'deleteStatus' => StatusCode::$standard,
            'enableStatus' => StatusCode::$standard,
            'isDefault'    => StatusCode::$standard,
            'pageType'     => StatusCode::$pageType['home']
        ]);
        if (empty($default)) {
            return;
        }
        $this->objDPage->insert([
            'pageType'     => $default['pageType'],
            'pageName'     => $default['pageName'],
            'pageData'     => $default['pageData'],
            'deleteStatus' => $default['deleteStatus'],
            'isDefault'    => $default['isDefault'],
            'enableStatus' => StatusCode::$delete,
        ]);
    }

    /**
     * 2.是否有已启用的模版,没有则启用系统默认模版
     */
    private function __initEnablePage()
    {
        //查询是否有已启用的模版,没有则启用系统默认模版
        $enablePage = $this->objDPage->get([
            'deleteStatus' => StatusCode::$standard,
            'enableStatus' => StatusCode::$standard,
            'pageType'     => StatusCode::$pageType['home'],
            'shopId'       => 0,
        ]);
        if (!empty($enablePage)) {
            return;
        }
        //没有启用的模版,更新默认模版的启用状态
        $this->objDPage->update(['enableStatus' => StatusCode::$standard], ['isDefault' => StatusCode::$standard,'shopId' => 0, 'pageType' => StatusCode::$pageType['home']]);
    }

    /**
     * 保存页面
     *
     * @param $params
     * @param bool $isStore
     * @param $shopId
     * @return ResultWrapper
     */
    public function save($params,bool $isStore,$shopId)
    {
        if ($isStore === true){
            $objMMerchant = new MMerchant($this->onlineEnterpriseId,$this->onlineUserId);
            $merchResult = $objMMerchant->getMerchByShopId($shopId);
            if (!$merchResult->isSuccess()){
                return ResultWrapper::fail($merchResult->getData(),$merchResult->getErrorCode());
            }
            $merch = $merchResult->getData();
            $params['shopId'] = $shopId;
            $params['merchantId'] = $merch['merchantId'];
        }
        if (isset($params['id'])) {
            $dbResult = $this->objDPage->get(['id' => $params['id']]);
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
            }
            if ($dbResult['isDefault'] == StatusCode::$standard) {
                $params['isDefault'] = StatusCode::$standard;
            }
            $params['enableStatus'] = $dbResult['enableStatus'];//启用状态
        }
        if (!isset($params['id'])) {
            $params['enableStatus'] = StatusCode::$delete;
        }
        $dbResult = $this->objDPage->replace($params);
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 获取页面详情
     *
     * @param $id
     * @return ResultWrapper
     */
    public function getPageInfo($id)
    {
        $dbResult = $this->objDPage->get(['id' => $id], 'id,pageType,pageName,pageData,enableStatus');
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        if (!empty($dbResult['pageData'])) $dbResult['pageData'] = json_decode($dbResult['pageData'], true);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 启用页面/禁用页面
     *
     * @param $params
     * @return ResultWrapper
     */
    public function updateEnableStatus($params)
    {
        $dbResult = $this->objDPage->get(['id' => $params['id']]);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        }
        //专题活动可以启用多个
        if ($dbResult['pageType'] != StatusCode::$pageType['special']) {
            //如果是启用操作，先禁用相同类型的已启用的，在启用当前的
            if ($params['enableStatus'] == StatusCode::$standard) {
                $condition = [
                    'enableStatus' => StatusCode::$standard,
                    'deleteStatus' => StatusCode::$standard,
                    'pageType' => $dbResult['pageType']
                    ];
                $dbResult = $this->objDPage->update(['enableStatus' => StatusCode::$delete],$condition);
                if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
            }
        }
       
        $dbResult = $this->objDPage->update(['enableStatus' => $params['enableStatus']], $params['id']);
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 删除页面
     *
     * @param $id
     * @return ResultWrapper
     */
    public function del($id)
    {
        $dbResult = $this->objDPage->get(['id' => $id]);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        }
        if ($dbResult['isDefault'] == StatusCode::$standard) {
            return ResultWrapper::fail('系统模版模版不能删除', ErrorCode::$paramError);
        }
        $dbResult = $this->objDPage->update(['deleteStatus' => StatusCode::$delete], $id);
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 获取页面列表
     *
     * @param $selectParams
     * @return ResultWrapper
     */
    public function getAll($selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $selectParams['deleteStatus'] = StatusCode::$standard;
        $dbResult = $this->objDPage->select($selectParams, 'id,pageType,pageName,enableStatus,isDefault', 'createTime DESC', $limit, $offset);
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        $total = $this->objDPage->count($selectParams);
        $return = [
            'data'  => $dbResult,
            'total' => ($total) ? intval($total) : 0,
        ];
        return ResultWrapper::success($return);
    }


    /**
     * 获取app首页
     *
     * @return ResultWrapper
     * @throws \Exception
     * @param int $pageType
     *
     */
    public function home($pageType = 1,$shopId = null)
    {
        $dbResult = $this->objDPage->get_field('pageData',
            [
                'deleteStatus' => StatusCode::$standard,
                'pageType'     => $pageType,
                'enableStatus' => StatusCode::$standard,
                'shopId'       => 0
            ]
        );
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        $items = empty($dbResult) ? [] : json_decode($dbResult, true);
        foreach ($items as $key => &$item) {
            $setting = $item['modelData'];//模块配置信息
            switch ($item['comName']){
                case 'GoodsGroup':
                    // 获取商品组模块数据 goodsFrom =1 自动获取 2手动选择
                    if ($setting['navStyle'] == 2) {
                        foreach ($setting['tabList'] as $index => &$val) {
                            $item['modelData']['tabList'][$index]['data'] = ($val['goodsFrom'] == 1) ? self::goodsModule($val) : self::checkGoods($val['goods_ids']);// 根据商品的id或信息检索商品数据
                        }
                        
                    } else {
                        $items[$key]['data'] = $setting['goodsFrom'] == 1 ? self::goodsModule($setting) : self::checkGoods($item['modelData']['goods_ids']); // 根据商品的id或信息检索商品数据
                    }
                    
                    break;
                case 'CouponGroup':
                    //获取优惠券模块数据
                    $items[$key]['data'] = self::couponModule($setting);
                    break;
                case 'LimitedSeckill':
                    //获取秒杀商品模块数据
                    $items[$key]['data'] = self::secKillModule($setting);
                    break;
                case 'Notice':
                    //获取公告数据
                    $items[$key]['data'] = self::noticeModule(['type'=>StatusCode::$standard]);
                    break;
            }
        }
        return ResultWrapper::success($items);
    }
    
    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/29
     * Time: 10:14 上午
     * @param $merchantId
     * @param $pageType
     * @return ResultWrapper
     * @throws \Exception
     */
    public function shopHome($merchantId,$pageType)
    {
        $dbResult = $this->objDPage->get(
            [
                'deleteStatus' => StatusCode::$standard,
                'pageType'     => $pageType,
                'enableStatus' => StatusCode::$standard,
                'merchantId'       => $merchantId
            ],'pageData,shopId'
        );
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        $shopId = getArrayItem($dbResult,'shopId',0);
        $items = empty($dbResult['pageData']) ? [] : json_decode($dbResult['pageData'],true);
        foreach ($items as $key => &$item) {
            $setting = $item['modelData'];
            switch ($item['comName']){
                case 'GoodsGroup':
                    //获取商品组模块数据
                    if ($setting['navStyle'] == 2) {
                        foreach ($setting['tabList'] as $index => &$val) {
                            $item['modelData']['tabList'][$index]['data'] = ($val['goodsFrom'] == 1) ? self::goodsModule($val,$shopId) : self::checkGoods($val['goods_ids'],$shopId);
                        }
                    } else {
                        $items[$key]['data'] = $setting['goodsFrom'] == 1 ? self::goodsModule($setting,$shopId) : self::checkGoods($item['modelData']['goods_ids'],$shopId);
                    }
                    break;
                case 'CouponGroup':
                    //获取优惠券模块数据
                    $items[$key]['data'] = self::couponModule($setting);
                    break;
                case 'LimitedSeckill':
                    //获取秒杀商品模块数据
                    $items[$key]['data'] = self::secKillModule($setting);
                    break;
                case 'Notice':
                    //获取公告数据
                    $items[$key]['data'] = self::noticeModule($setting);
                    break;
            }
        }
        return ResultWrapper::success($items);
    }

    /**
     * 检测商品
     *
     * @param $goodsIds
     * @param int $shopId
     * @return array
     * @throws \Exception
     */
    private function checkGoods($goodsIds,$shopId = 0)
    {
        $objMGoods = new MGoods($this->onlineEnterpriseId, true, $this->onlineUserId);
        $pageParams = pageToOffset(1, 100);
        $selectParams = [
            'limit'        => $pageParams['limit'],
            'offset'       => $pageParams['offset'],
            'userCenterId' => $this->onlineUserId,
            'goodsIds'     => $goodsIds,
            'areaCode'     => $this->areaCode,
            'shopId'       => $this->shopId
        ];
        if (isset($shopId) && !empty($shopId)){
            $selectParams['shopId'] = $shopId;
        }
        // 根据MD5查询需要的数据
        $md5Key = md5(json_encode($selectParams));
        $objPageCache = new PageCache();
        $goodsCacheData = $objPageCache->getPage($md5Key);
        if(!empty($goodsCacheData)){
            return self::formatGoods($goodsCacheData);
        }
        
        $result = $objMGoods->search($selectParams);
        if (!$result->isSuccess()) return [];
        $goodsData = $result->getData()['data'];
        // 写入缓存
        $objPageCache->addPage($md5Key,$goodsData);
        return self::formatGoods($goodsData);
    }

    /**
     * 市场价格
     * @param array $data
     * @return array
     */
    private function formatGoods($data)
    {
        if (empty($data)){
            return $data;
        }

        foreach ($data as $key => $value){
            if (isset($value['salePrice'])){
                continue;
            }
            $data[$key]['salePrice'] = isset($value['minSalePrice']) ? $value['minSalePrice'] : '0.00';
        }

        return $data;
    }


    /**
     * 获取开启的一条公告
     * @param $params
     * @return array|mixed
     */
    private function noticeModule($params)
    {
        $objMAnnouncement = new MAnnouncement($this->onlineEnterpriseId);
        $notice = $objMAnnouncement->getAnnouncement($params);
        if (!$notice->isSuccess()) {
            return (object)[];
        }
        return empty($notice->getData()) ? (object) [] : $notice->getData();
    }

    /**
     * 商品模块数据
     *
     * @param $params
     * @return array
     * @throws \Exception
     */
    private function goodsModule($params,$shopId = 0)
    {
        
        $objMGoods = new MGoods($this->onlineEnterpriseId, true, $this->onlineUserId);
        $pageParams = pageToOffset(1, isset($params['goodsNum']) ? $params['goodsNum'] : 10);
        $selectParams = [
            //'categoryId'   => isset($params['categoryPath'][0]) ? $params['categoryPath'][0] : '',
            'categoryPath'   => isset($params['categoryPath']) ? $params['categoryPath'] : [],
            'limit'        => $pageParams['limit'],
            'offset'       => $pageParams['offset'],
            'userCenterId' => $this->onlineUserId,
            'areaCode'     => $this->areaCode,
            'shopId' => $this->shopId
        ];
        if (isset($shopId) && !empty($shopId)){
            $selectParams['shopId'] = $shopId;
        }
        // 根据MD5查询需要的数据
        $md5Key = md5(json_encode($selectParams));
        $objPageCache = new PageCache();
        $goodsCacheData = $objPageCache->getPage($md5Key);
        if(!empty($goodsCacheData)){
            return self::formatGoods($goodsCacheData);
        }
        $result = $objMGoods->search($selectParams);
        if (!$result->isSuccess()) return [];
        $goodsData = $result->getData();
        $goodsData = isset($goodsData['data']) ? $goodsData['data'] : [];
        // 写入缓存
        $objPageCache->addPage($md5Key,$goodsData);
        return self::formatGoods($goodsData);
    }


    /**
     * 优惠券列表
     *
     * @param $params
     * @return array|ResultWrapper|mixed
     * @throws \Exception
     */
    private function couponModule($params)
    {
        $objMCoupon = new MCoupon($this->onlineUserId, $this->onlineEnterpriseId);
        $paramsData = [
            'grantType' => StatusCode::$grantType['receive'],
        ];
        $dbResult = $objMCoupon->couponList($paramsData);
        if (!$dbResult->isSuccess()) {
            return [];
        }
        $coupon = $dbResult->getData();
        if (!empty($this->onlineUserId)) {
            //用户已经登录,删除其中已经领取过的:
            $objDUserCoupon = new DUserCoupon();
            $sql = 'SELECT couponId,count(`id`) as num FROM qianniao_user_coupon_' . $this->onlineEnterpriseId . ' WHERE userId=' . $this->onlineUserId . ' GROUP BY couponId';
            $countCoupon = $objDUserCoupon->query($sql);
            if ($countCoupon === false) {
                return $coupon;
            }
            $groupNum = [];//优惠券对应领取数量
            if (!empty($countCoupon)) {
                foreach ($countCoupon as $count) {
                    $groupNum[$count['couponId']] = $count['num'];
                }
            }
            foreach ($coupon as $key => $val) {
                $haveNum = isset($groupNum[$val['id']]) ? $groupNum[$val['id']] : 0;
                if ($haveNum >= $val['allowNum']) {
                    //领取达到了上限
                    unset($coupon[$key]);
                    continue;
                }
            }
        }
        $coupon = array_slice($coupon, 0, $params['couponNum']);
        return $coupon;
    }

    /**
     * 秒杀商品数据
     *
     * @param $params
     * @return array
     * @throws \Exception
     */
    private function secKillModule($params)
    {
        if (empty($params['seckill_id'])) {
            return [];
        }

        $objMActivity = new MActivity($this->onlineUserId, $this->onlineEnterpriseId, $this->areaCode);
        $dbResult = $objMActivity->getInfo($params['seckill_id']);
        if (!$dbResult->isSuccess()) {
            return [];
        }
        $skillGoods = $dbResult->getData();

        //没有活动
        if (empty($skillGoods)){
            return [];
        }

        // 判断秒杀活动是否审核通过
        if (isset($skillGoods['auditStatus']) && $skillGoods['auditStatus'] != StatusCode::$auditStatus['auditPass']) {
            return [];
        }

        if ($skillGoods['enableStatus'] == StatusCode::$delete) {
            //此活动已下架
            return [];
        }


        //获取用户类型
        $customerType = null;
        if (!empty($this->onlineUserId)) {
            $objMCustomer = new MCustomer($this->onlineEnterpriseId, $this->onlineUserId);
            $customer = $objMCustomer->getCustomerInfoByUserCenterId($this->onlineUserId);
            if (!$customer->isSuccess()) {
                $customerType = null;
            } else {
                $customer = $customer->getData();
                $customerType = isset($customer['type']) ? $customer['type'] : null;
            }
        }

        //如果客户类型和活动不符合
        if ($skillGoods['customerRange'] == StatusCode::$delete) {
            if (empty($customerType)) {
                return [];
            }
            //客户类型
            $mapping = explode(',', trim($skillGoods['customerSourceId'], ','));
            if (!in_array($customerType, $mapping)) {
                return [];
            }
        }

        $skillGoods['inActivity'] = StatusCode::$standard;
        $skillGoods['msg'] = '活动进行中';
        if (!isset($skillGoods['startTime']) || !isset($skillGoods['endTime'])) {
            return [];
        }

        if ($skillGoods['startTime'] > time()) {
            $skillGoods['activityGoods'] = [];//删除商品
            $skillGoods['msg'] = '活动暂未开始';
            $skillGoods['inActivity'] = StatusCode::$delete;
        } elseif ($skillGoods['endTime'] < time()) {
            $skillGoods['activityGoods'] = [];//删除商品
            $skillGoods['msg'] = '活动已结束';
            $skillGoods['inActivity'] = StatusCode::$delete;
        }
        if (isset($skillGoods['activityGoods'])) {
            foreach ($skillGoods['activityGoods'] as &$goods) {
                $goods['originPrice'] = $goods['salePrice'];//原价
                $goods['salePrice'] = $goods['price'];//现在的秒杀活动价
            }
        }
        return $skillGoods;
    }

    /**
     * 获取专题活动
     * @param $selectParams
     * @return ResultWrapper
     */
    public function getSpecial($selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $selectParams['deleteStatus'] = StatusCode::$standard;
        $selectParams['pageType'] = StatusCode::$pageType['special'];
        $selectParams['enableStatus'] = StatusCode::$standard;
        $dbResult = $this->objDPage->select($selectParams, '*', 'updateTime DESC', $limit, $offset);
        $total = $this->objDPage->count($selectParams);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        }

        foreach ($dbResult as $key => &$value) {
            $pageData = json_decode($value['pageData'], true);
            $dbResult[$key]['pageData'] = $pageData;
        }
        $data = [
            'data'  => $dbResult,
            'total' => $total
        ];
        return ResultWrapper::success($data);
    }

    /**
     * 主要用来获取主题详情页
     * @param $id
     * @param
     * @return ResultWrapper
     * @throws \Exception
     */
    public function getDetailById($id)
    {
        $dbResult = $this->objDPage->get_field('pageData',
            ['id' => $id, 'enableStatus' => StatusCode::$standard, 'deleteStatus' => StatusCode::$standard]
        );
        if ($dbResult === false) return ResultWrapper::fail($this->objDPage->error(), ErrorCode::$dberror);
        $items = empty($dbResult) === true ? [] : json_decode($dbResult, true);
        foreach ($items as $key => &$item) {
            $setting = $item['modelData'];//模块配置信息
            switch ($item['comName']){
                case 'GoodsGroup':
                    //获取商品组模块数据
                    if ($setting['navStyle'] == 2) {
                        foreach ($setting['tabList'] as $index => &$val) {
                            $item['modelData']['tabList'][$index]['data'] = ($val['goodsFrom'] == 1) ? self::goodsModule($val) : self::checkGoods($val['goods_ids']);
                        }
                    } else {
                        $items[$key]['data'] = $setting['goodsFrom'] == 1 ? self::goodsModule($setting) : self::checkGoods($item['modelData']['goods_ids']);
                    }
                    break;
                case 'CouponGroup':
                    //获取优惠券模块数据
                    $items[$key]['data'] = self::couponModule($setting);
                    break;
                case 'LimitedSeckill':
                    //获取秒杀商品模块数据
                    $items[$key]['data'] = self::secKillModule($setting);
                    break;
                case 'Notice':
                    //获取公告数据
                    $items[$key]['data'] = self::noticeModule($setting);
                    break;

            }
            /**if ($item['comName'] == 'GoodsGroup') {
                //获取商品组模块数据
                if ($setting['navStyle'] == 2) {
                    foreach ($setting['tabList'] as $index => &$val) {
                        $item['modelData']['tabList'][$index]['data'] = ($val['goodsFrom'] == 1) ? self::goodsModule($val) : self::checkGoods($val['goods_ids']);
                    }
                } else {
                    $items[$key]['data'] = $setting['goodsFrom'] == 1 ? self::goodsModule($setting) : self::checkGoods($item['modelData']['goods_ids']);
                }
            } elseif ($item['comName'] == 'CouponGroup') {
                //获取优惠券模块数据
                $items[$key]['data'] = self::couponModule($setting);
            } elseif ($item['comName'] == 'LimitedSeckill') {
                //获取秒杀商品模块数据
                $items[$key]['data'] = self::secKillModule($setting);
            }**/
        }
        return ResultWrapper::success($items);
    }
}