package com.zcloud.basic.info.command.query;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.utils.CaptchaUtils;
import com.jjb.saas.system.client.user.facade.UserFacade;
import com.zcloud.basic.info.command.convertor.CorpInfoCoConvertor;
import com.zcloud.basic.info.command.convertor.UserCoConvertor;
import com.zcloud.basic.info.constant.RedisConstant;
import com.zcloud.basic.info.domain.config.NineCompanyConfig;
import com.zcloud.basic.info.domain.enums.UserEmploymentFlagEnum;
import com.zcloud.basic.info.domain.enums.UserTypeEnum;
import com.zcloud.basic.info.domain.gateway.UserGateway;
import com.zcloud.basic.info.domain.model.UserE;
import com.zcloud.basic.info.dto.*;
import com.zcloud.basic.info.dto.clientobject.*;
import com.zcloud.basic.info.persistence.dataobject.UserCorpInfoDO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.dataobject.UserExpandInfoDO;
import com.zcloud.basic.info.persistence.dataobject.UserImgDO;
import com.zcloud.basic.info.persistence.repository.CorpInfoRepository;
import com.zcloud.basic.info.persistence.repository.UserExpandInfoRepository;
import com.zcloud.basic.info.persistence.repository.UserRepository;
import com.zcloud.gbscommon.excelEntity.UserExcelExportEntity;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.ZcloudRedisUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;


/**
 * web-app
 *
 * @Author zhangyue
 * @Date 2025-11-04 14:07:36
 */
@Component
@AllArgsConstructor
@Slf4j
public class UserQueryExe {
    private final UserRepository userRepository;
    private final UserGateway userGateway;
    private final UserCoConvertor userCoConvertor;
    private final CorpInfoRepository corpInfoRepository;
    private final CorpInfoCoConvertor corpInfoCoConvertor;
    private ZcloudRedisUtil zcloudRedisUtil;
    private final UserExpandInfoRepository userExpandInfoRepository;
    private final NineCompanyConfig nineCompanyConfig;


     /**
     * 分页
     *
     * @param userPageQry
     * @return
     */
    public PageResponse<UserCO> execute(UserPageQry userPageQry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(userPageQry);
        UserE userE = new UserE();
        userE.dataProcessingRights(AuthContext.getTenantId(), params);
        PageResponse<UserDO> pageResponse = userRepository.listPage(params);
        List<UserCO> examCenterCOS = userCoConvertor.converDOsToCOs(pageResponse.getData());

        return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }

    @DubboReference
    private UserFacade userFacade;
    /**
     * 查询集合
     *
     * @param userQryCmd
     * @return
     */
    public MultiResponse<UserCO> executeListAll(UserQryCmd userQryCmd) {

        Map<String, Object> params = PageQueryHelper.toHashMap(userQryCmd);
        List<UserDO> imgFilesDOList = userRepository.listAll(params);
        List<UserCO> imgFilesCOList = userCoConvertor.converDOsToCOs(imgFilesDOList);

        return MultiResponse.of(imgFilesCOList);
    }


    /**
     * 详情
     *
     * @param id
     * @return
     */
    public SingleResponse<UserCO> executeGetInfo(Long id) {
        UserDO userDO = userRepository.getInfoById(id);
        UserCO userCO = new UserCO();
        BeanUtils.copyProperties(userDO, userCO);
        if(AuthContext.getTenantId()==null){
            UserExpandInfoDO userExpandInfoDO = userExpandInfoRepository.getInfoByPhone(userDO.getPhone());
            if(userExpandInfoDO!=null){
                userCO.setFlowFlag(userExpandInfoDO.getFlowFlag());
            }
        }

        return SingleResponse.of(userCO);
    }
    /**
     * 详情
     *
     * @param userName
     * @return
     */
    public SingleResponse<UserCO> executeGetInfoByUserName(String userName) {
        UserDO userDO = userRepository.getInfoByUserName(userName);
        UserCO userCO = new UserCO();
        BeanUtils.copyProperties(userDO, userCO);
        if(AuthContext.getTenantId()==null){
            UserExpandInfoDO userExpandInfoDO = userExpandInfoRepository.getInfoByPhone(userDO.getPhone());
            if(userExpandInfoDO!=null){
                userCO.setFlowFlag(userExpandInfoDO.getFlowFlag());
            }
        }

        return SingleResponse.of(userCO);
    }


    /**
     * 验证用户是否存在
     *
     * @param userVerifyQryCmd
     * @return
     */
    public Response executeVerifyUser(UserVerifyQryCmd userVerifyQryCmd) {
        Map<String, Object> params = PageQueryHelper.toHashMap(userVerifyQryCmd);
        Response response = userGateway.countUser(params);
        return response;
    }

    /**
     * 验证手机号是否存在
     *
     * @return
     */
    public void executeVerifyPhone(UserVerifyPhoneCmd cmd) {
        List<UserDO> userDOS = userRepository.listByPhone(cmd.getPhone());
        if(CollUtil.isNotEmpty(userDOS)){
            throw new BizException("手机号已被注册。");
        }
    }


    public List<UserCO> listByUserIds(Collection<Long> collection) {
        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.in("id",collection);
        List<UserDO> list = userRepository.list(userDOQueryWrapper);
        List<UserCO> userCOS = userCoConvertor.converDOsToCOs(list);
        return userCOS;
    }


    public List<UserCO> listUserByUserName(Collection<String> collection) {
        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.in("username",collection);
        userDOQueryWrapper.eq("employment_flag", 1);
        userDOQueryWrapper.eq("delete_enum", "FALSE");
        userDOQueryWrapper.groupBy("username");
        List<UserDO> list = userRepository.list(userDOQueryWrapper);
        List<UserCO> userCOS = userCoConvertor.converDOsToCOs(list);
        return userCOS;
    }


    public List<UserCO> listUserByUserNameV1(Collection<String> collection) {
        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.in("username",collection);
        userDOQueryWrapper.eq("delete_enum", "FALSE");
        userDOQueryWrapper.groupBy("username");
        List<UserDO> list = userRepository.list(userDOQueryWrapper);
        List<UserCO> userCOS = userCoConvertor.converDOsToCOs(list);
        return userCOS;
    }

    public List<UserCO> getUserList() {
        List<UserDO> list = userRepository.list();
        List<UserCO> userCOS = userCoConvertor.converDOsToCOs(list);
        return userCOS;
    }

//    private void desensitize(UserCO userCO) {
//        userCO.setUserIdCard(DesensitizationUtils.idCardDesensitize(userCO.getUserIdCard()));
//        userCO.setPhone(DesensitizationUtils.mobileDesensitize(userCO.getPhone()));
//    }

    public UserCO getInfoByUserId(Long aLong) {
        UserDO byId = userRepository.getById(aLong);
        UserCO userCO = userCoConvertor.converDOToCO(byId);
        return userCO;
    }

    /**
     * 导出用户
     */
    public void exportUserTable(HttpServletResponse httpServletResponse, Long[] ids, Long corpinfoId) {
        Map<String, Object> params = new HashMap<>();
        params.put("corpinfoId", corpinfoId);
        if(ids != null && ids.length > 0) {
            params.put("userIdList", Arrays.asList(ids));
        }
        params.put("noMain",1);
        List<UserDO> userDOList = userRepository.listAll(params);
        List<UserExcelExportEntity> userExcelExportEntities = userCoConvertor.converDOsToExcelEntitys(userDOList);
        UserE userE  = new UserE();
        userE.exportUserTable(httpServletResponse, userExcelExportEntities);
    }



    /**
     * 详情
     *
     *
     * @return
     */
    public SingleResponse<UserCO> executeGetInfoBySession() {
        SSOUser ssoUser = AuthContext.getCurrentUser();
        Long id = ssoUser.getUserId();
        UserDO userDO = userRepository.getInfoById(id);
        UserCO userCO = new UserCO();
        BeanUtils.copyProperties(userDO, userCO);
        try{
            Long nineCompanyId = nineCompanyConfig.getCompanyId();
            userCO.setNineCompanyFlag(nineCompanyId != null && nineCompanyId.equals(userCO.getCorpinfoId()));
        }catch (Exception e){
            log.error("获取九公司ID异常", e);
            e.printStackTrace();
        }

        return SingleResponse.of(userCO);
    }

    public SingleResponse<UserCO> getEncryInfo(UserCheckPassWordCmd userCheckPassWordCmd) {
        UserE userE = new UserE();
        BeanUtils.copyProperties(userCheckPassWordCmd, userE);
        userE.encryptionPassword();
        UserDO userDO = userRepository.getEncryInfo(userE);
        return SingleResponse.of(userCoConvertor.converDOToCO(userDO));
    }

    public PageResponse<UserXmfCO> listXgf(UserPageQry userPageQry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(userPageQry);
        UserE userE = new UserE();
        userE.dataProcessingRights(AuthContext.getTenantId(), params);
        PageResponse<UserDO> pageResponse = userRepository.listXgf(params);
        List<UserXmfCO> userXmfCOList = userCoConvertor.converDOsToXgfCOs(pageResponse.getData());

        return PageResponse.of(userXmfCOList, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }

    public UserLoginCO login(UserAppLoginCmd cmd) {
        UserLoginCO userLoginCO = new UserLoginCO();
        //验证验证码
        Object captcha = zcloudRedisUtil.get(RedisConstant.GENERATE_CAPTCHA + cmd.getCaptchaKey());
        if(captcha == null || !captcha.toString().equals(cmd.getCaptchaCode())){
            throw new BizException("验证码错误");
        }
        //返回企业列表
        //根据手机号获取用户列表
        List<UserDO> userDOList = userRepository.getListByPhone(cmd.getPhone(),null);
        if(CollUtil.isEmpty(userDOList)){
            throw new BizException("用户不存在");
        }
        //获取在职的用户取第一个
        UserDO userDO = userDOList.stream().filter(userDO1 -> UserEmploymentFlagEnum.ON.getCode().equals(userDO1.getEmploymentFlag()))
                .filter(userDO1 -> UserTypeEnum.XGF.getCode().equals(userDO1.getUserType())).findFirst().orElse(null);
        if(userDO == null){
            userDO = userDOList.get(0);
        }


        //判断密码是否正确
        UserE userE = new UserE();
        userE.setPassword(userDO.getPassword());
        Boolean checkUserPassword = userE.checkUserPassword(cmd.getPassword(), userDO.getPassword());
        if(!checkUserPassword){
            throw new BizException("密码错误");
        }
        //判断用户信息是否完善
        UserE userCheck = new UserE();
        BeanUtils.copyProperties(userDO, userCheck);
        UserExpandInfoDO userExpandInfoDO = userExpandInfoRepository.getInfoByPhone(userDO.getPhone());
        Boolean b = userCheck.checkUserInfoComplete(userCheck,userExpandInfoDO==null?null:userExpandInfoDO.getFlowFlag());

        userLoginCO.setIsInfoComplete(b);

        List<Long> userIds = userDOList.stream().map(UserDO::getId).collect(Collectors.toList());
        List<UserCorpInfoDO> userCorpDOS = userRepository.getListByUserIds(userIds);
        List<UserCorpInfoCO> corpInfoCOS = corpInfoCoConvertor.converUserInfoDOsToCOs(userCorpDOS);

        userLoginCO.setUserCorpInfoCOList(corpInfoCOS);
        userLoginCO.setUserCO(userCoConvertor.converDOToCO(userDO));
        return userLoginCO;
    }
    public UserLoginCO getUserCorpByPhone(UserAppPhoneCmd cmd) {
        UserLoginCO userLoginCO = new UserLoginCO();
        //返回企业列表
        //根据手机号获取用户列表
        List<UserDO> userDOList = userRepository.getListByPhone(cmd.getPhone(),null);
        if(CollUtil.isEmpty(userDOList)){
            throw new BizException("用户不存在");
        }
        //获取在职的用户取第一个
        UserDO userDO = userDOList.stream().filter(userDO1 -> UserEmploymentFlagEnum.ON.getCode().equals(userDO1.getEmploymentFlag())).findFirst().orElse(null);
        if(userDO == null){
            userDO = userDOList.get(0);
        }

        List<Long> userIds = userDOList.stream().map(UserDO::getId).collect(Collectors.toList());
        List<UserCorpInfoDO> userCorpDOS = userRepository.getListByUserIds(userIds);
        List<UserCorpInfoCO> corpInfoCOS = corpInfoCoConvertor.converUserInfoDOsToCOs(userCorpDOS);

        userLoginCO.setUserCorpInfoCOList(corpInfoCOS);
        userLoginCO.setUserCO(userCoConvertor.converDOToCO(userDO));
        return userLoginCO;
    }

    public List<UserCorpInfoCO> getUserCorpList(Long id) {
        //返回企业列表
        UserDO userDO = userRepository.getById(id);
        //根据手机号获取用户列表
        List<UserDO> userDOList = userRepository.getListByPhone(userDO.getPhone(),null);

        List<Long> userIds = userDOList.stream().map(UserDO::getId).collect(Collectors.toList());
        List<UserCorpInfoDO> userCorpDOS = userRepository.getListByUserIds(userIds);
        List<UserCorpInfoCO> corpInfoCOS = corpInfoCoConvertor.converUserInfoDOsToCOs(userCorpDOS);
        return corpInfoCOS;

    }

    public CaptchaCO generateCaptcha() {
        CaptchaUtils.CaptchaResult result = CaptchaUtils.getSimpleCaptcha();
        CaptchaCO captchaCO = new CaptchaCO();

        captchaCO.setImg(result.getImg());
        String captchaKey = Tools.get32UUID();

        // 放入到redis里
        boolean set = zcloudRedisUtil.set(RedisConstant.GENERATE_CAPTCHA + captchaKey, result.getCode(), 60);

        captchaCO.setCaptchaKey(captchaKey);
        return captchaCO;
    }

    public SingleResponse<UserCO> getUserIdByPhone(GetUserIdByPhoneCmd getUserIdByPhoneCmd) {
        UserDO userDO =userRepository.getUserIdByPhone(getUserIdByPhoneCmd.getPhone());
        return SingleResponse.of(userCoConvertor.converDOToCO(userDO));

    }

    public PageResponse<UserCO> pageByNopermission(UserPageQry userPageQry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(userPageQry);
        UserE userE = new UserE();
        userE.dataProcessingRights(AuthContext.getTenantId(), params);
        PageResponse<UserDO> pageResponse = userRepository.pageByNopermission(params);
        List<UserCO> examCenterCOS = userCoConvertor.converDOsToCOs(pageResponse.getData());

        return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }

    public List<UserImgDO> listBase64ByUrl(Map<String, Object> map){
        return userRepository.listBase64ByUrl(map);
    }
}

