package thyyxxk.webserver.service;

import cn.hutool.crypto.SecureUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.LoginDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.dictionary.CodeName;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.service.hutoolcache.UserCache;
import thyyxxk.webserver.service.outpatient.wxapi.SendWxInfoService;
import thyyxxk.webserver.utils.*;

import java.util.*;

/**
 * @author dj
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LoginService {
    private final LoginDao dao;
    private final UserCache userCache;
    private final PublicServer publicServer;
    private final SendWxInfoService sendWxInfoService;

    @Data
    public static class Verification {
        private String codeRs;
        private String code;
        private String newPwd;
    }

    public ResultVo<UserInfo> login(UserInfo userInfo, boolean encrypt) {
        UserInfo tempUserInfo = dao.findUserByCodeRsFromDjUserBase(userInfo.getCodeRs());
        if (null == tempUserInfo) {
            tempUserInfo = dao.findUserByCodeRsFromEmployeeMi(userInfo.getCodeRs());
            if (null == tempUserInfo) {
                return ResultVoUtil.fail(ExceptionEnum.USER_NOT_EXIST);
            }
            dao.insertNewUserToDjUserBase(tempUserInfo);
        }
        String pwd = encrypt ? SecureUtil.md5(userInfo.getPassword()) : userInfo.getPassword();
        boolean through
                = !Objects.equals("fromTriageScreen", userInfo.getSid())
                  && !pwd.equals(tempUserInfo.getPassword());
        if (through) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PASSWORD, userInfo);
        }
        String token = TokenUtil.getInstance().createToken(tempUserInfo.getCode(), pwd);
        tempUserInfo = userCache.get(tempUserInfo.getCode());
        tempUserInfo.setToken(token);
        return ResultVoUtil.success(tempUserInfo);
    }

    public ResultVo<String> sendAVerificationCode(String codeRs) {
        SendWxInfoService.Verification v = sendWxInfoService.sendResetPassword(codeRs);
        if (v.getVerificationCode() != null) {
            dao.updateVerificationCodeByCodeRs(codeRs, v.getVerificationCode(), DateUtil.offsetHour(new Date(), 30));
            return ResultVoUtil.success("验证码已发送。");
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "发送验证码错误，请联系人资，把您企业微信的账号修改为您的工号。");
    }

    public ResultVo<String> checkVerificationCode(String codeRs, String verificationCode) {
        int count = dao.checkVerificationCode(codeRs, verificationCode);
        if (count > 0) {
            dao.updatePasswordByCodeRs(codeRs);
            return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "密码已重置，默认密码为123456");
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "验证码过期或者验证码错误。");
    }


    public ResultVo<String> checkVerificationCodeV2(Verification verification) {
        int count = dao.checkVerificationCode(verification.getCodeRs(), verification.getCode());
        if (count > 0) {
            dao.updatePasswordByCodeRsV2(verification.getCodeRs(), SecureUtil.md5(verification.getNewPwd()));
            return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "验证成功，密码已修改");
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "验证码过期或者验证码错误。");
    }

    public ResultVo<UserInfo> simpleLogin(String code) {
        UserInfo us = dao.getUserInfoByCode(code);
        if (us == null) {
            return ResultVoUtil.fail(ExceptionEnum.NOT_EL_MESSAGE, "用户不存在");
        }
        return login(us, false);
    }

    public ResultVo<List<CodeName>> getWards() {
        String code = TokenUtil.getInstance().getTokenUserId();
        if (publicServer.needRule(2, 8, 52)) {
            return ResultVoUtil.success(dao.getAllWards());
        }
        return ResultVoUtil.success(dao.getUserWards(code));
    }

    public ResultVo<List<CodeName>> getAllWards() {
        return ResultVoUtil.success(dao.getAllWards());
    }

    public static String makeSid(String code, String sid, String ip) {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        if ("fromTriageScreen".equals(sid)) {
            uuid += "-triageFloorScreen";
        } else {
            uuid = "-" + ip + "-" + uuid;
        }
        return code + uuid;
    }

    public UserInfo getUserInfoByCode() {
        return userCache.getUserInfoByToken();
    }

}
