package com.ywt.outpatient.service.web;

import com.ywt.biz.common.enums.TerminalEnum;
import com.ywt.biz.common.util.StringHelper;
import com.ywt.gapi.Result;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.doctor.DoctorService;
import com.ywt.gapi.doctor.GetDoctorRequest;
import com.ywt.gapi.doctor.GetDoctorResponse;
import com.ywt.gapi.user.*;
import com.ywt.outpatient.core.BaseResponse;
import com.ywt.outpatient.domain.models.DoctorInfo;
import com.ywt.outpatient.core.WebAppContext;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


@Service
public class UserSrv {
    private static Logger logger = LoggerFactory.getLogger(UserSrv.class);

    @DubboReference
    private UserService userServiceBlockingStub;

    @DubboReference
    private DoctorService doctorServiceBlockingStub;

    /**
     * 获取当前登录用户Id
     * <p>
     * 当前登录终端为互联网医院医生端小程序与公众号（终端值分别为 16、13）时，
     * 登录用户Id根据当前的 unionid、openid 和 terminal 获取。
     * 因为前期导入系统的医生手机号大多是已经不用的，部分医生需要
     * 通过修改 sns_user_info 表的 user_id 字段来实现与旧手机号的账户关联，
     * 为了使修改后的值能立马生效，故不从网关读取当前用户ID。
     *
     * @return 当前登录用户Id
     */
    public int getCurrentUserId() {
        int terminal = getCurrentTerminal();
        if (terminal == TerminalEnum.TAI_HE_INTERNET_HOSPITAL_DOCTOR_WX_OFFICIAL.getValue() ||
                terminal == TerminalEnum.DOCTOR_MINI_PROGRAM.getValue()) {
            try {
                GetOfficialUserInfoRequest req = GetOfficialUserInfoRequest.newBuilder()
                        .setUnionId(WebAppContext.current().getUnionId())
                        .setTerminal(terminal)
                        .setOpenId(WebAppContext.current().getOpenId())
                        .build();
                GetOfficialUserInfoResponse response = userServiceBlockingStub.getOfficialUserInfo(req);
                if (response.getResult().getCode() == ResultCode.SUCCEED) {
                    return response.getUserId();
                }
            } catch (Exception e) {
                logger.error("getCurrentUserId(terminal-{}): {}", terminal, e.getMessage(), e);
            }
        }
        return WebAppContext.current().getUserId();
    }

    /**
     * 互联网患者端的请求，根据 unionId 获取对应的太和公众号 userId
     * @return 太和公众号 userId
     */
    public int getTaiheUserId() {
        int currentTerminal = getCurrentTerminal();
        String openId = getCurrentOpenId();
        String unionId = getCurrentUnionId();
        if (currentTerminal == TerminalEnum.TAI_HE_INTERNET_HOSPITAL_PATIENT_MINI_PROGRAM.getValue()) {
            try {
                // 根据 unionId & terminal 获取 snsUserInfo
                GetOfficialUserInfoRequest req = GetOfficialUserInfoRequest.newBuilder()
                        .setUnionId(unionId)
                        .setTerminal(TerminalEnum.TaiheWxOfficial.getValue())
                        .build();
                GetOfficialUserInfoResponse response = userServiceBlockingStub.getOfficialUserInfo(req);
                if (response.getResult().getCode() == ResultCode.SUCCEED) {
                    return response.getUserId();
                } else {
                    logger.info("UserSrv#getTaiheUserId(currentTerminal={} , unionId={} , openId={} ):\n获取 OfficialUserInfo 失败：{}",
                            currentTerminal, unionId, openId, response.getResult().getInfo());
                }
            } catch (Exception e) {
                logger.error("UserSrv#getTaiheUserId(currentTerminal={} , unionId={} , openId={} ):\n {}",
                        currentTerminal, unionId, openId, e.getMessage(), e);
            }
        }
        // 直接返回当前网关记录的 userId
        return WebAppContext.current().getUserId();
    }

    /**
     * A wrapped method to get cuid, useful for test especially.
     * @return cuid
     */
    public int getCurrentUserIdWrapped() {
//        return 5;
         return getCurrentUserId();
    }

    /**
     * 当前登录终端
     *
     * @return
     */
    public int getCurrentTerminal() {
        return WebAppContext.current().getTerminal();
//        return TerminalEnum.TAI_HE_INTERNET_HOSPITAL_DOCTOR_WX_OFFICIAL.getValue();
//        return TerminalEnum.TAI_HE_INTERNET_HOSPITAL_PATIENT_WX_OFFICIAL.getValue();
//        return TerminalEnum.TAI_HE_INTERNET_HOSPITAL_PATIENT_MINI_PROGRAM.getValue();
    }

    public String getCurrentOpenId() {
//        return "odOOe4qFM9V1z_vdoEhGD6c8-l4Y";
        return WebAppContext.current().getOpenId();
    }

    public String getCurrentUnionId() {
//        return "omLSUweHiKFZgoEs-0E0KHk3JOlY";
        return WebAppContext.current().getUnionId();
    }


    public Result bindWx(String mobile, String unionId, String openId, String ip, TerminalEnum terminalEnum) {
        BindWxRequest req = BindWxRequest.newBuilder()
                .setMobile(mobile)
                .setUnionId(unionId)
                .setOpenId(openId)
                .setIp(ip)
                .setTerminal(terminalEnum.getValue())
                .build();
        return userServiceBlockingStub.bindWx(req);
    }

    public BaseResponse getUserInfoByCode(String code, TerminalEnum terminalEnum) {
        BaseResponse response = new BaseResponse();

        if (StringHelper.isNullOrWhiteSpace(code)) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "invalid code");
        }

        GetUserInfoByCodeRequest req = GetUserInfoByCodeRequest.newBuilder()
                .setCode(code)
                .setType(terminalEnum.getValue())
                .build();
        GetUserInfoByCodeResponse res = userServiceBlockingStub.getUserInfoByCode(req);
        Result result = res.getResult();

        if (result.getCode() == ResultCode.SUCCEED) {
            Map<String, Object> map = new HashMap<>();
            map.put("unionId", res.getUnionId());
            map.put("userId", res.getUserId());
            map.put("openId", res.getOpenId());
            return response.succeed(map);
        }

        return response.failed(BaseResponse.PARAMETER_ERROR, result.getInfo());
    }

    public LoginResponse loginByMobile(String mobile, String ip, int loginType) {
        LoginByMobileRequest req = LoginByMobileRequest.newBuilder()
                .setMobile(mobile)
                .setIp(ip)
                .setUserType(loginType)
                .build();
        return userServiceBlockingStub.loginByMobile(req);
    }

    public com.ywt.outpatient.domain.models.DoctorInfo getDoctorInfo(int doctorId) {
        DoctorInfo doctorInfo = null;

        try {
            GetDoctorRequest req = GetDoctorRequest.newBuilder().setDoctorId(doctorId).build();
            GetDoctorResponse resp = doctorServiceBlockingStub.getDoctor(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                com.ywt.gapi.doctor.DoctorInfo info = resp.getDoctorInfo();
                doctorInfo = new com.ywt.outpatient.domain.models.DoctorInfo();
                doctorInfo.setDoctorId(info.getDoctorid());
                doctorInfo.setAvatar(info.getAvatar());
                doctorInfo.setName(info.getName());
                doctorInfo.setQrCodeUrl(info.getQrCodeUrl());
                doctorInfo.setHospitalName(info.getHospital());
                doctorInfo.setDeptName(info.getDept());
                doctorInfo.setTitle(info.getTitle());
                doctorInfo.setSpecialty(info.getSpecialty());
                doctorInfo.setScheduleStatus(info.getScheduleStatus());
                doctorInfo.setAuthType(info.getAuthType());
            }
        } catch (Exception e) {
            logger.error("getDoctorInfo({}): {}", doctorId, e.getMessage(), e);
        }
        return doctorInfo;
    }

    public String getCurrentNickName() {
        String nickName = "";
        try {
            GetOfficialUserInfoRequest req = GetOfficialUserInfoRequest.newBuilder()
                    .setHospitalId(0)
                    .setUnionId(getCurrentUnionId())
                    .setTerminal(getCurrentTerminal())
                    .setOpenId(getCurrentOpenId())
                    .build();
            GetOfficialUserInfoResponse response = userServiceBlockingStub.getOfficialUserInfo(req);
            Result result = response.getResult();
            if (result.getCode() == ResultCode.SUCCEED) {
                nickName = response.getNickname();
            }
        } catch (Exception e) {
            logger.error("getCurrentNickName(): {}", e.getMessage(), e);
        }
        return nickName;
    }

//    /**
//     * 获取当前登录用户信息
//     *
//     * @return
//     */
//    public LoginInfo getCurrentLoginInfo() {
//        LoginInfo loginInfo = null;
//        int currentDoctorId = getCurrentUserId();
//
//        if (currentDoctorId > 0) {
//            try {
//                if (TerminalEnum.checkDoctorTerminal(getCurrentTerminal())) {
//                    //医生终端
//                    GetDoctorRequest req = GetDoctorRequest.newBuilder().setDoctorId(currentDoctorId).build();
//                    GetDoctorResponse resp = doctorServiceBlockingStub.getDoctor(req);
//                    Result result = resp.getResult();
//
//                    if (result.getCode() == ResultCode.SUCCEED) {
//                        DoctorInfo info = resp.getDoctorInfo();
//                        loginInfo = new LoginInfo();
//                        loginInfo.setUserId(info.getDoctorid());
//                        loginInfo.setAvatar(info.getAvatar());
//                        loginInfo.setRealName(info.getName());
//                        loginInfo.setQrCodeUrl(info.getQrCodeUrl());
//                        loginInfo.setHospitalName(info.getHospital());
//                        loginInfo.setDeptName(info.getDept());
//                        loginInfo.setTitle(info.getTitle());
//                        loginInfo.setSpecialty(info.getSpecialty());
//                        loginInfo.setScheduleStatus(info.getScheduleStatus());
//                        loginInfo.setAuthType(info.getAuthType());
//                    }
//                } else {
//
//                }
//            } catch (Exception e) {
//                logger.error("getCurrentLoginInfo(): {}", e.getMessage(), e);
//            }
//        }
//        return doctorInfo;
//    }


    /**
     * 根据userId得到当前用户信息
     *
     * @return
     */
    public User findByUserId() {
        int userId = getCurrentUserIdWrapped();
        try {
            UserRequest req = UserRequest.newBuilder()
                    .setUserid(userId)
                    .build();
            UserResponse resp = userServiceBlockingStub.findByUserId(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                User user = resp.getUser();
                return user;
            }
        } catch (Exception e) {
            logger.error("findByUserId({}): {}", userId, e.getMessage(), e);
        }
        return null;
    }

}
