<?php

namespace App\Services;

use App\Constants\HttpEnumCode;
use App\Model\SubTemplate;
use App\Model\User;
use App\Model\User as UserModel;
use App\Model\UserDoctor;
use App\Model\UserDoctorInfo;
use App\Model\UserPatient;
use App\Model\UserShipAddress;
use App\Utils\Mask;
use App\Utils\PcreMatch;
use Extend\TencentIm\Profile;
use Extend\Wechat\Wechat;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Result;
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 UserService extends BaseService
{
    /**
     * 添加订阅消息
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     */
    public function addSubMessage(): array
    {
        // 下载消息模版
        $weChat = new Wechat(1);
        $result = $weChat->getTemplate();
        if (empty($result)) {
            Db::rollBack();
            return fail();
        }

        $template = json_decode($result, true);

        foreach ($template['data'] as $item) {
            $params = array();
            $params['wx_template_id'] = $item['priTmplId'];
            $sub_template = SubTemplate::getOne($params);
            if (empty($sub_template)) {
                // 新增模版
                $data = array();
                $data['client_type'] = 1;
                $data['wx_template_id'] = $item['priTmplId'];
                $data['template_title'] = $item['title'];
                $data['template_type'] = $item['type'];
                $data['template_content'] = $item['content'];
                $sub_template = SubTemplate::addSubTemplate($data);
                if (empty($sub_template)) {
                    Db::rollBack();
                    return fail();
                }
            }
        }

        return success();
    }

    /**
     * 修改用户头像
     * @return array
     * @throws GuzzleException
     */
    public function putUserAvatar(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $avatar = $this->request->input('avatar');

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

        // 匹配去除oss网址
        $avatar = PcreMatch::pregRemoveOssWebsite($avatar);

        Db::beginTransaction();
        try {
            // 修改用户表
            $data = array();
            $data['avatar'] = $avatar;

            $params = array();
            $params['user_id'] = $user_info['user_id'];
            User::editUser($params, $data);

            // 获取对应用户信息
            if ($user['user_type'] == 1) {
                // 患者
                $params = array();
                $params['user_id'] = $user_info['user_id'];
                $user_patient = UserPatient::getOne($params);
                if (empty($user_patient)) {
                    Db::rollBack();
                    return fail();
                }

                if ($user_patient['avatar'] != $avatar) {
                    $data = array();
                    $data['avatar'] = $avatar;

                    $params = array();
                    $params['patient_id'] = $user_patient['patient_id'];
                    UserPatient::editUserPatient($params, $data);
                }
            } elseif ($user['user_type'] == 2) {
                // 医生
                $params = array();
                $params['user_id'] = $user_info['user_id'];
                $user_doctor = UserDoctor::getOne($params);
                if (empty($user_doctor)) {
                    Db::rollBack();
                    return fail();
                }

                if ($user_doctor['avatar'] != $avatar) {
                    $data = array();
                    $data['avatar'] = $avatar;

                    $params = array();
                    $params['doctor_id'] = $user_doctor['doctor_id'];
                    UserDoctor::editUserDoctor($params, $data);
                }
            } elseif ($user['user_type'] == 3) {
                // 药师
                $params = array();
                $params['user_id'] = $user_info['user_id'];
                $user_pharmacist = UserPatient::getOne($params);
                if (empty($user_pharmacist)) {
                    Db::rollBack();
                    return fail();
                }

                if ($user_pharmacist['avatar'] != $avatar) {
                    $data = array();
                    $data['avatar'] = $avatar;

                    $params = array();
                    $params['pharmacist_id'] = $user_pharmacist['pharmacist_id'];
                    UserPatient::editUserPatient($params, $data);
                }
            }

            // 修改im头像
            $profile = new Profile();
            $arg = array();
            $arg['Tag_Profile_IM_Image'] = addAliyunOssWebsite($avatar);
            $profile->setProfile($user_info['user_id'], $arg);

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

        return success();
    }

    /**
     * 修改用户名
     * @return array
     */
    public function putUserName(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $user_name = $this->request->input('user_name');

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

        if ($user['user_type'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "禁止修改");
        }

        if ($user['user_name'] == $user_name) {
            return success();
        }

        Db::beginTransaction();
        try {
            // 修改用户表
            $data = array();
            $data['user_name'] = $user_name;

            $params = array();
            $params['user_id'] = $user['user_id'];
            User::editUser($params, $data);

            // 修改对应用户表
            if ($user['user_type'] == 1) {
                // 患者
                $data = array();
                $data['user_name'] = $user_name;

                $params = array();
                $params['user_id'] = $user['user_id'];
                UserPatient::editUserPatient($params, $data);
            }

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

        return success();
    }

    /**
     * 退出登陆
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function putLoginout(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

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

        // 获取token
        $bearer_token = $this->request->getHeader('Authorization');
        if (empty($bearer_token)) {
            return fail();
        }

        $token = explode(' ', $bearer_token[0]);
        if (!isset($token[1])) {
            return fail();
        }

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

        // 旧token加入黑名单 5天有效期，5天内，无法继续进行访问
        $res = $redis->set('jwt_black_' . $token[1], time(), 60 * 60 * 24 * 5);
        if (!$res) {
            return fail(HttpEnumCode::SERVER_ERROR);
        }

        return success();
    }

    /**
     * 获取用户收获地址列表
     * @return array
     */
    public function getUserAddress(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $params = array();
        $params['user_id'] = $user_info['user_id'];
        $user_ship_address = UserShipAddress::getList($params);
        if (empty($user_ship_address)) {
            return success();
        }

        return success($user_ship_address->toArray());
    }

    /**
     * 获取用户收获地址详情
     * @return array
     */
    public function getUserAddressInfo(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $address_id = $this->request->route('address_id');

        $params = array();
        $params['address_id'] = $address_id;
        $params['user_id'] = $user_info['user_id'];
        $user_ship_address = UserShipAddress::getOne($params);
        if (empty($user_ship_address)) {
            return fail();
        }

        return success($user_ship_address->toArray());
    }

    /**
     * 添加用户收获地址
     * @return array
     */
    public function addUserAddress(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $request_params = $this->request->all();

        $areaService = new AreaService();
        $req = $areaService->checkAreaById($request_params['province_id'], $request_params['city_id'], $request_params['county_id']);
        if (empty($req)) {
            return fail(HttpEnumCode::HTTP_ERROR, "地区选择错误");
        }

        $area = $areaService->getAreaById($request_params['province_id'], $request_params['city_id'], $request_params['county_id']);

        Db::beginTransaction();

        try {
            if ($request_params['is_default'] == 1) {
                // 获取默认地址
                $params = array();
                $params['user_id'] = $user_info['user_id'];
                $params['is_default'] = $request_params['is_default'];
                $user_ship_address = UserShipAddress::getOne($params);
                if (!empty($user_ship_address)) {
                    $data = array();
                    $data['is_default'] = 0;

                    $params = array();
                    $params['address_id'] = $user_ship_address['address_id'];
                    $params['user_id'] = $user_info['user_id'];
                    UserShipAddress::edit($params, $data);
                }
            }

            // 新增
            $data = array();
            $data['user_id'] = $user_info['user_id'];
            $data['province_id'] = $request_params['province_id'];
            $data['province'] = $area['province']['area_name'];
            $data['city_id'] = $request_params['city_id'];
            $data['city'] = $area['city']['area_name'];
            $data['county_id'] = $request_params['county_id'];
            $data['county'] = $area['county']['area_name'];
            $data['address'] = $request_params['address'];
            $data['address_mask'] = Mask::maskAddressStr($request_params['address']);
            $data['consignee_name'] = $request_params['consignee_name'];
            $data['consignee_name_mask'] = Mask::maskNameStr($request_params['consignee_name']);
            $data['consignee_tel'] = $request_params['consignee_tel'];
            $data['consignee_tel_mask'] = Mask::maskPhoneStr($request_params['consignee_tel']);
            $data['is_default'] = $request_params['is_default'];
            $data['tag'] = $request_params['tag'] ?? "";
            $user_ship_address = UserShipAddress::addUserShipAddress($data);
            if (empty($user_ship_address)) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR);
            }

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

        return success();
    }

    /**
     * 修改用户收获地址
     * @return array
     */
    public function putUserAddress(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $request_params = $this->request->all();
        $address_id = $this->request->route('address_id');

        $params = array();
        $params['address_id'] = $address_id;
        $params['user_id'] = $user_info['user_id'];
        $user_ship_address = UserShipAddress::getOne($params);
        if (empty($user_ship_address)) {
            return fail();
        }

        $data = array();

        if ($user_ship_address['province_id'] != $request_params['province_id'] || $user_ship_address['city_id'] != $request_params['city_id'] || $user_ship_address['county_id'] != $request_params['county_id']) {
            $areaService = new AreaService();
            $req = $areaService->checkAreaById($request_params['province_id'], $request_params['city_id'], $request_params['county_id']);
            if (empty($req)) {
                return fail(HttpEnumCode::HTTP_ERROR, "地区选择错误");
            }

            $area = $areaService->getAreaById($request_params['province_id'], $request_params['city_id'], $request_params['county_id']);

            $data['province_id'] = $request_params['province_id'];
            $data['province'] = $area['province']['area_name'];
            $data['city_id'] = $request_params['city_id'];
            $data['city'] = $area['city']['area_name'];
            $data['county_id'] = $request_params['county_id'];
            $data['county'] = $area['county']['area_name'];
        }

        if ($user_ship_address['address'] != $request_params['address']) {
            $data['address'] = $request_params['address'];
            $data['address_mask'] = Mask::maskAddressStr($request_params['address']);
        }

        if ($user_ship_address['consignee_name'] != $request_params['consignee_name']) {
            $data['consignee_name'] = $request_params['consignee_name'];
            $data['consignee_name_mask'] = Mask::maskNameStr($request_params['consignee_name']);
        }

        if ($user_ship_address['consignee_tel'] != $request_params['consignee_tel']) {
            $data['consignee_tel'] = $request_params['consignee_tel'];
            $data['consignee_tel_mask'] = Mask::maskPhoneStr($request_params['consignee_tel']);
        }

        if ($user_ship_address['tag'] != $request_params['tag']) {
            $data['tag'] = $request_params['tag'];
        }

        if ($user_ship_address['is_default'] != $request_params['is_default']) {
            $data['is_default'] = $request_params['is_default'];
        }

        Db::beginTransaction();
        try {
            if ($request_params['is_default'] == 1 && $user_ship_address['is_default'] != $request_params['is_default']) {
                // 获取默认地址
                $params = array();
                $params['user_id'] = $user_info['user_id'];
                $params['is_default'] = $request_params['is_default'];
                $default_user_ship_address = UserShipAddress::getOne($params);
                if (!empty($default_user_ship_address)) {
                    $default_data = array();
                    $default_data['is_default'] = 0;

                    $params = array();
                    $params['address_id'] = $default_user_ship_address['address_id'];
                    $params['user_id'] = $user_info['user_id'];
                    UserShipAddress::edit($params, $default_data);
                }
            }

            if (!empty($data)) {
                $params = array();
                $params['address_id'] = $user_ship_address['address_id'];
                UserShipAddress::edit($params, $data);
            }

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

        return success();
    }

    /**
     * 删除用户收获地址
     * @return array
     */
    public function deleteUserAddress(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $address_id = $this->request->route('address_id');

        $params = array();
        $params['address_id'] = $address_id;
        $params['user_id'] = $user_info['user_id'];
        $user_ship_address = UserShipAddress::getOne($params);
        if (empty($user_ship_address)) {
            return fail();
        }

        $res = UserShipAddress::deleteUserShipAddress($params);
        if (!$res){
            return fail(HttpEnumCode::SERVER_ERROR);
        }

        return success();
    }

    /**
     * 通过user_id获取用户openid
     * @param string|int $user_id
     * @param int $user_type
     * @return string
     */
    public function getOpenIdWithUserId(string|int $user_id, int $user_type): string
    {
        $open_id = '';
        if ($user_type == 1) {
            // 患者
            $params = array();
            $params['user_id'] = $user_id;
            $user_patient = UserPatient::getOne($params);
            if (empty($user_patient)) {
                return "";
            }

            if (empty($user_patient['open_id'])) {
                return "";
            }

            $open_id = $user_patient['open_id'];
        } elseif ($user_type == 2) {
            // 医生
            $params = array();
            $params['user_id'] = $user_id;
            $user_doctor = UserDoctor::getOne($params);
            if (empty($user_doctor)) {
                return "";
            }

            if (empty($user_doctor['open_id'])) {
                return "";
            }

            $open_id = $user_doctor['open_id'];
        } elseif ($user_type == 3) {
            // 药师
            $params = array();
            $params['user_id'] = $user_id;
            $user_pharmacist = UserPatient::getOne($params);
            if (empty($user_pharmacist)) {
                return "";
            }

            if (empty($user_pharmacist['open_id'])) {
                return "";
            }

            $open_id = $user_pharmacist['open_id'];
        }

        return $open_id;
    }


}