<?php
namespace Our;

use Error\CodeConfigModel;

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/21
 * Time: 9:47
 */
class Push
{
    private $message = array();
    private $fromId;
    private $fromUserId;
    private $fromUserName;
    private $fromAvatar;
    private $fromType;
    private $toId;
    private $toUserId;
    private $toUserName;
    private $toUserType;
    private $uid;
    private $errorMessage;
    private $errorCode;
    private $systemId = -1;
    private $systemIdStr='01';
    private $orderId = -2;
    private $orderUserId = -2;
    private $orderIdStr='02';
    private $orderName = '订单消息';
    private $expressId = -3;
    public $data;

    public function add($data)
    {
        $this->message = $data['message'];
        $this->fromId = $data['fromId'];
        $this->fromUserId = $data['fromUserId'];
        $this->fromUserName = $data['fromUserName'];
        $this->fromAvatar = $data['fromAvatar'];
        $this->fromType = $data['fromType'];
        $this->toId = $data['toId'];
        $this->toUserId = $data['toUserId'];
        $this->toUserName = $data['toUserName'];
        $this->toUserType = $data['toType'];
        $this->data = $data;
    }

    public function addOneToList($data)
    {
        $this->message = $data['message'];
        $this->fromId = $data['fromId'];
        $this->fromUserId = $data['fromUserId'];
        $this->fromUserName = $data['fromUserName'];
        $this->fromAvatar = $data['fromAvatar'];
        $this->fromType = $data['fromType'];
        $this->toId = $data['toId'];
        $this->toUserId = $data['toUserId'];
        $this->toUserName = $data['toUserName'];
        $this->toUserType = $data['toType'];
        $this->data[] = $data;
    }
    public function addOneToClient($data)
    {
        $this->data[] = $data;
    }

    public function addList($dataList)
    {
        foreach ($dataList as $value) {
            $this->addOneToList($value);
        }
    }

    public function setArrayUid($uids)
    {
        if (is_array($uids)) {
            $this->uid = $uids;
        } else {
            $this->uid = explode(',', $uids);
        }
    }

    function __set($property, $value)
    {
        $this->$property = $value;
    }

    function __get($property)
    {
        return $this->$property;
    }

    public function getErrorMessage()
    {
        return $this->errorMessage;
    }

    public function pushOrderCloseMessage($dataList)
    {
        foreach ($dataList as $data) {
            $convert['fromId'] = $this->orderId;
            $convert['fromUserId'] = $this->orderUserId;
            $convert['fromUserName'] = $this->orderName;
            $convert['fromAvatar'] = Common::getStaticFile(ImageConst::orderAvatarName, ImageConst::systemAvatar);
            $convert['fromType'] = ApiConst::orderMessageType;
            $convert['toId'] = $data['buyerId'];
            $convert['toUserId'] = $data['buyerId'];
            $convert['toUserName'] = $data['buyerName'];
            $convert['toType'] = ApiConst::memberMessageType;
            $convert['message'] = ArrayConst::orderCloseTemplate;
            $convert['message']['href'] = "orderId=" . $data['orderId'];
            $convert['message']['content']=Common::format($convert['message']['content'],$data['orderSn']);
            $convert['message'] = serialize($convert['message']);
            $id = time().(string)$this->orderIdStr.$data['orderId'];
            $convert['id'] =$id;
            $this->addOneToList($convert);
        }
        $this->sendTcpMessage();
    }

    private function getMessageTemplate($type, $title, $content, $thumb='',$url='', $href='', $price=0, $button = array())
    {
        return array(
            'type' => $type,
            'title' => $title,
            'content' => $content,
            'thumb' => $thumb,
            'url'=>$url,
            'href' => $href,
            'price' => $price,
            'createTime'=>TIMESTAMP,
            'buttons' => $button
        );

    }

    private function pushMessage($id,$fromId, $toId, $fromUserId, $toUserId, $fromUserName, $toUserName, $fromType, $toType,$fromavatar, $message)
    {
        $convert['fromId'] = $fromId;
        $convert['fromUserId'] = $fromUserId;
        $convert['fromUserName'] = $fromUserName;
        $convert['fromAvatar'] = $fromavatar;
        $convert['fromType'] = $fromType;
        $convert['toId'] = $toId;
        $convert['toUserId'] = $toUserId;
        $convert['toUserName'] = $toUserName;
        $convert['toType'] = $toType;
        $convert['message'] = serialize($message);
        $convert['id'] = $id;
        $this->addOneToList($convert);
    }

    //到货提醒
    public function reacheRemind($toId,$orderId,$orderSn)
    {
        $memberDao = \DAO\MemberModel::getInstance();
        $member = $memberDao->getInfo($toId);
        $toId=$toId;
        $toUserId=$toId;
        $messageContent=Common::format(DescribeConst::reacheRemindContent,$orderSn);
        $href=Common::format(PathConst::orderId,$orderId);
        $fromAvatar=Common::getStaticFile(ImageConst::orderAvatarName, ImageConst::systemAvatar);
        $buttons=$this->getRecieveButtons($orderId);
        $message=$this->getMessageTemplate(ApiConst::reachRemindMessageType,DescribeConst::reacheRemindTitle,$messageContent,'','',$href,ApiConst::zero,$buttons);
        $id = time() . (string)$this->orderIdStr.$orderId;
        $this->pushMessage($id,$this->orderId,$toId,$this->orderId,$toUserId,$this->orderName,$member['memberName'],ApiConst::orderMessageType,ApiConst::memberMessageType,$fromAvatar,$message);
    }
    //配送提醒
    public function deliveryRemind($toId,$orderId,$orderGoodsId=false)
    {
        $memberDao = \DAO\MemberModel::getInstance();
        $member = $memberDao->getInfo($toId);
        $toId=$toId;
        $toUserId=$toId;
        $orderService=\Business\Order\OrderServiceModel::getInstance();
        $orderDetail=$orderService->getOrderDetail($orderId);
        if($orderGoodsId){
            $orderGoodsDao=\DAO\Order\OrderGoodsModel::getInstance();
            $orderDetail['orderGoods']= $orderGoodsDao->convertRefundOrderGoods($orderDetail['orderGoods'],$orderGoodsId);
        }

        $messageContent=$this->getOrderMessageContent($orderDetail);
        $href=Common::format(PathConst::orderId,$orderId);
        $fromAvatar=Common::getStaticFile(ImageConst::orderAvatarName, ImageConst::systemAvatar);
        // $buttons=$this->getRecieveButtons($orderId);
        $message=$this->getMessageTemplate(ApiConst::deliveryOrderType,DescribeConst::deliveryRemindTitle,$messageContent,'','',$href,ApiConst::zero);
        $id = time() . (string)$this->orderIdStr.$orderId;
        $this->pushMessage($id,\Our\MemberIdConst::deliveryId,$toId,\Our\MemberIdConst::deliveryId,$toUserId,\Our\MemberIdConst::deliveryMessageName,$member['memberName'],ApiConst::diliveryMessageOrder,ApiConst::deliveryUserMessageType,$fromAvatar,$message);
    }
    public function sendDelivery($toId,$orderId,$orderGoodsId=false){
        $this->deliveryRemind($toId,$orderId,$orderGoodsId);
        $this->sendTcpMessage();
    }
    private function getButton($buttonType,$name,$buttonId,$params){
        return array(
            'type'=>$buttonType,
            'name'=>$name,
            'status'=>ApiConst::messageButoonNotClick,
            'showType'=>ApiConst::messageButtonShowTypeOnLight,
            'buttonId'=>$buttonId,
            'params'=>$params
        );
    }
    //确认收货按钮
    private function getRecieveButtons($orderId){
        $buttons=array();
        $button=$this->getButton(ApiConst::messageButtonTypeConfirmButton,DescribeConst::confirmButton,ApiConst::messageButtonIdOne,array('orderId'=>$orderId));
        array_push($buttons,$button);
        return $buttons;

    }
    //确认接单按钮
    private function getComfirmRecieveButtons($orderId){
        $buttons=array();
        $button=$this->getButton(ApiConst::messageButtonTypeReciverButton,DescribeConst::recieveButton,ApiConst::messageButtonIdOne,array('orderId'=>$orderId));
        array_push($buttons,$button);
        return $buttons;

    }
    public function getOrderMessageContent($orderDetail){
        $messageContent='订单号:'.$orderDetail['orderSn']."\n";
        $messageContent.='商品名称:';
        foreach($orderDetail['orderGoods'] as $orderGood){
            $messageContent.=$orderGood['goodsName'].'×'.$orderGood['goodsNum']."\n";
        }
        $messageContent.='支付方式:'.ArrayConst::paymentTypes[$orderDetail['paymentType']]."\n";
        $messageContent.='付款状态:'.($orderDetail['paymentTime']>ApiConst::zero?DescribeConst::payed:DescribeConst::notPayed)."\n";
        $messageContent.='收货地址:'.$orderDetail['reciverInfo']['address']."\n";
        $messageContent.='收货人:'.$orderDetail['reciverInfo']['trueName']."\n";
        $messageContent.='收货人电话:'.$orderDetail['reciverInfo']['mobPhone']."\n";
        return $messageContent;

    }
    public function getUpdateOrderAmountContent($orderDetail){
        $messageContent='订单号:'.$orderDetail['orderSn']."\n";
        $messageContent.='商品名称:';
        foreach($orderDetail['orderGoods'] as $orderGood){
            $messageContent.=$orderGood['goodsName'].'×'.$orderGood['goodsNum']."\n";
        }
        $messageContent.='支付方式:'.ArrayConst::paymentTypes[$orderDetail['paymentType']]."\n";
        $messageContent.='付款状态:'.($orderDetail['paymentTime']>ApiConst::zero?DescribeConst::payed:DescribeConst::notPayed)."\n";
        $messageContent.='收货地址:'.$orderDetail['reciverInfo']['address']."\n";
        $messageContent.='收货人:'.$orderDetail['reciverInfo']['trueName']."\n";
        $messageContent.='收货人电话:'.$orderDetail['reciverInfo']['mobPhone']."\n";
        $messageContent.='订单金额:'.Common::getDivNum($orderDetail['goodsAmount'])."\n";
        $messageContent.='运费:'.Common::getDivNum($orderDetail['shippingFee'])."\n";
        $messageContent.='优惠金额:'.Common::getDivNum($orderDetail['couponAmount'])."\n";
        $messageContent.='应付金额:'.Common::getDivNum($orderDetail['orderAmount'])."\n";
        return $messageContent;

    }
    //用户被修改价格消息
    public function updateOrderAmount($storeId,$orderId,$orderSn)
    {
        $storeDao=\DAO\StoreModel::getInstance();
        $orderDao=\DAO\Order\OrderModel::getInstance();
        $condition['store_id'] = $storeId;
        $store = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeDao, 'getInfo'), array($condition), ApiConst::oneDaySecond, array($storeId));
        //$store = $storeDao->getInfo(array('store_id'=>$storeId));
        $orderService=\Business\Order\OrderServiceModel::getInstance();
        $orderDetail=$orderService->getOrderDetail($orderId);
        $amountOrder=$orderDao->getClienOrderCommon($orderDetail);
        $orderDetail=array_merge($orderDetail,$amountOrder);
        $toUserId=$orderDetail['buyerId'];
        $messageContent=$this->getUpdateOrderAmountContent($orderDetail);
        $fromAvatar=Common::getStaticFile(ImageConst::orderAvatarName, ImageConst::systemAvatar);
        $href=Common::format(PathConst::orderId,$orderId);
        // $buttons=$this->getComfirmRecieveButtons($orderId);
        $message=$this->getMessageTemplate(ApiConst::reicieveOrderType,DescribeConst::updateOrderTitle,$messageContent,'','',$href,ApiConst::zero);
        $id = time() . (string)$this->orderIdStr.$orderId;
        $this->pushMessage($id,$this->orderId,$orderDetail['buyerId'],$this->orderId,$toUserId,$this->orderName,$store['store_name'],ApiConst::orderMessageType,ApiConst::memberMessageType,$fromAvatar,$message);
    }
    //用户被接单消息
    public function recievedOrder($storeId,$orderId,$orderSn)
    {
        $storeDao=\DAO\StoreModel::getInstance();
        $condition['store_id'] = $storeId;
        $store = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeDao, 'getInfo'), array($condition), ApiConst::oneDaySecond, array($storeId));
        //$store = $storeDao->getInfo(array('store_id'=>$storeId));
        $orderService=\Business\Order\OrderServiceModel::getInstance();
        $orderDetail=$orderService->getOrderDetail($orderId);
        $toUserId=$orderDetail['buyerId'];
        $messageContent=$this->getOrderMessageContent($orderDetail);
        $fromAvatar=Common::getStaticFile(ImageConst::orderAvatarName, ImageConst::systemAvatar);
        $href=Common::format(PathConst::orderId,$orderId);
       // $buttons=$this->getComfirmRecieveButtons($orderId);
        $message=$this->getMessageTemplate(ApiConst::reicieveOrderType,DescribeConst::recieveOrderTitle,$messageContent,'','',$href,ApiConst::zero);
        $id = time() . (string)$this->orderIdStr.$orderId;
        $this->pushMessage($id,$this->orderId,$orderDetail['buyerId'],$this->orderId,$toUserId,$this->orderName,$store['store_name'],ApiConst::orderMessageType,ApiConst::memberMessageType,$fromAvatar,$message);
    }
    //店铺接单
    public function recieveWait($storeId,$orderId,$orderSn)
    {
        $storeDao=\DAO\StoreModel::getInstance();
        $condition['store_id'] = $storeId;
        $store = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeDao, 'getInfo'), array($condition), ApiConst::oneDaySecond, array($storeId));
        //$store = $storeDao->getInfo(array('store_id'=>$storeId));
        $orderService=\Business\Order\OrderServiceModel::getInstance();
        $orderDetail=$orderService->getOrderDetail($orderId);
        $toUserId=$storeId;
        $messageContent=$this->getOrderMessageContent($orderDetail);
        $fromAvatar=Common::getStaticFile(ImageConst::orderAvatarName, ImageConst::systemAvatar);
        $href=Common::format(PathConst::orderId,$orderId);
        $buttons=$this->getComfirmRecieveButtons($orderId);
        $message=$this->getMessageTemplate(ApiConst::waitRecieveOrderType,DescribeConst::recieveWaitTitle,$messageContent,'','',$href,ApiConst::zero,$buttons);
        $id = time() . (string)$this->orderIdStr.$orderId;
        $this->pushMessage($id,$this->orderId,$store['member_id'],$this->orderId,$toUserId,$this->orderName,$store['store_name'],ApiConst::orderMessageType,ApiConst::storeMessageType,$fromAvatar,$message);
    }

    public function sendTcpMessage()
    {
        $push = \Yaf\Registry::get('config')->get('push');
        $conf = \Yaf\Registry::get('config')->get('redis.database.params');
        try{
            if ($push['open']) {
                if(!empty($this->data)){
                    $redis=new \Redis();
                    $redis->connect($conf['host'], $conf['port']);
                    if(!empty($conf['password'])){
                        $redis->auth($conf['password']);
                    }
                    $message['data'] = $this->data;
                    $message['uid'] = !empty($this->uid)?$this->uid:ApiConst::zero;
                    // $message['data']=array_slice($message['data'],2,14);
                    $message = json_encode($message);
                    $key=md5($message);
                    $redis->set($key,$message);
                    $message=$key;
                    $message = $message . "\r\n";
                    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                    if (!@socket_connect($socket, $push['host'], $push['port'])) {
                        $this->errorCode = CodeConfigModel::pushConnectError;
                        return false;
                    }
                    // @socket_connect($socket, $push['host'], $push['port']) or die("推送连接失败");
                    $num = ApiConst::zero;
                    $length = strlen($message);
                    do {
                        $buffer = substr($message, $num);
                        $ret = @socket_write($socket, $buffer);
                        $num += $ret;
                    } while ($num < $length);
                    $ret = '';
                    do {
                        $buffer = @socket_read($socket, 1024, PHP_BINARY_READ);
                        $ret .= $buffer;
                    } while (strlen($buffer) == 1024);
                    socket_close($socket);
                    $server_data = json_decode($ret, true);
                    if ($server_data['status'] == 1) {
                        unset($this->data);
                        return true;
                    }
                    $redis->close();
                    unset($this->data);
                    unset($redis);
                }
            } else {
                $this->errorCode = CodeConfigModel::pushIsNotOpen;
                return false;
            }
        }catch(\Exception $ex){
            echo $ex->getMessage();
        }

    }

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

    /**
     * 获取类实例
     *
     * @ccw push
     */
    public static function getInstance()
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}

///推送模块
