<?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 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)
    {
        $memberDao = \DAO\MemberModel::getInstance();
        $member = $memberDao->getInfo($toId);
        $toId=$toId;
        $toUserId=$toId;
        $orderService=\Business\Order\OrderServiceModel::getInstance();
        $orderDetail=$orderService->getOrderDetail($orderId);
        $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::orderMessageType,ApiConst::deliveryUserMessageType,$fromAvatar,$message);
    }
    public function sendDelivery($toId,$orderId){
        $this->deliveryRemind($toId,$orderId);
        $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 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');
        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;
                }
                unset($this->data);
                unset($redis);
            }
        } else {
            $this->errorCode = CodeConfigModel::pushIsNotOpen;
            return false;
        }
    }

    /**
     * 类实例
     *
     * @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;
    }
}

///推送模块
