package com.ruoyi.framework.web.service;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.cms.domain.vo.WechatAuthVO;
import com.ruoyi.cms.service.IAppUserService;
import com.ruoyi.cms.util.StringUtil;
import com.ruoyi.cms.util.WechatUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginSiteUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.redis.DistributedLockUtil;
import com.ruoyi.common.utils.*;
import com.ruoyi.framework.web.exception.ParamErrorConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.BlackListException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserNotExistsException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 登录校验方法
 * 
 * @author ruoyi
 */
@Component
public class SysLoginService
{
    @Autowired
    private TokenService tokenService;

    @Resource
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;
    
    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private TokenSiteService tokenSiteService;
    @Autowired
    WechatUtil wechatUtil;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private DistributedLockUtil distributedLockUtil;

    /**
     * 登录验证
     * 
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    public String login(String username, String password, String code, String uuid)
    {
        // 验证码校验
        validateCaptcha(username, code, uuid);
        // 登录前置校验
        loginPreCheck(username, password);
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        finally
        {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }
    //模拟登录
    public String loginApp(String username, String password)
    {

        AppUser appUser = userService.selectAppUserById(1L);
        LoginSiteUser loginSiteUser = new LoginSiteUser();
        loginSiteUser.setUserId(appUser.getUserId());
        loginSiteUser.setUser(appUser);
        recordLoginInfo(appUser);
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        recordLoginInfo(appUser);
        // 生成token
        return tokenSiteService.createToken(loginSiteUser);
    }

    /**
     * 根据微信生成的
     * @param appUser
     * @return
     */
    public String loginUserIdApp(AppUser appUser)
    {
        LoginSiteUser loginSiteUser = new LoginSiteUser();
        loginSiteUser.setUserId(appUser.getUserId());
        loginSiteUser.setUser(appUser);
        recordLoginInfo(appUser);
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(appUser.getName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        recordLoginInfo(appUser);
        // 生成token //tokenSiteService.createToken(loginSiteUser) 有时间
        return tokenSiteService.noExpireCreateToken(loginSiteUser);
    }

    //单点登录
    public String loginOss(String ticket)
    {
        return "tokenService.createToken(loginUser)";
    }
    /**
     * 校验验证码
     * 
     * @param username 用户名
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    public void validateCaptcha(String username, String code, String uuid)
    {
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        if (captchaEnabled)
        {
            String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
            String captcha = redisCache.getCacheObject(verifyKey);
            if (captcha == null)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
                throw new CaptchaExpireException();
            }
            redisCache.deleteObject(verifyKey);
            if (!code.equalsIgnoreCase(captcha))
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
                throw new CaptchaException();
            }
        }
    }
    public void recordLoginInfo(AppUser user)
    {
        AppUser sysUser = new AppUser();
        sysUser.setUserId(user.getUserId());
        sysUser.setLoginIp(IpUtils.getIpAddr());
        sysUser.setLoginDate(DateUtils.getNowDate());
        sysUser.setUpdateBy(user.getName());
//        userService.updateSiteUser(sysUser);
    }
    /**
     * 登录前置校验
     * @param username 用户名
     * @param password 用户密码
     */
    public void loginPreCheck(String username, String password)
    {
        // 用户名或密码为空 错误
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
            throw new UserNotExistsException();
        }
        // 密码如果不在指定范围内 错误
        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
            throw new UserPasswordNotMatchException();
        }
        // 用户名不在指定范围内 错误
        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
            throw new UserPasswordNotMatchException();
        }
        // IP黑名单校验
        String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
            throw new BlackListException();
        }
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(Long userId)
    {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setLoginIp(IpUtils.getIpAddr());
        sysUser.setLoginDate(DateUtils.getNowDate());
        userService.updateUserProfile(sysUser);
    }

    /**
     * 小程序微信授权登录
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult appLogin(LoginBody dto){
        AjaxResult ajax = AjaxResult.success();
        try {
            System.out.println("小程序微信授权登录---------参数列表========dto========"+ JSON.toJSONString(dto));
            JSONObject sessionInfo = wechatUtil.code2Session(dto.getCode());
            String openid = sessionInfo.getString("openid");
            String unionid = sessionInfo.getString("unionid");
            String sessionKey = sessionInfo.getString("session_key");
            if (openid == null) {
                return AjaxResult.error("微信授权失败");
            }
            //验证是否登录过
            AppUser existingUser=appUserService.selectByOpenid(openid,dto.getUserType());
            if(existingUser!=null){
                if(StringUtils.isEmpty(existingUser.getIsCompanyUser())){
                    updateAppUserCommon(existingUser,openid,unionid,dto.getUserType(),dto.getOrgType());
                }
                String token = loginUserIdApp(existingUser);
                ajax.put(Constants.TOKEN, token);
                ajax.put("isNewUser", false);
                ajax.put("idCard",existingUser.getIdCard());
                ajax.put("isCompanyUser",existingUser.getIsCompanyUser());
                System.out.println("返回ajax====================================="+JSON.toJSONString(ajax));
                return ajax;
            }else {
                JSONObject phoneInfo = wechatUtil.decryptPhoneNumber(dto.getEncryptedData(), sessionKey, dto.getIv());
                String phone = phoneInfo.getString("phoneNumber");
                if (phone == null) {
                    return AjaxResult.error("获取手机号失败");
                }

                // 3. 检查手机号是否已被绑定
                AppUser existUser = appUserService.getPhone(phone);
                String token="";
                boolean isNewUser=false;
                if (existUser != null) {
                    updateAppUserCommon(existUser,openid,unionid,dto.getUserType(),dto.getOrgType());
                    // 5. 生成系统令牌
                    token = loginUserIdApp(existUser);
                    ajax.put("idCard",existUser.getIdCard());
                    ajax.put("isCompanyUser",existUser.getIsCompanyUser());
                }else{
                    // 4. 创建用户并存储所有信息
                    AppUser appUser = new AppUser();
                    appUser.setOpenid(openid);
                    appUser.setUnionid(unionid);
                    appUser.setPhone(phone);
                    appUser.setIsCompanyUser(dto.getUserType());//保存角色
                    appUserService.insertAppUser(appUser);
                    // 5. 生成系统令牌
                    token = loginUserIdApp(appUser);
                    isNewUser=true;
                    ajax.put("idCard",null);
                    ajax.put("isCompanyUser",dto.getUserType());
                }
                ajax.put("isNewUser", isNewUser);
                ajax.put(Constants.TOKEN, token);
                System.out.println("返回ajax====================================="+JSON.toJSONString(ajax));
                return ajax;
            }
        }catch (Exception e) {
            System.err.println("登录失败：" + e.getMessage());
            return AjaxResult.error("登录失败，请稍后重试");
        }
    }

    /**
     * 小程序登录主逻辑
     * 核心逻辑：优先处理网格员（is_company_user=2），再处理普通招聘者/求职者
     */
    public AjaxResult appLoginNew(LoginBody dto) {
        // 1. 验证基础参数（前端userType仅0/1，拦截非法参数）
        AjaxResult validateResult = validateBaseParam(dto);
        if (validateResult != null) {
            return validateResult;
        }

        try {
            // 2. 微信授权获取OpenID/UnionID/SessionKey（网格员查询依赖OpenID）
            WechatAuthVO wechatAuthVO = getWechatAuthInfo(dto.getCode());
            if (wechatAuthVO == null) {
                System.err.println("小程序登录失败：微信授权返回null");
                return AjaxResult.error("微信授权失败");
            }
            String openid = wechatAuthVO.getOpenid();
            String unionid = wechatAuthVO.getUnionid();
            String sessionKey = wechatAuthVO.getSessionKey();
            if (StringUtils.isEmpty(openid)) {
                System.err.println("小程序登录失败：微信授权返回openid为空");
                return AjaxResult.error("微信授权失败");
            }

            // 3. 第一步：通过OpenID优先查询网格员（无需解密手机号，效率更高）
            AppUser openidSpecialUser = appUserService.selectByOpenid(openid, StringUtil.IS_GRID_USER);
            if (openidSpecialUser != null) {
                System.out.printf("小程序登录-匹配到OpenID网格员：openid=%s, phone=%s%n",
                        openidSpecialUser.getOpenid(), openidSpecialUser.getPhone());
                return handleSpecialUserLogin(openidSpecialUser);
            }

            // 4. 解密获取手机号（含二次校验）- 网格员兜底查询/普通用户登录依赖
            String phone = decryptPhone(dto, sessionKey);
            if (phone == null) {
                System.err.println("小程序登录失败：手机号解密失败，openid=" + openid);
                return AjaxResult.error("获取手机号失败");
            }

            // 5. 第二步：通过手机号查询网格员（OpenID未匹配时兜底）
            AppUser phoneSpecialUser = appUserService.getPhoneAndUserType(phone, StringUtil.IS_GRID_USER);
            if (phoneSpecialUser != null) {
                System.out.printf("小程序登录-匹配到手机号网格员：phone=%s, openid=%s%n",
                        phoneSpecialUser.getPhone(), phoneSpecialUser.getOpenid());
                return handleSpecialUserLogin(phoneSpecialUser);
            }

            // 6. 非网格员：处理普通用户（招聘者/求职者）登录逻辑
            String userType = dto.getUserType();
            // 6.1 优先匹配「OpenID+前端传入角色」的老用户
            AppUser existingUser = appUserService.selectByOpenid(openid, userType);
            if (existingUser != null) {
                System.out.printf("小程序登录-匹配到普通老用户：openid=%s, userType=%s%n", openid, userType, dto.getOrgType());
                return handleExistingUser(existingUser, userType,dto.getOrgType());
            }

            // 6.2 处理普通用户的匹配与注册（手机号绑定、新用户创建等）
            return handleUserMatchAndRegister(openid, unionid, phone, userType,dto.getOrgType());

        } catch (Exception e) {
            System.err.println("小程序登录异常：" + e.getMessage());
            e.printStackTrace();
            return AjaxResult.error("登录失败，请稍后重试");
        }
    }

    /**
     * 1-基础参数校验（原validateLoginParam false场景）
     * @param dto
     * @return
     */
    private AjaxResult validateBaseParam(LoginBody dto) {
        if (dto == null) {
            return AjaxResult.error(ParamErrorConstants.PARAM_NULL_MSG);
        }
        if (StringUtils.isEmpty(dto.getCode())) {
            return AjaxResult.error(ParamErrorConstants.CODE_EMPTY_MSG);
        }
        String userType = dto.getUserType();
        if (StringUtils.isEmpty(userType) ||
                !StringUtil.IS_COMPANY_USER.equals(userType) &&
                        !StringUtil.IS_JOB_REQUEST_USER.equals(userType)) {
            return AjaxResult.error(ParamErrorConstants.USER_TYPE_INVALID_MSG);
        }
        return null;
    }

    /**
     * 2-微信授权信息获取（封装code2Session逻辑）
     * @param code
     * @return
     */
    private WechatAuthVO getWechatAuthInfo(String code) {
        JSONObject sessionInfo = wechatUtil.code2Session(code);
        if (sessionInfo == null || sessionInfo.getString("openid") == null) {
            return null;
        }
        WechatAuthVO authVO = new WechatAuthVO();
        authVO.setOpenid(sessionInfo.getString("openid"));
        authVO.setUnionid(StringUtils.isBlank(sessionInfo.getString("unionid")) ? "" : sessionInfo.getString("unionid"));
        authVO.setSessionKey(sessionInfo.getString("session_key"));
        return authVO;
    }

    /**
     * 3-手机号解密（含二次参数校验）
     * @param dto
     * @param sessionKey
     * @return
     */
    private String decryptPhone(LoginBody dto, String sessionKey) {
        // 二次校验（解密相关参数）
        AjaxResult validateResult = validateDecryptParam(dto);
        if (validateResult != null) {
            return null;
        }
        // 解密手机号
        JSONObject phoneInfo = wechatUtil.decryptPhoneNumber(dto.getEncryptedData(), sessionKey, dto.getIv());
        String phone = phoneInfo.getString("phoneNumber");
        if (phone == null || phone.trim().isEmpty()) {
            return null;
        }
        return phone.trim();
    }

    /**
     * 4-解密参数校验（原validateLoginParam true场景）
     * @param dto
     * @return
     */
    private AjaxResult validateDecryptParam(LoginBody dto) {
        if (StringUtils.isEmpty(dto.getEncryptedData())) {
            return AjaxResult.error(ParamErrorConstants.ENCRYPTED_DATA_EMPTY_MSG);
        }
        if (StringUtils.isEmpty(dto.getIv())) {
            return AjaxResult.error(ParamErrorConstants.IV_EMPTY_MSG);
        }
        return null;
    }

    /**
     * 5-用户匹配与注册（含锁逻辑、无角色数据处理）
     * @param openid
     * @param unionid
     * @param phone
     * @param userType
     * @return
     */
    private AjaxResult handleUserMatchAndRegister(String openid, String unionid, String phone, String userType,String orgType) {
        // 匹配「手机号+角色」的用户
        AppUser phoneRoleUser = appUserService.getPhoneAndUserType(phone, userType);
        if (phoneRoleUser != null) {
            return handlePhoneBoundUser(phoneRoleUser, openid, unionid, userType,orgType);
        }

        // 匹配无角色历史数据
        AppUser noRoleUser = appUserService.getPhoneAndNoRole(phone);
        if (noRoleUser != null) {
            return handleNoRoleUserBinding(openid, unionid, phone, userType, noRoleUser,orgType);
        }

        // 全新用户注册
        return handleNewUserRegistration(openid, unionid, phone, userType,orgType);
    }

    /**
     * 6-无角色用户绑定（含分布式锁）
     * @param openid
     * @param unionid
     * @param phone
     * @param userType
     * @param noRoleUser
     * @return
     */
    private AjaxResult handleNoRoleUserBinding(String openid, String unionid, String phone, String userType, AppUser noRoleUser,String orgType) {
        String lockKey = "login_no_role_bind_" + phone + "_" + userType;
        try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(lockKey, 3, TimeUnit.SECONDS)) {
            if (!lock.isLocked()) {
                return AjaxResult.error("登录请求过于频繁，请稍后重试");
            }
            // 双重检查
            AppUser doubleCheck = appUserService.getPhoneAndUserType(phone, userType);
            if (doubleCheck != null) {
                return handlePhoneBoundUser(doubleCheck, openid, unionid, userType,orgType);
            }
            return handlePhoneBoundUser(noRoleUser, openid, unionid, userType,orgType);
        }
    }

    /**
     * 7-新用户注册（含分布式锁）
     * @param openid
     * @param unionid
     * @param phone
     * @param userType
     * @return
     */
    private AjaxResult handleNewUserRegistration(String openid, String unionid, String phone, String userType,String orgType) {
        String createLockKey = "login_create_" + phone + "_" + userType;
        try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(createLockKey, 3, TimeUnit.SECONDS)) {
            if (!lock.isLocked()) {
                return AjaxResult.error("登录请求过于频繁，请稍后重试");
            }
            // 双重检查
            AppUser checkNew = appUserService.getPhoneAndUserType(phone, userType);
            if (checkNew != null) {
                return handlePhoneBoundUser(checkNew, openid, unionid, userType,orgType);
            }
            return handleNewUser(openid, unionid, phone, userType,orgType);
        }
    }

    /**
     * 8-特殊处理-网格员登录
     * @param specialUser
     * @return
     */
    private AjaxResult handleSpecialUserLogin(AppUser specialUser) {
        String lockKey = "login_grid_user_" + specialUser.getUserId(); // 按用户ID加锁
        try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(lockKey, 2, TimeUnit.SECONDS)) {
            if (!lock.isLocked()) {
                System.err.println("网格员登录请求过于频繁，userId=" + specialUser.getUserId());
                return AjaxResult.error("登录请求过于频繁，请稍后重试");
            }
            // 原有逻辑（更新登录时间、生成token）
            AjaxResult ajax = AjaxResult.success();
            updateAppUserCommon(specialUser, null, null, null,specialUser.getOrgType());
            String token = loginUserIdApp(specialUser);
            ajax.put(Constants.TOKEN, token);
            ajax.put("isNewUser", false);
            ajax.put("idCard", StringUtil.desensitizeIdCard(specialUser.getIdCard()));
            ajax.put("isCompanyUser", specialUser.getIsCompanyUser());
            System.out.printf("特殊角色用户登录成功，openid:%s, phone:%s, 角色:%s%n",
                    specialUser.getOpenid(), StringUtil.desensitizePhone(specialUser.getPhone()), specialUser.getIsCompanyUser());
            System.out.println(ParamErrorConstants.LOG_AJAX_RETURN + JSON.toJSONString(ajax));
            return ajax;
        }
    }

    /**
     * 处理老用户登录（日志用println）
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult handleExistingUser(AppUser existingUser, String userType,String orgType) {
        AjaxResult ajax = AjaxResult.success();
        updateAppUserCommon(existingUser, null, null, userType,orgType);
        String token = loginUserIdApp(existingUser);
        ajax.put(Constants.TOKEN, token);
        ajax.put("isNewUser", false);
        ajax.put("idCard", existingUser.getIdCard());
        ajax.put("isCompanyUser", existingUser.getIsCompanyUser());
        System.out.println("老用户登录成功，openid:" + existingUser.getOpenid() + "===========");
        System.out.println(ParamErrorConstants.LOG_AJAX_RETURN + JSON.toJSONString(ajax));
        return ajax;
    }


    /**
     * 处理手机号已绑定的用户
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult handlePhoneBoundUser(AppUser phoneUser, String openid, String unionid, String userType,String orgType) {
        AjaxResult ajax = AjaxResult.success();
        if (StringUtils.hasText(phoneUser.getOpenid()) && !openid.equals(phoneUser.getOpenid())) {
            System.out.printf("手机号绑定冲突，phone:%s, oldOpenid:%s, newOpenid:%s%n",
                    phoneUser.getPhone(), phoneUser.getOpenid(), openid);
            //如果手机号一致openid不一致重新注册小程序账号
            ajax=handleNewUser(openid,unionid,phoneUser.getPhone(),userType,orgType);
            return ajax;
        }
        //修改用户信息
        updateAppUserCommon(phoneUser, openid, unionid, userType,orgType);
        phoneUser.setOpenid(openid);
        phoneUser.setUnionid(unionid);
        phoneUser.setIsCompanyUser(userType);
        String token = loginUserIdApp(phoneUser);
        ajax.put(Constants.TOKEN, token);
        ajax.put("isNewUser", false);
        ajax.put("idCard", phoneUser.getIdCard());
        ajax.put("isCompanyUser", phoneUser.getIsCompanyUser());
        System.out.println("手机号绑定用户登录成功，phone:" + phoneUser.getPhone());
        System.out.println(ParamErrorConstants.LOG_AJAX_RETURN + JSON.toJSONString(ajax));
        return ajax;
    }

    /**
     * 处理新用户注册
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult handleNewUser(String openid, String unionid, String phone, String userType,String orgType) {
        AjaxResult ajax = AjaxResult.success();
        AppUser newUser = new AppUser();
        newUser.setOpenid(openid);
        newUser.setUnionid(unionid);
        newUser.setPhone(phone);
        newUser.setIsCompanyUser(userType);
        newUser.setLoginDate(new Date());
        newUser.setOrgType(orgType);
        appUserService.insertAppUser(newUser);
        String token = loginUserIdApp(newUser);
        ajax.put(Constants.TOKEN, token);
        ajax.put("isNewUser", true);
        ajax.put("idCard", null);
        ajax.put("isCompanyUser", userType);
        System.out.printf("新用户创建成功，openid:%s, phone:%s%n", openid, phone);
        System.out.println(ParamErrorConstants.LOG_AJAX_RETURN + JSON.toJSONString(ajax));
        return ajax;
    }

    /**
     * 抽取用户更新公共方法
     */
    private void updateAppUserCommon(AppUser targetUser, String openid, String unionid, String userType,String orgType) {
        AppUser updateParm = new AppUser();
        updateParm.setUserId(targetUser.getUserId());

        String currentRole = targetUser.getIsCompanyUser();
        if (currentRole == null || StringUtil.IS_COMPANY_USER.equals(currentRole) || StringUtil.IS_JOB_REQUEST_USER.equals(currentRole)) {
            updateParm.setIsCompanyUser(userType);
            targetUser.setIsCompanyUser(userType);
        }else{
            System.out.printf("用户角色不允许修改，openid:%s, 当前角色:%s, 传入角色:%s%n",
                    targetUser.getOpenid(), currentRole, userType);
        }
        if (StringUtils.isNotBlank(openid)) {
            updateParm.setOpenid(openid);
            targetUser.setOpenid(openid);
        }
        if (StringUtils.isNotBlank(unionid)) {
            updateParm.setUnionid(unionid);
            targetUser.setUnionid(unionid);
        }
        if(StringUtils.isNotBlank(orgType)){
            updateParm.setOrgType(orgType);
        }
        //最后登录时间
        updateParm.setLoginDate(new Date());
        appUserService.updateAppUser(updateParm);
    }

    /**
     * 注册
     * @param registerBody
     * @return
     */
    public String registerAppUser(RegisterBody registerBody) {
        //AppUser appUser=appUserService.registerAppUser(registerBody);
        AppUser appUser=appUserService.registerAppUserNew(registerBody);
        return loginUserIdApp(appUser);
    }

    /**
     * 手机号验证登录
     * @return
     */
    public AjaxResult phoneLogin(LoginBody loginBody){
        //AppUser appUser=appUserService.getPhone(loginBody.getUsername());
        AppUser appUser=appUserService.getYtjValidPhone(loginBody.getUsername());
        AjaxResult ajaxResult=validPhoneLogin(loginBody.getPassword(),appUser);
        if(!ajaxResult.isSuccess()){
            return ajaxResult;
        }
        return getAjax(appUser);
    }

    /**
     * 身份证号登录
     * @param loginBody
     * @return
     */
    public AjaxResult idCardLogin(LoginBody loginBody){
        String idCard=StringUtil.toUpperCaseIgnoreBlank(loginBody.getIdCard());
        AppUser appUser=appUserService.getYtjValidIdcard(idCard);
        if(appUser==null){
            AppUser userParm=new AppUser();
            userParm.setIdCard(idCard);
            userParm.setName(loginBody.getUsername());
            userParm.setIsCompanyUser("1");
            appUserService.insertAppUser(userParm);
            appUser = appUserService.getYtjValidIdcard(idCard);
        }
        return getAjax(appUser);
    }

    /**
     * 获取ajax
     * @param appUser
     * @return
     */
    public AjaxResult getAjax(AppUser appUser){
        AjaxResult ajax = AjaxResult.success();
        String token=loginUserIdApp(appUser);
        ajax.put(Constants.TOKEN, token);
        ajax.put("isNewUser", false);
        ajax.put("idCard",appUser.getIdCard());
        ajax.put("isCompanyUser",appUser.getIsCompanyUser());
        return ajax;
    }

    /**
     * 手机验证登录
     * @param password
     * @param appUser
     * @return
     */
    public static AjaxResult validPhoneLogin(String password,AppUser appUser){
        if(appUser==null){
            return AjaxResult.error("未查询到您的注册信息，请先完成注册后再登录～");
        }
        if(StringUtils.isBlank(appUser.getYtjPassword())){
            return AjaxResult.error("一体机密码为空，请维护后再进行登录～!");
        }
        try {
            if (!SiteSecurityUtils.matchesPassword(password, appUser.getYtjPassword())) {
                return AjaxResult.error("您输入的密码有误，请核对后重新尝试～");
            }
        } catch (Exception e) {
            return AjaxResult.error("密码校验失败，请稍后重试～");
        }
        return AjaxResult.success("验证成功!");
    }
}
