/**
  * Push status
  *
  * <b>Request Type: </b>POST<br/>
  * <b>Request Endpoint: </b>http://{server-domain}/api/chat/conversation/state<br/>
  * <b>Content-type: </b>application/json<br/>
  * <b>Summary: </b>This is api is for push the status of the client or helpDesk to the server<br/>
  *
  * <b>Request Parameters: </b><br/>
  *     channelName: string, the name of the channel<br/>
  *     eventName: string, the name of the event, should be 'deskLeft', 'deskJoined', 'clientLeft', 'clientJoined', 'clientPing', 'pendingLeft' <br/>
  *     consersationId: string, the identifier of the conversation.<br/>
  *     desk: array, the information of the help desk.<br/>
  *         desk.badge: string, the badge id of the helpDesk.<br/>
  *         desk.id: string, the identifier of the helpDesk.<br/>
  *         desk.email: string, the email of the helpDesk.<br/>
  *         desk.avatar: string, the url of the avatar of the helpDesk.<br/>
  *     client: array, the information of the client.<br/>
  *         client.nick: string, the nickname of the client.<br/>
  *         client.avatar: string, the url of the avatar of the client.<br/>
  *         client.openId: string, the openId of the client.<br/>
  *         client.source: string, 'web' or 'wechat', the source.<br/>
  *
  * <b>Request Example: </b><br/>
  * <pre>
  * {
  *      "eventName": "clientJoined",
  *      "conversationId": "149035b7b81374aa468b4566",
  *      "desk": {
  *         "badge": "T04247",
  *         "id": "54a24c12db4c0ecc048b4568",
  *          "email": "*****@*****.**",
  *           "avatar": "http://test.com/avatar.png"
  *       },
  *       "client": {
  *           "nick": "devin",
  *           "avatar": "http://test.com/avatar.png",
  *           "openId": "2234231234f2d12",
  *           "source": "website",
  *           "messages": [
  *               ...
  *           ]
  *       },
  *       "extra": {
  *           //extra data
  *       }
  *   }
  *
  * <b>Response Example: </b><br/>
  * <pre>
  *     {"status": "ok"}
  * </pre>
  *
  * for clientJoined
  * </pre>
  * {
  *      "status": "ok",
  *       "helpDesk": {
  *           "id": "54a24c12db4c0ecc048b4568",
  *           "badge": "T04247",
  *           "email": "*****@*****.**",
  *           "avatar": "/images/management/image_hover_default_avatar.png",
  *           "isEnabled": true,
  *           "isActivated": false,
  *           "name": null,
  *           "language": "zh_cn",
  *           "clientCount": 1,
  *           "isOnline": false,
  *           "conversationCount": 2,
  *           "maxClient": 5
  *       },
  *       "channel": "wm-chat-54a24c12db4c0ecc048b4568-2234231234f2d12",
  *       "conversationId": "54a295addb4c0ecd048b456c"
  *   }
  * </pre>
  */
 public function actionState()
 {
     $eventName = $this->getParams('eventName');
     $conversationId = $this->getParams('conversationId');
     $desk = $this->getParams('desk');
     $client = $this->getParams('client');
     $extra = $this->getParams('extra');
     $cache = Yii::$app->cache;
     $accountId = $this->getAccountId();
     $response = [];
     if (!empty($desk['id'])) {
         $deskMongoId = new \MongoId($desk['id']);
     }
     if (empty($eventName)) {
         throw new BadRequestHttpException('Missing required fields');
     }
     switch ($eventName) {
         case 'deskJoined':
             if (empty($desk) || empty($deskMongoId)) {
                 throw new BadRequestHttpException('Missing required fields');
             }
             $response = HelpDesk::join($desk['id'], $accountId);
             Yii::$app->tuisongbao->triggerEvent(HelpDesk::EVENT_ONLINE_STATUS, [], [HelpDesk::CHANNEL_GLOBAL . $accountId]);
             break;
         case 'deskLeft':
             if (empty($desk) || empty($deskMongoId)) {
                 throw new BadRequestHttpException('Missing required fields');
             }
             // cannot get accountId when logout from work order system first
             $cid = new \MongoId($this->getParams('cid'));
             $accountId = empty($accountId) ? $cid : $accountId;
             $response = HelpDesk::leave($desk['id'], $accountId, $extra);
             Yii::$app->tuisongbao->triggerEvent(HelpDesk::EVENT_ONLINE_STATUS, [], [HelpDesk::CHANNEL_GLOBAL . $accountId]);
             break;
         case 'clientJoined':
             if (empty($client)) {
                 throw new BadRequestHttpException('Missing required fields');
             }
             $client['nick'] = "guest-" . $client['openId'];
             $accountId = $this->getParams('cid');
             if (empty($accountId)) {
                 throw new BadRequestHttpException('Missing accountId');
             }
             $accountId = new \MongoId($accountId);
             $client['accountId'] = $accountId;
             $conversation = ChatConversation::findOpenByClientId($client['openId'], $accountId);
             if (!empty($conversation)) {
                 //Return the original conversation information if the convesation is not closed
                 $response = ['status' => 'ok', 'desk' => $conversation->desk, 'client' => $conversation->client, 'channel' => $conversation->conversation, 'conversationId' => (string) $conversation->_id, 'lastChatTime' => $conversation->lastChatTime, 'chatTimes' => ChatConversation::getChatTimes($conversation->client['openId'], $accountId)];
             } else {
                 $response = HelpDesk::connect($client, $accountId);
             }
             break;
         case 'clientLeft':
             if (empty($conversationId)) {
                 throw new BadRequestHttpException('Missing required fields');
             }
             $accountId = $this->getParams('cid');
             if (empty($accountId)) {
                 throw new BadRequestHttpException("Missing accountId");
             }
             $accountId = new \MongoId($accountId);
             $response = HelpDesk::disconnect(new \MongoId($conversationId), $extra);
             break;
         case 'clientPing':
             if (empty($client) || empty($client['openId'])) {
                 throw new BadRequestHttpException("missing client field or openId for client");
             }
             $response = ['status' => 'ok'];
             if (PendingClient::setLastPingTimeByOpenId($client['openId']) == 0) {
                 $response['status'] = 'fail';
             }
             break;
         case 'deskPing':
             if (empty($desk) || empty($desk['id'])) {
                 throw new BadRequestHttpException("missing desk field or id for desk");
             }
             $response = ['status' => 'ok'];
             if (!HelpDesk::setLastPingTimeById($desk['id'], $accountId)) {
                 $response['status'] = 'fail';
             }
             break;
         case 'pendingLeft':
             if (empty($client) || empty($client['openId'])) {
                 throw new BadRequestHttpException("missing client");
             }
             $status = PendingClient::deleteAll(['openId' => $client['openId']]) ? 'ok' : 'fail';
             $response['status'] = $status;
             break;
             //for develop only, query the conversation status
         //for develop only, query the conversation status
         case 'status':
             $response['online'] = $cache->get('conversations' . $accountId);
             $response['onsocket'] = $cache->get('wm-online-desks' . $accountId);
             if (!empty($desk['id'])) {
                 $response['webhook-time'] = $cache->get('wm-update-time' . $desk['id']);
             }
             break;
         default:
             throw new BadRequestHttpException('Illegal event name');
             break;
     }
     return array_merge($response, ['sentTime' => TimeUtil::msTime()]);
 }