<?php


namespace App\Libs\Push\OPPOPush;

use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

class OPPOPushCommon
{
    // app key
    private $_appKey;

    // master secret
    private $_masterSecret;

    // token
    private $_authToken;

    private $_reg_arr;

    /**
     * OPPOPushCommon constructor.
     * @param $appKey
     * @param $masterSecret
     * @throws GuzzleException
     */
    public function __construct($appKey, $masterSecret)
    {
        $this->_appKey       = $appKey;
        $this->_masterSecret = $masterSecret;
        $this->_authToken    = $this->getAuthToken();
    }

    public function setRegArr($regArr)
    {
        $this->_reg_arr = $regArr;
    }

    /**
     * 全部推送
     * @param $messageId
     * @return mixed
     * @throws GuzzleException
     */
    public function broadCastAll($messageId)
    {
        return $this->broadCast(1, $messageId);
    }

    /**
     * 批量推送
     * @param $messageId
     * @return mixed
     * @throws GuzzleException
     */
    public function broadCastRegIds($messageId)
    {
        return $this->broadCast(2, $messageId);
    }

    /**
     * 保存通知栏消息内容体
     * @param       $title
     * @param       $content
     * @param       $url
     * @return mixed|string
     * @throws GuzzleException
     */
    public function getMessageId($title, $content, $url)
    {
        // 组装数据
        $pushMessage = new PushMessage();
        $pushMessage->style(1); // 通知栏样式,1. 标准样式
        $pushMessage->title($title);
        $pushMessage->content($content);
        $pushMessage->click_action_type(1); // 点击动作类型0，启动应用；1，打开应用内页
        $pushMessage->click_action_activity('com.nearme.instant.action.PUSH');
        $pushMessage->action_parameters(json_encode([
            'page' => $url,
        ]));
        $pushMessage->channel_id('OPPO PUSH');
        $pushMessage->auth_token($this->_authToken);
        $fields = $pushMessage->getData();

        // 请求数据
        $data = [
            'form_params' => $fields
        ];

        // 请求
        $client    = new Client(['base_uri' => config('push.server.oppo.saveMessage'), 'timeout' => 10.0,]);
        $response  = $client->request('POST', '', $data);
        $body      = $response->getBody();
        $result    = json_decode($body, true);
        $messageId = getProp($result['data'], 'message_id');
        if (!$messageId) {
            throw new Exception('保存通知栏消息内容体失败');
        }

        $this->logPush(__FUNCTION__, 'result', compact('data', 'messageId'));
        return $messageId;
    }

    /**
     * 添加标签
     * @param $name
     * @param $desc
     * @return mixed
     * @throws GuzzleException
     */
    public function addTags($name, $desc)
    {
        $data = [
            'headers' => [
                'auth_token' => $this->_authToken
            ],
            'json'    => [
                'name' => $name,
                'desc' => $desc,
            ]
        ];

        // 请求
        $client   = new Client(['base_uri' => config('push.server.oppo.addTags'), 'timeout' => 10.0,]);
        $response = $client->request('POST', '', $data);
        $body     = $response->getBody();
        $result   = json_decode($body, true);

        $this->logPush(__FUNCTION__, 'result', compact('data', 'result'));
        return $result;
    }

    /**
     * 标签订阅接口
     * @param $regId
     * @param $tags
     * @return mixed
     * @throws GuzzleException
     */
    public function subscribeTags($regId, $tags)
    {
        $data = [
            'headers' => [
                'auth_token' => $this->_authToken
            ],
            'json'    => [
                'registration_id' => $regId,
                'tags'            => $tags,
            ]
        ];

        // 请求
        $client   = new Client(['base_uri' => config('push.server.oppo.subTags'), 'timeout' => 10.0,]);
        $response = $client->request('POST', '', $data);
        $body     = $response->getBody();
        $result   = json_decode($body, true);

        $this->logPush(__FUNCTION__, 'result', compact('data', 'result'));
        return $result;
    }

    /**
     * 取消标签订阅接口
     * @param $regId
     * @param $tags
     * @return mixed
     * @throws GuzzleException
     */
    public function unSubscribeTags($regId, $tags)
    {
        $data = [
            'headers' => [
                'auth_token' => $this->_authToken
            ],
            'json'    => [
                'registration_id' => $regId,
                'tags'            => $tags,
            ]
        ];

        // 请求
        $client   = new Client(['base_uri' => config('push.server.oppo.unSubTags'), 'timeout' => 10.0,]);
        $response = $client->request('POST', '', $data);
        $body     = $response->getBody();
        $result   = json_decode($body, true);

        $this->logPush(__FUNCTION__, 'result', compact('data', 'result'));
        return $result;
    }

    /**
     * 取消标签订阅接口
     * @param $regId
     * @return mixed
     * @throws GuzzleException
     */
    public function getAllTags($regId)
    {
        $data = [
            'headers' => [
                'auth_token' => $this->_authToken
            ],
            'json'    => [
                'registration_id' => $regId,
            ]
        ];

        // 请求
        $client   = new Client(['base_uri' => config('push.server.oppo.getAllTags'), 'timeout' => 10.0,]);
        $response = $client->request('POST', '', $data);
        $body     = $response->getBody();
        $result   = json_decode($body, true);

        $this->logPush(__FUNCTION__, 'result', compact('data', 'result'));
        return $result;
    }

    /**
     * 查询APP当天发送量的状态
     * @return mixed
     * @throws GuzzleException
     */
    public function fetchPushPermit()
    {
        $data = [
            'headers' => [
                'auth_token' => $this->_authToken
            ]
        ];

        // 请求
        $client   = new Client(['base_uri' => config('push.server.oppo.fetchPushPermit'), 'timeout' => 10.0,]);
        $response = $client->request('GET', '', $data);
        $body     = $response->getBody();
        $result   = json_decode($body, true);

        $this->logPush(__FUNCTION__, 'result', compact('data', 'result'));
        return $result;
    }

    /**
     * 获得auth_token权限令牌
     * @return mixed|string
     * @throws GuzzleException
     */
    private function getAuthToken()
    {
        // 生成sign
        $timestamp = getMillisecond();
        $sign      = hash('sha256', $this->_appKey . $timestamp . $this->_masterSecret);

        // 数据组装
        $data = [
            'form_params' => [
                'app_key'   => $this->_appKey,
                'sign'      => $sign,
                'timestamp' => $timestamp
            ]
        ];

        $client    = new Client(['base_uri' => config('push.server.oppo.auth'), 'timeout' => 10.0,]);
        $response  = $client->request('POST', '', $data);
        $body      = $response->getBody();
        $result    = json_decode($body, true);
        $authToken = getProp($result['data'], 'auth_token');
        if (!$authToken) {
            throw new Exception('获取auth token失败');
        }

        $this->logPush(__FUNCTION__, 'result', compact('authToken'));
        return $authToken;
    }

    /**
     * 广播推送-通知栏消息
     * @param       $targetType
     * @param       $messageId
     * @return mixed
     * @throws GuzzleException
     */
    private function broadCast($targetType, $messageId)
    {
        $param = [
            'auth_token'  => $this->_authToken,
            'message_id'  => $messageId,
            'target_type' => $targetType,
        ];

        // reg_id 批量
        if ((int)$targetType === 2 && $this->_reg_arr) {
            $param['target_value'] = implode(';', $this->_reg_arr);
        }

        // 请求数据
        $data = [
            'form_params' => $param
        ];

        // 请求
        $client   = new Client(['base_uri' => config('push.server.oppo.broadcast'), 'timeout' => 10.0,]);
        $response = $client->request('POST', '', $data);
        $body     = $response->getBody();
        $result   = json_decode($body, true);

        $this->logPush(__FUNCTION__, 'result', compact('targetType', 'messageId', 'result'));
        return $result;
    }

    private function logPush($className, $message, $data = [])
    {
        var_dump('[' . $className . '] ' . $message, $data);
        myLog('push')->info('[OPPO] [' . $className . '] ' . $message, $data);
    }
}