<?php

namespace App\Services;

use App\Constants\DoctorTitleCode;
use App\Exception\BusinessException;
use App\Model\Hospital;
use App\Model\User;
use App\Model\UserDoctor;
use App\Model\UserPatient;
use App\Model\UserPharmacist;
use App\Utils\Log;
use Extend\TencentIm\Account;
use Extend\TencentIm\Message;
use Extend\TencentIm\Profile;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class ImService extends BaseService
{
    /**
     * 检测并创建账号
     * @param string $user_id
     * @return bool
     * @throws GuzzleException
     */
    public function createAccount(string $user_id): bool
    {
        try {
            $params = array();
            $params['user_id'] = $user_id;
            $user = User::getOne($params);
            if (empty($user)){
                throw new BusinessException("用户数据错误");
            }

            $avatar = addAliyunOssWebsite($user['avatar']);

            $account = new Account();
            // 查询账号导入状态
            $res = $account->checkAccountStatus($user['user_id']);
            if (!$res){
                // 创建单个账号
                $account->createAccount($user_id,$user['user_name'],$avatar);
            }

            // 检测用户资料
            $profile = new Profile();
            $result = $profile->getOneAccountPortraitList($user['user_id']);
            if (!empty($result)){
                $arg = array();

                // 头像
                if (in_array('Tag_Profile_IM_Image',$result)){
                    $arg['Tag_Profile_IM_Image'] = $avatar;
                }

                // 性别
                if (in_array('Tag_Profile_IM_Gender',$result)){
                    $arg['Tag_Profile_IM_Gender'] = sexToImSex($user['sex']);
                }

                if ($user['user_type'] == 2){
                    $params = array();
                    $params['user_id'] = $user['user_id'];
                    $user_doctor = UserDoctor::getOne($params);
                    if (empty($user_doctor)){
                        throw new BusinessException("医生数据错误");
                    }

                    // 获取订单医生医院
                    $params = array();
                    $params['hospital_id'] = $user_doctor['hospital_id'];
                    $hospital = Hospital::getOne($params);
                    if (empty($hospital)){
                        throw new BusinessException("医生医院数据错误");
                    }

                    // 医院
                    if (in_array('Tag_Profile_Custom_Hname',$result)){
                        $arg['Tag_Profile_Custom_Hname'] = $hospital['hospital_name'];
                    }

                    // 职称
                    if (in_array('Tag_Profile_Custom_Title',$result)){
                        $arg['Tag_Profile_Custom_Title'] = $user_doctor['doctor_title'] ?? DoctorTitleCode::getMessage($user_doctor['doctor_title']);
                    }
                }

                if (!empty($arg)){
                    $profile->setProfile($user['user_id'],$arg);
                }
            }

            return true;
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }

    /**
     * 设置用户资料
     * @param string $user_id
     * @return bool
     * @throws GuzzleException
     */
    public function setUserProfile(string $user_id): bool
    {
        try {
            $params = array();
            $params['user_id'] = $user_id;
            $user = User::getOne($params);
            if (empty($user)){
                throw new BusinessException("用户数据错误");
            }

            $avatar = addAliyunOssWebsite($user['avatar']);

            // 检测用户资料
            $profile = new Profile();
            $result = $profile->getOneAccountPortraitList($user['user_id']);

            if (!empty($result)){
                $arg = array();

                // 头像
                if (in_array('Tag_Profile_IM_Image',$result)){
                    $arg['Tag_Profile_IM_Image'] = $avatar;
                }

                // 性别
                if (in_array('Tag_Profile_IM_Gender',$result)){
                    $arg['Tag_Profile_IM_Gender'] = sexToImSex($user['sex']);
                }

                if ($user['user_type'] == 2){
                    $params = array();
                    $params['user_id'] = $user['user_id'];
                    $user_doctor = UserDoctor::getOne($params);
                    if (empty($user_doctor)){
                        throw new BusinessException("医生数据错误");
                    }

                    // 获取订单医生医院
                    $params = array();
                    $params['hospital_id'] = $user_doctor['hospital_id'];
                    $hospital = Hospital::getOne($params);
                    if (empty($hospital)){
                        throw new BusinessException("医生医院数据错误");
                    }

                    // 医院
                    if (in_array('Tag_Profile_Custom_Hname',$result)){
                        $arg['Tag_Profile_Custom_Hname'] = $hospital['hospital_name'];
                    }

                    // 职称
                    if (in_array('Tag_Profile_Custom_Title',$result)){
                        $arg['Tag_Profile_Custom_Title'] = $user_doctor['doctor_title'] ?? DoctorTitleCode::getMessage($user_doctor['doctor_title']);
                    }
                }

                if (!empty($arg)){
                    $profile->setProfile($user['user_id'],$arg);
                }
            }

            return true;
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }

    /**
     * 验证回调签名
     * @param string $request_time 签名时间戳
     * @param string $sign 签名
     * @return bool
     */
    public function validateSign(string $request_time,string $sign): bool
    {
        $token = config('im.token');
        if (empty($token)){
            throw new BusinessException("Im Token Config Error");
        }

        $sys_sign =  hash("sha256", $token . $request_time);
        if ($sign != $sys_sign){
            return false;
        }

        return true;
    }

    /**
     * 添加最近联系人会话记录缓存
     * @param string $doctor_id 医生id
     * @param string $inquiry_type 订单类型（自定义字段 1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
     * @param string $patient_user_id 患者用户id
     * @param array $content 内容
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function addRecentContactRecordCache(string $doctor_id,string $inquiry_type,string $patient_user_id,array $content): void
    {
        $redis_key = "recentContact" . $doctor_id . $inquiry_type;

        $hash_key = $patient_user_id;

        $redis = $this->container->get(Redis::class);

        $redis->hSet($redis_key,$hash_key,json_encode($content,JSON_UNESCAPED_UNICODE));
    }

    /**
     * 发送文本消息
     * @param string $from_user_id 发送者id
     * @param string $to_user_id 接受者id
     * @param string $content 内容
     * @param string $order_inquiry_id 订单id
     * @param int $inquiry_type
     * @return void
     * @throws GuzzleException
     */

    /**
     * 发送消息
     * @param string $from_user_id 发送者id
     * @param string $to_user_id 接受者id
     * @param array $message_content 内容 对应 MsgBody.MsgContent
     * @param string $message_type 消息类型 具体查看（https://cloud.tencent.com/document/product/269/2720）
     * @param array $cloud_custom_data 自定义字段
     * @return void
     */
    public function sendMessage(string $from_user_id, string $to_user_id, array $message_content, string $message_type, array $cloud_custom_data): void
    {
        try {
            if (!empty($from_user_id)){
                // 检测并创建发送者资料
                $this->setUserProfile($from_user_id);
            }

            // 检测并创建接收者资料
            $this->setUserProfile($to_user_id);

            $message = new Message();

            $arg = array();
            if (!empty($from_user_id)){
                $arg['From_Account'] = $from_user_id; // 发送方user_id 如系统发送，无需填写
            }
            $arg['To_Account'] = $to_user_id; // 接收方user_id
            $arg['ForbidCallbackControl'] = ['ForbidBeforeSendMsgCallback',"ForbidAfterSendMsgCallback"];
            $arg['SendMsgControl'] = ['NoUnread'];

            $arg['MsgBody'] = [
                [
                    "MsgType" => $message_type,
                    "MsgContent" => $message_content,
                ]
            ];

            $arg['CloudCustomData'] = "";
            if (!empty($cloud_custom_data)){
                $arg['CloudCustomData'] = json_encode($cloud_custom_data,JSON_UNESCAPED_UNICODE);
            }

            $message->sendMessage($arg);
        }catch (\Exception $e){
            throw new BusinessException($e->getMessage());
        } catch (GuzzleException $e) {
            throw new BusinessException($e->getMessage());
        }
    }
}