<?php

namespace App\Utils;

use GuzzleHttp\Client;
use Ixudra\Curl\Facades\Curl;
use Tencent\TLSSigAPI;

class ImUtil
{

    /** @var string $url */
    protected $url = 'https://console.tim.qq.com';

    /** @var string $version */
    protected $version = 'v4';

    /** @var string $usersig */
    protected $usersig = 'eJxlj1FPgzAYRd-5FYRXjftoaZ2*sUXjpChEnIMXUqFjFaFYus1p-O9GXCKJ9-Wc3Jv7adm27STs4YwXhdq2JjeHTjj2pe2Ac-oHu06WOTc51uU-KN47qUXO10boAbqEEAQwdmQpWiPX8mjwspGt7I3mRumR1pd1Pmz99ngAiGLqjpt6WQ0wvErni3ieIAgDvA9u2AyWKppw3Wf7pygWEZt0dSCqa5XGsA3Tqb-Y*HfVZsU*3hTzm8NJMrt1i2nDXnfZ42p5n70QEsTnFD8LDV49mjSyEcdj9IJ6mCI0ojuhe6naQUDgEhdh*IljfVnf3wtf6Q__';

    /** @var string $identifier */
    protected $identifier = 'administrator';

    /** @var string $sdkAppId */
    protected $sdkAppId = '1400263610';

    /** @var string $contentType */
    protected $contentType = 'json';

    /** @var Client $httpClient */
    protected $httpClient;

    public function __construct()
    {
        $this->httpClient = new Client(['verify' => false]);
    }

    /**
     * @param  string  $identifier
     * @return string
     * @throws \Exception
     */
    protected function generateSign($identifier)
    {
        $tencentIM = new TLSSigAPI();
        $tencentIM->SetAppid($this->sdkAppId);
        $private = file_get_contents(resource_path('certs/tencent_im_private'));
        $tencentIM->SetPrivateKey($private);
        return $tencentIM->genSig($identifier, 24 * 3600 * 365 * 10000);
    }



    protected function getUrl($type)
    {
        $url = $this->url . '/' . $this->version;
        switch ($type) {
            case 'sendMessage':
                $url .= '/openim/sendmsg';
                break;
            case 'register':
                $url .= '/im_open_login_svc/account_import';
                break;
            case 'update':
                $url .= '/profile/portrait_set';
                break;
            case 'fetchUser':
                $url .= '/profile/portrait_get';
                break;
            case 'download-messages':
                $url .= '/open_msg_svc/get_history';
                break;
            case 'dirty-word-add':
                $url .= '/openim_dirty_words/add';
                break;
            case 'get-dirty-words':
                $url .= '/openim_dirty_words/get';
                break;
            case 'delete-dirty-words':
                $url .= '/openim_dirty_words/delete';
                break;
            default:
                break;
        }

        return $url . "?" . http_build_query([
                'usersig' => $this->usersig,
                'identifier' => $this->identifier,
                'sdkAppid' => $this->sdkAppId,
                'random' => rand(10000, 99999),
                'contenttype' => $this->contentType,
            ]);
    }

    public function getDirtyWords()
    {
        $url = $this->getUrl('get-dirty-words');
        $res = $this->httpClient->request('get', $url);

        return json_decode($res->getBody(), true);
    }

    public function dirtyWordAdd(array $words)
    {
        $url = $this->getUrl('dirty-word-add');
        $res = $this->httpClient->request("POST", $url, [
            'json' => [
                'DirtyWordsList' => $words,
            ]
        ]);
        return json_decode($res->getBody(), true);
    }

    public function deleteDirtyWords(array $words)
    {
        $url = $this->getUrl('delete-dirty-words');
        $res = $this->httpClient->request("POST", $url, [
            'json' => [
                'DirtyWordsList' => $words,
            ]
        ]);
        return json_decode($res->getBody(), true);
    }

    /**
     * 注册用户/重新获取sig
     * @param  string  $imAccount 自己生成的IM_Account
     * @param  string  $name 用户名字
     * @param  string  $avatar 头像
     * @param  int  $gender
     * @param  int  $type
     * @return string
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Exception
     */
    public function registerUser($imAccount, $name, $avatar, $gender = 1, $type = 0)
    {
        $sign = $this->generateSign($imAccount);

        $url = $this->getUrl('register');

        $this->httpClient->request('POST', $url, [
            'json' => [
                'Identifier' => "$imAccount",
                'Nick' => "$name",
                'FaceUrl' => "$avatar",
                'Type' => $type, // 值 0 表示普通帐号，1 表示机器人帐号
            ]
        ]);

        $this->updateUser($imAccount, $name, $avatar, $sign, $gender);

        return $sign;
    }


    /**
     * @param $name
     * @return mixed|\Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function fetchUser($name)
    {
        $url = $this->getUrl('fetchUser');

        $response = $this->httpClient->request('POST', $url, [
            'json' => [
                'To_Account' => [
                    $name
                ],
                'TagList' => [
                    "Tag_Profile_IM_Nick",
                ]
            ]
        ]);

        return $response;
    }


    /**
     * 发送消息
     * @param $identifier
     * @param $toAccount
     * @param $msgBody
     * @return \Psr\Http\Message\StreamInterface
     * @throws \Exception
     */
    public function sendMessage($identifier, $toAccount, $msgBody)
    {
        $sig = $this->generateSign($identifier);
        $this->identifier = $identifier;
        $this->usersig = $sig;

        $url = $this->getUrl('sendMessage');

        $response = $this->httpClient->post($url, [
            'json' => [
                'SyncOtherMachine' => 2,
                'From_Account' => $identifier,
                'To_Account' => $toAccount,
                'MsgLifeTime' => 86400 * 7,
                'MsgRandom' => rand(1000000, 9999999),
                'MsgBody' => $msgBody

                //    "OfflinePushInfo": {
                //        "PushFlag": 0,
                //        "Desc": "离线推送内容",
                //        "Ext": "这是透传的内容",
                //        "AndroidInfo": {
                //            "Sound": "android.mp3"
                //        },
                //        "ApnsInfo": {
                //            "Sound": "apns.mp3",
                //            "BadgeMode": 1, // 这个字段缺省或者为 0 表示需要计数，为 1 表示本条消息不需要计数，即右上角图标数字不增加
                //            "Title":"apns title", // apns title
                //            "SubTitle":"apns subtitle", // apns subtitle
                //            "Image":"www.image.com" // image url
                //        }
                //    }
                //}
            ]
        ]);
        return $response->getBody();
    }

    /**
     * 修改头像
     * @param  string  $identifier
     * @param  string  $name
     * @param  string  $avatar
     * @param  int  $sex
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Exception
     */
    public function updateAvatar($identifier, $name, $avatar, $sex = 0)
    {
        $sign = $this->generateSign($identifier);

        $url = $this->getUrl('update');

        $this->httpClient->request("POST", $url, [
            'json' => [
                "From_Account" => "$identifier",
                "ProfileItem" => [
                    [
                        'Tag' => 'Tag_Profile_IM_Nick',
                        'Value' => "$name",
                    ],
                    [
                        'Tag' => 'Tag_Profile_IM_Gender',
                        'Value' => $this->getGenderString($sex),
                    ],
                    [
                        'Tag' => 'Tag_Profile_IM_Image',
                        'Value' => "$avatar",
                    ],
                    [
                        'Tag' => 'Tag_Profile_Custom_Password',
                        'Value' => "$sign",
                    ],

                ]
            ]
        ]);
    }

    public function downloadMessages($msgTime)
    {
        $url = $this->getUrl('download-messages');

        $response = $this->httpClient->request("POST", $url, [
            'json' => [
                'ChatType' => 'C2C',
                'MsgTime' => $msgTime,
            ]
        ]);

        return $response->getBody()->getContents();
    }


    /**
     * 获取性别字符串
     * @param  int  $gender
     * @return string
     */
    protected function getGenderString($gender)
    {
        switch ($gender) {
            case 1:
                return "Gender_Type_Male";
            case 2:
                return "Gender_Type_Female";
            default:
                return "Gender_Type_Unknown";
        }
    }


    /**
     * @param  string  $identifier
     * @param  string  $name
     * @param  string  $avatar
     * @param  string  $sign
     * @param  int  $gender
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function updateUser($identifier, $name, $avatar, $sign, $gender = 0)
    {
        $url = $this->getUrl('update');

        $this->httpClient->request("POST", $url, [
            'json' => [
                "From_Account" => "$identifier",
                "ProfileItem" => [
                    [
                        'Tag' => 'Tag_Profile_IM_Nick',
                        'Value' => "$name",
                    ],
                    [
                        'Tag' => 'Tag_Profile_IM_Gender',
                        'Value' => $this->getGenderString($gender),
                    ],
                    [
                        'Tag' => 'Tag_Profile_IM_Image',
                        'Value' => "$avatar",
                    ],
                    [
                        'Tag' => 'Tag_Profile_Custom_Password',
                        'Value' => "$sign",
                    ],

                ]
            ]
        ]);
    }

    /**
     * 重新设置资料
     * @param  string  $identifier
     * @param  string  $name
     * @param  string  $avatar
     * @param  int  $gender
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Exception
     */
    public function updates($identifier, $name, $avatar, $gender = 0)
    {
        $url = $this->getUrl('update');

        $sign = $this->generateSign($identifier);

        $this->httpClient->request("POST", $url, [
            'json' => [
                "From_Account" => "$identifier",
                "ProfileItem" => [
                    [
                        'Tag' => 'Tag_Profile_IM_Nick',
                        'Value' => "$name",
                    ],
                    [
                        'Tag' => 'Tag_Profile_IM_Gender',
                        'Value' => $this->getGenderString($gender),
                    ],
                    [
                        'Tag' => 'Tag_Profile_IM_Image',
                        'Value' => "$avatar",
                    ],
                    [
                        'Tag' => 'Tag_Profile_Custom_Password',
                        'Value' => "$sign",
                    ],

                ]
            ]
        ]);
    }
}
