<?php

namespace App\Services;

use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Model\User as UserModel;
use App\Model\UserDoctor as UserDoctorModel;
use App\Model\UserPatient as UserPatientModel;
use App\Model\UserPharmacist as UserPharmacistModel;
use App\Utils\Http;
use App\Utils\Jwt;
use App\Utils\Log;
use Extend\TencentIm\Account;
use Extend\Wechat\Wechat;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class LoginService extends BaseService
{
    /**
     * 微信登陆
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function wechatMobileLogin(): array
    {
        $phone_code = $this->request->input('phone_code');
        $wx_code = $this->request->input('wx_code');
        $user_type = $this->request->input('user_type');

        $weChat = new Wechat($user_type);

        // 获取手机号
        $phone_info = $weChat->getPhone($phone_code);

        if (empty($phone_info) || empty($phone_info['phone_info']) || empty($phone_info['phone_info']['purePhoneNumber'])){
            return fail(HttpEnumCode::GET_WX_ERROR);
        }
//        $phone_info['phone_info']['purePhoneNumber'] = "18221234162";

        // 获取用户openid
        $wx_info_data = $weChat->codeToSession($wx_code);
//        $wx_info_data = array(
//            "session_key" => "SWfpkHtKZRq/G0ONoxigaQ==",
//            "openid" => "o9gYG441zEAHuYoNX7lwFKiQBzKE",
//        );
        if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) {
            return fail(HttpEnumCode::GET_WX_ERROR);
        }

        Db::beginTransaction();

        try {
            // 获取用户信息
            $params = array();
            $params['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
            $user = UserModel::getOne($params);
            if (empty($user)) {
                // 处理药师特殊情况，后台添加，前台不允许注册
                if ($user_type == 3) {
                    Db::rollBack();
                    return fail(HttpEnumCode::HTTP_ERROR,"账号不存在，请联系客服");
                }

                // 新增用户表
                $data = array();
                $data['user_name'] = substr($phone_info['phone_info']['purePhoneNumber'],-4);
                $data['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
                $data['wx_mobile'] = $phone_info['phone_info']['purePhoneNumber'];
                $data['user_type'] = $user_type;
                $data['register_method'] = 1;//注册方式（1:小程序授权 2:手机号 ）
                $data['login_ip'] = (new Http())->getIp() ?? "";// 登陆ip
                $data['last_login_at'] = date('Y-m-d H:i:s', time());// 最后登陆时间
                $user = UserModel::addUser($data);
                if (empty($user)) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }

                // 新增对应用户数据表
                $data = array();
                $data['user_id'] = $user->user_id;
                $data['user_name'] = $user['user_name'];
                $data['open_id'] = $wx_info_data['openid'];
                $data['union_id'] = $wx_info_data['unionid'] ?? "";
                $data['wx_session_key'] = $wx_info_data['session_key'];
                $data['status'] = 1;

                if ($user['user_type'] == 1) {
                    // 患者
                    $user_patient = UserPatientModel::addUserPatient($data);
                    if (empty($user_patient)) {
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR);
                    }
                    $client_user_id = $user_patient['patient_id'];

                    // 发放用户优惠卷
                    $CouponService = new CouponService();

                    $res = $CouponService->DistributeCoupon(1,$user->user_id,$user_patient['patient_id']);
                    if (!$res){
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR);
                    }
                } elseif ($user['user_type'] == 2) {
                    // 新增医生表
                    $user_doctor = UserDoctorModel::addUserDoctor($data);
                    if (empty($user_doctor)) {
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR);
                    }

                    $client_user_id = $user_doctor['doctor_id'];
                }

                // 创建im账号
                $account = new Account();
                // 创建单个账号
                $account->createAccount($user->user_id,$user->user_name,"");
            } else {
                // 已注册用户
                // 重复注册不同端
                if ($user_type != $user['user_type']) {
                    Db::rollBack();
                    $result = UserTypeToString($user['user_type']);
                    return fail(HttpEnumCode::GET_WX_ERROR, "手机号已在" . $result . "注册");
                }

                // 获取对应端用户信息
                $params = array();
                $params['user_id'] = $user->user_id;
                if ($user['user_type'] == 1) {
                    $result = UserPatientModel::getOne($params);
                    if (!empty($result)){
                        $client_user_id = $result['patient_id'];
                    }
                } elseif ($user['user_type'] == 2) {
                    $result = UserDoctorModel::getOne($params);
                    if (!empty($result)){
                        $client_user_id = $result['doctor_id'];
                    }
                } elseif ($user['user_type'] == 3) {
                    $result = UserPharmacistModel::getOne($params);
                    if (!empty($result)){
                        $client_user_id = $result['pharmacist_id'];
                    }
                }

                if (empty($result)) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }

                // 判断用户状态
                if ($result['status'] != 1) {
                    Db::rollBack();
                    return fail(HttpEnumCode::USER_STATUS_ERROR);
                }

                // 更新session_key
                $data = array();
                if ($wx_info_data['session_key'] != $result['session_key']) {
                    $data['wx_session_key'] = $wx_info_data['session_key'];
                }
                $data['updated_at'] = date('Y-m-d H:i:s', time());

                $params = array();
                if ($user['user_type'] == 1) {
                    $params['patient_id'] = $result['patient_id'];
                    $res = UserPatientModel::editUserPatient($params, $data);
                } elseif ($user['user_type'] == 2) {
                    $params['doctor_id'] = $result['doctor_id'];
                    $res = UserDoctorModel::editUserDoctor($params, $data);
                } elseif ($user['user_type'] == 3) {
                    $params['pharmacist_id'] = $result['pharmacist_id'];
                    $res = UserPharmacistModel::editUserPharmacist($params, $data);
                }

                if (!$res) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }
            }

            // 记录用户登陆记录
            $Http = new Http();
            $login_ip = $Http->getIp();
            $params = array();
            $params['user_id'] = $user['user_id'];

            $data = array();
            $data['login_ip'] = $login_ip ?? "";
            $data['last_login_at'] = date('Y-m-d H:i:s', time());

            UserModel::editUser($params,$data);
            // 组合生成token的数据
            $token_user_data = array();
            $token_user_data['user_id'] = $user['user_id']; // 用户id
            $token_user_data['user_type'] = $user['user_type'];// 用户类型
            $token_user_data['open_id'] = $wx_info_data['openid'];// open_id
            $token_user_data['client_user_id'] = $client_user_id;// 对应客户端id

            // 发放token
            $Jwt = new Jwt();
            $token = $Jwt->encode($token_user_data);

            // 组合返回数据
            $data = array();
            $data['token'] = $token;
            $data['user_id'] = $user['user_id'];
            $data['client_user_id'] = $client_user_id;

            Db::commit();
            return success($data);

        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
        }
    }

    /**
     * 手机号登陆
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function mobileLogin(): array
    {
        $code = $this->request->input('code');
        $phone = $this->request->input('phone');
        $user_type = $this->request->input('user_type');
        $wx_code = $this->request->input('wx_code');

//        $redis = $this->container->get(Redis::class);
//        // 验证验证码
//        $sms_code = $redis->get("login_code" . $phone);
//        if (empty($sms_code)){
//            return fail(HttpEnumCode::CODE_EXPIRED);
//        }
//
//        if ($sms_code != $code){
//            return fail(HttpEnumCode::CODE_ERROR);
//        }

        try {
            $weChat = new Wechat($user_type);

            // 获取用户openid
            $wx_info_data = $weChat->codeToSession($wx_code);
            $session_key = $wx_info_data['session_key'] ?? "";
            $open_id = $wx_info_data['openid'] ?? "";
        } catch (\Exception $e) {
            // 此处不进行处理
            Log::getInstance()->info($e->getMessage());
        }

        Db::beginTransaction();

        try {
            // 获取用户信息
            $params = array();
            $params['mobile'] = $phone;
            $user = UserModel::getOne($params);
            if (empty($user)) {
                // 处理药师特殊情况，后台添加，前台不允许注册
                if ($user_type == 3) {
                    Db::rollBack();
                    return fail(HttpEnumCode::HTTP_ERROR,"账号不存在，请联系客服");
                }

                // 新增用户表
                $data = array();
                $data['user_name'] = substr($phone,-4);
                $data['mobile'] = $phone;
                $data['wx_mobile'] = $phone;
                $data['user_type'] = $user_type;
                $data['register_method'] = 2;
                $data['login_ip'] = (new Http())->getIp() ?? "";// 登陆ip
                $data['last_login_at'] = date('Y-m-d H:i:s', time());// 最后登陆时间
                $user = UserModel::addUser($data);
                if (empty($user)) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }

                // 新增对应用户数据表
                $data = array();
                $data['user_id'] = $user->user_id;
                $data['user_name'] = $user['user_name'];
                $data['status'] = 1;
                $data['open_id'] = $open_id ?? '';
                $data['wx_session_key'] = $session_key ?? "";

                if ($user['user_type'] == 1) {
                    // 患者
                    $user_patient = UserPatientModel::addUserPatient($data);
                    if (empty($user_patient)) {
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR);
                    }
                    $client_user_id = $user_patient['patient_id'];

                    // 发放用户优惠卷
                    $CouponService = new CouponService();

                    $res = $CouponService->DistributeCoupon(1,$user->user_id,$user_patient['patient_id']);
                    if (!$res){
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR);
                    }
                } elseif ($user['user_type'] == 2) {
                    // 新增医生表
                    $user_doctor = UserDoctorModel::addUserDoctor($data);
                    if (empty($user_doctor)) {
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR);
                    }
                    $client_user_id = $user_doctor['doctor_id'];
                }elseif($user['user_type'] == 3){
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }else{
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }

                // 创建im账号
                $account = new Account();
                // 创建单个账号
                $account->createAccount($user->user_id,$user->user_name,"");
            } else {
                // 已注册用户
                if ($user_type != $user['user_type']) {
                    Db::rollBack();
                    $result = UserTypeToString($user['user_type']);
                    return fail(HttpEnumCode::HTTP_ERROR, "手机号为" . $result . "账号");
                }

                $params = array();
                $params['user_id'] = $user->user_id;
                if ($user['user_type'] == 1) {
                    $result = UserPatientModel::getOne($params);
                    if (!empty($result)){
                        $client_user_id = $result['patient_id'];
                    }
                } elseif ($user['user_type'] == 2) {
                    $result = UserDoctorModel::getOne($params);
                    if (!empty($result)){
                        $client_user_id = $result['doctor_id'];
                    }
                } elseif ($user['user_type'] == 3) {
                    $result = UserPharmacistModel::getOne($params);
                    if (!empty($result)){
                        $client_user_id = $result['pharmacist_id'];
                    }
                }else{
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }

                if (empty($result)) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR);
                }

                // 判断用户状态
                if ($result['status'] != 1) {
                    Db::rollBack();
                    return fail(HttpEnumCode::USER_STATUS_ERROR);
                }
            }

            // 记录用户登陆记录
            $Http = new Http();
            $login_ip = $Http->getIp();
            $params = array();
            $params['user_id'] = $user['user_id'];

            $data = array();
            $data['login_ip'] = $login_ip ?? "";
            $data['last_login_at'] = date('Y-m-d H:i:s', time());
            UserModel::editUser($params,$data);

            // 组合生成token的数据
            $token_user_data = array();
            $token_user_data['user_id'] = $user['user_id']; // 用户id
            $token_user_data['user_type'] = $user['user_type'];// 用户类型
            $token_user_data['open_id'] = $open_id ?? "";// open_id
            $token_user_data['client_user_id'] = $client_user_id;// 对应客户端id

            // 发放token
            $Jwt = new Jwt();
            $token = $Jwt->encode($token_user_data);

            // 登录成功，删除验证码
//            $redis->del("login_code" . $phone);

            // 组合返回数据
            $data = array();
            $data['token'] = $token;
            $data['user_id'] = $user['user_id'];
            $data['client_user_id'] = $client_user_id;

            Db::commit();
            return success($data);

        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
        }
    }

    /**
     * 微信授权接口
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     */
    public function wxAuthorize(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];
        $wx_code = $this->request->input('wx_code');

        if (empty($user_info)){
            return fail(HttpEnumCode::GET_WX_ERROR);
        }

        // 获取用户数据
        $params = array();
        $params['user_id'] = $user_info['user_id'];
        $user = UserModel::getOne($params);
        if (empty($user)){
            return fail();
        }

        try {
            $weChat = new Wechat($user['user_type']);

            // 获取用户openid
            $wx_info_data = $weChat->codeToSession($wx_code);
            if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) {
                return fail(HttpEnumCode::GET_WX_ERROR);
            }

            // 获取对应端用户信息
            $params = array();
            $params['user_id'] = $user['user_id'];
            if ($user['user_type'] == 1) {
                $result = UserPatientModel::getOne($params);
            } elseif ($user['user_type'] == 2) {
                $result = UserDoctorModel::getOne($params);
            } elseif ($user['user_type'] == 3) {
                $result = UserPharmacistModel::getOne($params);
            }

            if (empty($result)) {
                return fail(HttpEnumCode::SERVER_ERROR);
            }

            // 判断用户状态
            if ($result['status'] != 1) {
                return fail(HttpEnumCode::USER_STATUS_ERROR);
            }

            // 更新session_key
            $data = array();
            if ($wx_info_data['session_key'] != $result['session_key']) {
                $data['wx_session_key'] = $wx_info_data['session_key'];
            }

            if ($wx_info_data['openid'] != $result['open_id']) {
                $data['open_id'] = $wx_info_data['openid'];
            }

            if (!empty($data)){
                $data['updated_at'] = date('Y-m-d H:i:s', time());

                $params = array();
                if ($user['user_type'] == 1) {
                    $params['patient_id'] = $result['patient_id'];
                    $res = UserPatientModel::editUserPatient($params, $data);
                } elseif ($user['user_type'] == 2) {
                    $params['doctor_id'] = $result['doctor_id'];
                    $res = UserDoctorModel::editUserDoctor($params, $data);
                } elseif ($user['user_type'] == 3) {
                    $params['pharmacist_id'] = $result['pharmacist_id'];
                    $res = UserPharmacistModel::editUserPharmacist($params, $data);
                }else{
                    $res = false;
                }

                if (!$res) {
                    return fail(HttpEnumCode::SERVER_ERROR);
                }
            }
        } catch (\Exception $e) {
            // 此处不进行处理
            return fail(HttpEnumCode::GET_WX_ERROR,$e->getMessage());
        }

        return success();
    }
}