<?php
namespace DAO;

use Our\ApiConst;
use Our\ArrayConst;
use Our\DbNameConst;
use Our\ImageConst;

/**
 * 店铺数据层
 * @date 2018-5-14
 * @author csw
 */
class StoreModel extends \DAO\AbstractModel
{

    public $detailField = " member_id as memberId,store_id as storeId,offline_payway as offlinePayway,store_label as storeLabel,offline_payway as offlinePayway";

    protected function init()
    {

    }

    /**
     * 表名
     *
     * @var string
     */
    protected $_tableName = 'han_store';

    protected $_tableNameFull = 'han_store_full';

    /**
     * 主键
     *
     * @var string
     */
    protected $_primaryKey = 'store_id';


    public function convertOfflinePayway($offlinPayway)
    {

        if (!empty($offlinPayway)) {
            $offlinPayway=unserialize($offlinPayway);
            $res['imageUrls']=[];
            foreach($offlinPayway['images'] as $image){
                $image= \Our\Common::getStaticFile($image, \Our\ImageConst::storeLabel);
                array_push($res['imageUrls'],$image);
            }

            $res['payway']=$offlinPayway['payway']?$offlinPayway['payway']:'';
        }
        if(empty($res)){
            $res=new \stdClass();
        }
        return $res;
    }

    public function updateStoreDeposit(){
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $addKey=\Our\Common::getConfig('password.key');
        $storeDepositSql = 'update han_store_extend t set t.total_deposit = (SELECT max(a.deposit) from han_qm_store_class a  where a.store_id = t.store_id and a.class_style =2 and a.is_charged =1), t.total_deposit_sign = MD5(CONCAT(t.gmt_create,(SELECT max(a.deposit) from han_qm_store_class a  where a.store_id = t.store_id and a.class_style =2 and a.is_charged =1),\''.$addKey.'\'))';
        $result = $this->db->update($this->_tableNameFull)->query($storeDepositSql);
        $emptyDepositSql = 'update han_store_extend t set  t.total_deposit_sign =\'\' where t.total_deposit = 0';
        $resultEmpty = $this->db->update($this->_tableNameFull)->query($emptyDepositSql);
        return $result&&$resultEmpty;
    }

    /**
     * 获取店铺信息
     * @param $where
     * @return mixed
     */

    public function getInfo($where)
    {
        $this->setDb();
        $field = $this->_getColumns();
        $store = $this->db->select($field)->from($this->_tableName)->where($where)->fetchOne();
        $store['store_label'] = $this->getStoreLabelSrc($store['store_label']);
        return $store;
    }


    /**
     *
     * 获取指定字段店铺信息
     *
     * @param $where 查询条件
     * @param $field 查询字段
     * @return mixed 店铺信息
     * User: King <358887571@qq.com>
     * Date: 2018/11/27 0027
     * Time: 下午 5:27
     */
    public function getFieldsInfo($where, $field)
    {
        $this->setDb();
        $store = $this->db->select($field)->from($this->_tableName)->where($where)->fetchOne();
        return $store;
    }


    public function getInfoById($id, $field = '*', $isField = false)
    {
        $this->setDb($this->dbName);
        $where[$this->_primaryKey] = $id;
        $store = $this->db->from($this->_tableNameFull)->select($field)->where($where)->fetchOne();
        if ($isField) {
            return $store[$isField];
        } else {
            return $store;
        }
    }
    public function getStoreFullList($where, $field) {
        $this->setDb($this->dbName);
        if(is_array($where)) {
            $where = $this->db->getSqlWhereByArray($where);
        }
        $result = $this->db->from($this->_tableNameFull)->select($field)->where($where)->fetchAll();
        return $result;
    }
    public function getInfoByMemberId($memberId, $field = '*', $isField = false, $db = DbNameConst::salveDBConnectName)
    {
        $this->setDb($db);
        $where['member_id'] = $memberId;
        $store = $this->db->from($this->_tableName)->select($field)->where($where)->fetchOne();
        if ($isField) {
            return $store[$isField];
        } else {
            return $store;
        }
    }

    /**
     * 店铺头像/资质图片
     *
     * @param $storeLabel
     * @return string
     */
    public function getStoreLabelSrc($storeLabel, $width = \Our\ImageConst::circleStoreLabel, $height = 0,$original = false)
    {
        $width = ceil($width * \Our\ImageConst::sizeScale);
        $height ? $height = ceil($height * \Our\ImageConst::sizeScale) : $height = $width;
        if ($storeLabel) {
            $storeLabel = \Our\Common::getStaticFile($storeLabel, \Our\ImageConst::storeLabel, 'ossHost');
        } else {
            $storeLabel = \Our\Common::getStaticFile(ImageConst::defaultStoreLabelName, ImageConst::defaultPath);
        }
        if($original == false) {
            $storeLabel .= "?x-oss-process=image/resize,m_fill,h_{$height},w_{$width}";
        }
        return $storeLabel;
    }

    /**
     * 店铺首页banner
     *
     * @param $storeLabel
     * @return string
     */
    public function getStoreBanner($img)
    {
        if ($img) {
            $storeLabel = \Our\Common::getStaticFile($img, \Our\ImageConst::storeLabel, 'ossHost');
        } else {
            $storeLabel = \Our\Common::getStaticFile(ImageConst::defaultStoreBannerName, ImageConst::defaultPath);
        }
        $storeLabel .= "?x-oss-process=image/resize,m_fill,h_314,w_750";
        return $storeLabel;
    }

    /**
     * 店铺月销量
     *
     * @param $storeId
     * @return mixed
     */
    public function getStoreMonthSales($storeId)
    {
        $this->setDb();
        $data = $this->db->from('han_store_month_sales')->select('*')->where(array('store_id' => $storeId))->fetchOne();

        if ($data) {
            return $data['num'];
        }
    }


    /**
     * @param $field 可获取
     * @return mixed 返回店铺列表
     */
    public function getOnlineStores($where = null, $field = '*', $limit = [])
    {

        //$conditionSql = 'store_state =1 and open_flag =1 and (store_end_time >=' . TIMESTAMP . ' or store_end_time =0 ) ';
        $conditionSql = 'store_state =1 and open_flag =1 ';
        if ($where) {
            $conditionSql = $where . ' and ' . $conditionSql;
        }
        $result = $this->getStores($conditionSql, $field, $limit);
        return $result;
    }


    public function getList($where, $pageIndex, $pageSize, $field = '*')
    {
        $this->setDb();
        return $this->db->select($field)->from($this->_tableName)->where($where)->page($pageIndex, $pageSize)->order('state', 'ASC')->order('addtime', 'DESC')->fetchAll();
    }

    //是否收取快递费
    public function isChargeGet($storeId)
    {
        $isChargeGet = $this->getInfoById($storeId, 'is_charge_get');

        return $isChargeGet['is_charge_get'] > ApiConst::zero ? TRUE : FALSE;
    }

    //线上支付订单已接单待发货退款是否收取服务费(0:否 1:是)
    public function isChargeNoSend($storeId)
    {
        $isChargeNoSend = $this->getInfoById($storeId, 'is_charge_no_send');
        return $isChargeNoSend;
    }

    //线上支付发货中订单退货是否收取服务费(0:否 1:是)
    public function isChargeSend($storeId)
    {
        $isChargeSend = $this->getInfoById($storeId, 'is_charge_send');
        return $isChargeSend;
    }

    public function isGetFee($storeId, $orderStatus)
    {
        if ($orderStatus <= ApiConst::orderStateWaitSend) {
            return $this->isChargeNoSend($storeId);
        }
        if ($orderStatus >= ApiConst::orderStateWaitRecieve) {
            return $this->isChargeGet($storeId);
        }
    }

    //获取是否应该收取服务费或快递费
    public function isFee($storeId, $shippingtype, $orderStatus)
    {
        if ($shippingtype != ApiConst::express) {
            return $this->isGetFee($storeId, $orderStatus);
        } else {
            return $this->isChargeGet($storeId);
        }

    }

    /**
     * 获取店铺列表
     * @param $where
     * @param $field
     * @return mixed
     */
    public function getStores($where, $field = "*", $limit = [])
    {
        $this->setDb();
        if($limit) {
            $this->db->limit($limit[0], $limit[1]);
        }
        $result = $this->db->select($field)->from($this->_tableName)->where($where)->fetchAll();
        return $result;
    }

    public function deleteStoreRefundCache($storeId,$orderId=ApiConst::zero){

        if(!empty($storeId)){
            $refundReturnDao = \DAO\Order\RefundReturnModel::getInstance(DbNameConst::salveDBConnectName);
            $orderGoodsDao = \DAO\Order\OrderGoodsModel::getInstance(DbNameConst::salveDBConnectName);
            $orderDao=\DAO\Order\OrderModel::getInstance(DbNameConst::salveDBConnectName);
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$refundReturnDao, 'getList'), array(), array($storeId));
             \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderGoodsDao, 'getOrderGoodsByOrderIds'), array(), array($storeId));
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderGoodsDao, 'getOrderGoodsByRecIds'), array(), array($storeId));
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderDao, 'getList'), array(), array($storeId));
        }
        if(!empty($orderId)){

            $orderCommonDao = \DAO\Order\OrderCommonModel::getInstance(DbNameConst::salveDBConnectName);
             \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderGoodsDao, 'findByRecId'), array(), array($orderId));
             \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderCommonDao, 'findByOrderId'), array(), array($orderId));
             \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderDao, 'findByOrderId'), array(), array($orderId));
        }
    }
    public function deleteStoreCache($storeId,$orderId){
        $qmDeliveryManLogDao =\DAO\Order\QmDeliverymanLogModel::getInstance();
        $diliveryMan = \DAO\Order\DiliverymanModel::getInstance();
        if(!empty($storeId)){
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getList'), array(), array($storeId));
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$qmDeliveryManLogDao, 'getList'), array(), array($storeId));
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$diliveryMan, 'getDeliveryManByStoreId'), array(), array($storeId));
        }
        if(!empty($orderId)){
            $orderDao=\DAO\Order\OrderModel::getInstance(DbNameConst::salveDBConnectName);
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$orderDao, 'findByOrderId'), array(), array($orderId));
        }
    }

    public function deleteStoreTotalCount($storeId){
        $favoritesStoreDao = \DAO\FavoritesStoreModel::getInstance();
        $orderDao=\DAO\Order\OrderModel::getInstance();
        $storeStatisticsDao=\DAO\StoreStatisticsModel::getInstance();
        $storeMemberStaticDao=\DAO\StoreMemberStatisticsModel::getInstance();
        $favoritesStoreDao->deleteGetFavoritesCountByStoreId($storeId);
        $memberFavoritesStoreStoreMemberStatisticsDao = \DAO\Store\MemberFavoritesStoreStoreMemberStatisticsModel::getInstance();
        $memberFavoritesStoreStoreMemberStatisticsDao->deleteGetGoodsCountOrderTotalByStoreIdCache($storeId);
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeMemberStaticDao, 'getGoodsCountOrderTotalByStoreId'), array(),  array($storeId));
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$memberFavoritesStoreStoreMemberStatisticsDao, 'getGoodsCountOrderTotalByStoreId'), array(),  array($storeId));
        \Our\RedisHelper::delCachedFunction(\Redis\Db5\OrderRedisModel::getInstance(), array(&$orderDao, 'getShopKeeperCountByStoreId'), array(),  array($storeId));
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeStatisticsDao, 'getByStoreId'), array(), array($storeId));;
        \Our\RedisHelper::delCachedFunction(\Redis\Db5\OrderRedisModel::getInstance(), array(&$favoritesStoreDao, 'getFavoritesCountByStoreId'), array(), array($storeId));
        $orderDao->deleteGetOrderOrderTotalOnlineByStoreIdCache($storeId);
       // \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeStatisticsDao, 'getByStoreId'), array($storeId),  array($storeId));;
        $storeStatisticsDao->deleteGetByStoreIdCache($storeId);

    }

    public function getStoresByCityCode($cityCode, $field = 'store_id,store_longitude,store_latitude,max_sign_rang,max_sales_rang,store_sales_scope')
    {
        $storeClassCondition = " store_citycode = '" . $cityCode . "' ";

        $stores = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getOnlineStores'), array($storeClassCondition, $field), \Our\ApiConst::oneHour, array($cityCode));
        return $stores;
    }

    public function delStoresCacheByCityCode($cityCode)
    {
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getOnlineStores'), array(), array($cityCode));
    }

    /**
     * 获取当前城市对应正在经营店铺列表
     * @param $cityCode 当前城市编码
     * @return mixed 当前城市列表
     * @throws \Our\Exception
     */
    public function getExpressStores($field = 'store_id,store_longitude,store_latitude,max_sign_rang,max_sales_rang,store_sales_scope')
    {

        $storeClassCondition = " express_distribution = 1 ";

        $stores = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getOnlineStores'), array($storeClassCondition, $field), \Our\ApiConst::oneHour);
        return $stores;
    }

    public function deleteExpressStores($field = 'store_id,store_longitude,store_latitude,max_sign_rang,max_sales_rang,store_sales_scope')
    {
        $storeClassCondition = " express_distribution = 1 ";
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getOnlineStores'), array(array($storeClassCondition, $field)));
    }

    public function getNearbyStores($cityCode, $storeIds)
    {
        $condition = " store_id in (" . implode(',', $storeIds) . ") and  store_citycode = '" . $cityCode . "'";
        $field = 'store_id as storeId,store_label as storeLabel,store_name as storeName,store_intro as storeIntro,store_longitude,store_latitude';
        $returnStores = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getOnlineStores'), array($condition, $field), \Our\ApiConst::oneHour, array($cityCode));
        return $returnStores;
    }

    public function delNearbyStoresCache($cityCode)
    {
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getOnlineStores'), array(), array($cityCode));
    }

    public function getAddress($storeId)
    {

        $storeInfo = $this->getStoreInfoCache($storeId);
        //地址
        $address = '';
        if ($storeInfo['area_info']) {
            $address .= $storeInfo['area_info'];
        }
        if ($storeInfo['store_address']) {
            $address .= $storeInfo['store_address'];
        }
        return $address;

    }

    public function get($storeId, $label = true, $reportError = true)
    {
        $storeInfo = $this->getStoreInfoCache($storeId);
        if (!$storeInfo) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNotExistOrClose);
        }
        if ($storeInfo['open_flag'] != 1 || $storeInfo['store_state'] != 1) {
            if ($reportError) {
                /*if($storeInfo['open_flag'] != 1) {
//                    \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNotOpen);
                    \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNotExistOrClose);
                }else{
                    \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNotExistOrClose);
                }*/
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNotExistOrClose1);
            } else {
                $storeInfo['isClose'] = 1;
            }
        } else {
            $storeInfo['isClose'] = 0;
        }

        if ($label) {
            //店铺头像
            $storeLabel = $this->getStoreLabelSrc($storeInfo['store_label']);

            return array($storeInfo, $storeLabel);
        }
        return $storeInfo;
    }

    public function getStoreInfoCache($storeId)
    {
        $storeInfo = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getInfoById'), array($storeId), \Our\ApiConst::sevenDaySecond, array($storeId));
        return $storeInfo;
    }

    public function delStoreInfoCache($storeId)
    {
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$this, 'getInfoById'), array(), array($storeId));
    }

    /**
     * 店铺分享图片
     *
     * @param $storeLabel
     * @return string
     */
    public function getStoreShareSrc($img)
    {
        return \Our\Common::getStaticFile($img, \Our\ImageConst::defaultPath, 'ossHost');

    }

    /**
     * 获取店铺分享信息
     * @param $storeInfo
     * @return mixed
     */
    public function getShareInfo($storeInfo)
    {
        if (!is_array($storeInfo)) {
            $storeInfo = $this->get($storeInfo, false);
        }
        $share['title'] = $storeInfo['store_share_title'] ? $storeInfo['store_share_title'] : $storeInfo['store_name'];
        $share['desc'] = $storeInfo['store_share_desc'] ? $storeInfo['store_share_desc'] : $storeInfo['store_notice'];
        if ($storeInfo['store_share_img']) {
            $img = $this->getStoreShareSrc($storeInfo['store_share_img']);
        } else {
            $img = $this->getStoreLabelSrc($storeInfo['store_label']);
        }
        $share['imgUrl'] = $img;
        $share['link'] = 'http://www.shenbd.com';
        return $share;
    }

    /**
     * 检查当前地址是否有可用配送方式
     * @param $address
     * @param $store
     * @return int
     */
    public function checkAddressInServiceArea($address, $store)
    {
        $inAreaFlag = \Our\ApiConst::zero;
        if ($store['buyer_distribution']) {//如果店铺开启了到店自提和快递配送,则认为存在可用配送方式
            $inAreaFlag = \Our\ApiConst::one;
            return $inAreaFlag;
        }
        if ($store['seller_distribution'] && $address) {
            $result = \Store\StoreUtil::getInstance()->checkAddressInServiceAreaByStore(array('lng' => $address['lng'], 'lat' => $address['lat']),$store);
            if ($result) {
                $inAreaFlag = \Our\ApiConst::one;
            }
        }
        return $inAreaFlag;
    }


    /**
     * 类实例
     *
     * @var \DAO\UserModel
     */
    private static $_instance = null;

    /**
     * 获取类实例
     *
     * @return \DAO\UserModel
     */
    public static function getInstance($dbName = \Our\DbNameConst::salveDBConnectName)
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self($dbName);
        }

        return self::$_instance;
    }

    private function _getColumns()
    {
        return array(
            'store_id',
            'store_name',
            'store_address',
            'store_state',
            'store_start_time',
            'store_close_time',
            'store_close_info',
            'store_label',
            'store_banner',
            'store_phone',
            'store_zy',
            'store_credit',
            'member_id',
            'store_desccredit',
            'store_servicecredit',
            'store_deliverycredit',
            'store_collect',
            'store_slide',
            'store_slide_url',
            'store_workingtime',
            'store_free_price',
            'store_decoration_switch',
            'store_decoration_only',
            'store_free_time',
            'store_longitude',
            'store_latitude',
            'wx_pay',
            'offline_pay',
            'aog_pay',
            'seller_distribution',
            'start_shipping_price',
            'free_shipping_price',
            'buyer_distribution',
            'express_distribution',
            'is_ally',
            'is_ally_discount',
            'ally_discount',
            'recommend_word',
            'is_direct_refund',
            'is_charge_no_send',
            'is_charge_send',
            'is_charge_get',
            'is_charge_delivery',
            'search_keyword',
            'store_sales_scope',
            'max_sales_rang',
            'store_notice',
            'store_citycode',
            'store_subaddress',
            'store_qrcode_param',
            'store_qrcode_path',
            'store_detail_image',
            'store_dis_sta_time',
            'store_dis_end_time',
            'store_share_title',
            'store_share_img',
            'store_share_desc',
            'store_share_url',
            'is_wx_bind',
            'default_user_comment',
            'store_end_time',
            'store_points_ratio',
            'delivery_interval',
            'is_rec',
            'offline_payway',
            'open_flag',
            'store_intro',
            'business_start_time',
            'business_end_time',
        );
    }

    public function getAll($where = array())
    {
        $this->setDb($this->dbName);
        if ($where) {
            $where = $this->db->getSqlWhereByArray($where);
        }
        if ($where) {
            $res = $this->db->from($this->_tableName)->where($where)->fetchAll();
        } else {
            $res = $this->db->from($this->_tableName)->fetchAll();
        }
        $resArray = array();
        foreach ($res as $val) {
            $resArray[$val['store_id']] = $val;
        }

        return $resArray;
    }

    /**
     * 保存用户信息
     */
    public function add($data)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->insert($this->_tableName)->rows($data)->execute();
        return $result;
    }

    public function save($data, $where)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->update($this->_tableName)->rows($data)->where($where)->execute();
        return $result;
    }

    /**
     * 获取当前店铺对应的微信支付服务商号
     * @param $storeId
     * @return array
     */
    public function getStoreWxMchId($storeId){
        $store = $this->get($storeId,false);
        $errorCode = 0;
        $mchId = '';
        if($store['wx_pay']){
            if(!($store['wxpay_mchid']&&$store['onlinepay_flag'])){
                $errorCode = \Error\CodeConfigModel::orderWxPayError;
            }
            $addKey=\Our\Common::getConfig('password.key');
            if ($store['wxpay_mchid_sign'] == md5($store['gmt_create'].$store['wxpay_mchid'].$addKey)) {
                $mchId = $store['wxpay_mchid'];
            }else{
                $errorCode = \Error\CodeConfigModel::orderWxPaySignError;
            }
        }
        return array('mchId'=>$mchId,'errorCode'=>$errorCode);
    }

    /**
     * 获取试用期快到期的店铺
     */
    public function getTryExpireStore() {
        $this->setDb($this->dbName);
        $sql = "SELECT  store.store_id,store.store_end_time,store.store_phone,store.store_name,max(pay_state) AS pay_state FROM han_store store LEFT JOIN han_store_class_pay_log store_class_pay_log on store.store_id = store_class_pay_log.store_id where   ((unix_timestamp(now())+9*24*3600) < store.store_end_time and store.store_end_time <= (unix_timestamp(now())+10*24*3600) ) or ((unix_timestamp(now())+2*24*3600) < store.store_end_time and store.store_end_time <= (unix_timestamp(now())+3*24*3600) ) or ((unix_timestamp(now())+4*24*3600) < store.store_end_time and store.store_end_time <= (unix_timestamp(now())+5*24*3600) ) GROUP BY store.store_id  HAVING pay_state IS NULL or pay_state = 0";
        $query = $this->db->query($sql);
        return $query->rows;
    }
}
