package com.zcloud.basic.info.persistence.repository.impl;

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.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jjb.saas.auth.client.account.facade.AccountFacade;
import com.jjb.saas.auth.client.account.request.AccountPasswordCheckCmd;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.event.producer.RemoteEventPublisher;
import com.jjb.saas.framework.repository.common.PageHelper;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
import com.jjb.saas.message.client.message.facede.MessageFacade;
import com.jjb.saas.message.client.todotask.facade.BusTodoTaskFacade;
import com.jjb.saas.system.client.role.facade.RoleFacade;
import com.jjb.saas.system.client.role.response.RoleCO;
import com.jjb.saas.system.client.user.facade.UserFacade;
import com.jjb.saas.system.client.user.request.RoleDeptAddCmd;
import com.jjb.saas.system.client.user.request.UserAddCmd;
import com.jjb.saas.system.client.user.request.UserUpdateCmd;
import com.jjb.saas.system.client.user.request.UserUpdatePasswordCmd;
import com.zcloud.basic.info.domain.enums.MenuEnum;
import com.zcloud.basic.info.domain.model.UserE;
import com.zcloud.basic.info.persistence.dataobject.DepartmentLeaderStatictiscDO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.mapper.UserMapper;
import com.zcloud.basic.info.persistence.repository.UserRepository;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import com.zcloud.gbscommon.utils.Query;
import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.UuidUtil;
import com.zcloud.gbscommon.zcloudimgfiles.facade.ZcloudImgFilesFacade;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * web-infrastructure
 *
 * @Author zhangyue
 * @Date 2025-11-04 14:07:37
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserRepositoryImpl extends BaseRepositoryImpl<UserMapper, UserDO> implements UserRepository {
    private final UserMapper userMapper;

    @DubboReference(check = false)
    private UserFacade userFacade;
    @DubboReference(check = false)
    private RoleFacade roleFacade;

    @DubboReference(check = false)
    private AccountFacade accountFacade;
    @Autowired
    private RemoteEventPublisher remoteEventPublisher;

    @Override
    public PageResponse<UserDO> listPage(Map<String, Object> params) {


//        ZcloudImgFilesQryCmd zcloudImgFilesQryCmd = new ZcloudImgFilesQryCmd();
//        MultiResponse<ZcloudImgFilesCO> s = zcloudImgFilesFacade.listAll(zcloudImgFilesQryCmd);
//        TodoTaskAddCmd todoTaskAddCmd = new TodoTaskAddCmd();
//        todoTaskAddCmd.setUserId(AuthContext.getCurrentUser().getUserId());
//        String busId = UuidUtil.get32UUID();
//        System.out.println(busId);
//        todoTaskAddCmd.setBusId(busId);
//        todoTaskAddCmd.setAppKey("9f41187e801e4de5843b1a9a3fe4318e");
//        todoTaskAddCmd.setTitle(DateUtil.getSdfTimes());
//        todoTaskAddCmd.setLevelEnum("IMPATIENT");
//        todoTaskAddCmd.setBusTypeEnum("ssss");
//        todoTaskAddCmd.setBusCode("wowowowo");
//        todoTaskAddCmd.setButtonName("查看");
//        todoTaskAddCmd.setContent("这是content");
//        todoTaskAddCmd.setDetailUrl("/basicInfo/container/supervision/supervision/user/list?gbs_native=true&gbs_client_id=GWJZH&paginationKeys=current,pageSize&paginationValues=1,20");
//        busTodoTaskFacade.addTask(todoTaskAddCmd);
//        HandelTaskAddCmd handelTaskAddCmd = new HandelTaskAddCmd();
//        handelTaskAddCmd.setUserId(AuthContext.getCurrentUser().getUserId());
//        handelTaskAddCmd.setBusId("08ce77d4d7fa4291bc65d62cdbbd24a1");
//        handelTaskAddCmd.setBusCode("wowowowo");
//        busTodoTaskFacade.handleTask(handelTaskAddCmd);
        IPage<UserDO> iPage = new Query<UserDO>().getPage(params);
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params, "u.");
        queryWrapper.eq("u.delete_enum", "FALSE");
        queryWrapper.apply("u.id != u.corpinfo_id");
        queryWrapper.orderByAsc("u.sort").orderByDesc("u.create_time");
        String menuPerms = "";
        if (!ObjectUtils.isEmpty(params.get("menuPath"))){
            menuPerms = MenuEnum.getMenuKeyByPath(params.get("menuPath").toString());
        }
        IPage<UserDO> result = userMapper.selectUserPage(iPage, queryWrapper, menuPerms);
        return PageHelper.pageToResponse(result, result.getRecords());
    }

    @DubboReference
    private ZcloudImgFilesFacade zcloudImgFilesFacade;

    @DubboReference
    private MessageFacade messageFacade;

    @DubboReference
    private BusTodoTaskFacade busTodoTaskFacade;

    @Override
    public List<UserDO> listAll(Map<String, Object> params) {
        if (!ObjectUtils.isEmpty(params.get("corpinfoId"))) {
            SSOUser ssoUser = AuthContext.getCurrentUser();
            params.put("corpinfoId", ssoUser.getTenantId());
        }
        return userMapper.selectListAll(params);
    }

    @Override
    public Long getCountByCorpInfoId(Long id) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("corpinfo_id", id);
        return userMapper.selectCount(queryWrapper);
    }

    @Override
    public Boolean checkUserDepartment(Long id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("department_id", id);
        Long userCount = userMapper.selectCount(queryWrapper);
        if (userCount > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Boolean checkUserDepartment(Long[] ids) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("department_id", ids);
        Long userCount = userMapper.selectCount(queryWrapper);
        if (userCount > 0) {
            return true;
        }
        return false;
    }

    @Override
    public UserDO getInfoById(Long id) {

        return userMapper.getInfoById(id);
    }

    @Override
    public Response countUser(Map<String, Object> params) {
        if (!ObjectUtils.isEmpty(params.get("username"))){
            Map<String, Object> verifyParam = new HashMap<>();
            verifyParam.put("username", params.get("username"));
            verifyParam.put("id", params.get("id"));
            Integer count = userMapper.countUser(verifyParam);
            if (count > 0) {
                return Response.buildFailure("用户名已经存在，请联系管理员");
            }
        }
        if (!ObjectUtils.isEmpty(params.get("phone"))){
            Map<String, Object> verifyParam = new HashMap<>();
            verifyParam.put("phone", params.get("phone"));
            verifyParam.put("id", params.get("id"));
            Integer count = userMapper.countUser(verifyParam);
            if (count > 0) {
                return Response.buildFailure("手机号已经存在，请联系管理员");
            }
        }
        if (!ObjectUtils.isEmpty(params.get("userIdCard"))){
            Map<String, Object> verifyParam = new HashMap<>();
            verifyParam.put("userIdCard", params.get("userIdCard"));
            verifyParam.put("id", params.get("id"));
            Integer count = userMapper.countUser(verifyParam);
            if (count > 0) {
                return Response.buildFailure("身份证号已经存在，请联系管理员");
            }
        }

        return Response.buildSuccess();
    }

    @Override
    public List<UserDO> listByPostId(Long postId) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", postId);
        queryWrapper.eq("delete_enum", "FALSE");
        queryWrapper.orderByAsc("sort").orderByDesc("create_time");
        List userPostList = this.list(queryWrapper);
        return userPostList;
    }

    @Override
    public List<UserDO> listByPostIds(Long[] postIds) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper();
        queryWrapper.in("post_id", postIds);
        queryWrapper.eq("delete_enum", "FALSE");
        queryWrapper.orderByAsc("sort").orderByDesc("create_time");
        List<UserDO> userPostList = this.list(queryWrapper);
        return userPostList;
    }

    @Override
    public List<UserDO> listByCorpInfoId(Long corpInfoId) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper();
        queryWrapper.eq("corpinfo_id", corpInfoId);
        queryWrapper.eq("delete_enum", "FALSE");
        queryWrapper.orderByAsc("sort").orderByDesc("create_time");
        return list(queryWrapper);
    }

    @Override
    public void addCorpUser(UserE userE) {
        UserDO userDo = new UserDO();
        BeanUtils.copyProperties(userE, userDo);
        if (userDo.getUserId() == null) {
            userDo.setUserId(Tools.get32UUID());
        }
        save(userDo);
        userE.setId(userDo.getId());
    }

    @Override
    public void saveUser(UserDO userDO) {
        if(StringUtils.isEmpty(userDO.getUsername())){
            userDO.setUsername(userDO.getPhone());
        }
        UserAddCmd userAddCmd = new UserAddCmd();
        userAddCmd.setAccount(userDO.getUsername());
        userAddCmd.setName(userDO.getName());
        RoleDeptAddCmd roleDeptAddCmd = new RoleDeptAddCmd();
        roleDeptAddCmd.setRoleId(userDO.getRoleId());
        roleDeptAddCmd.setDeptId(userDO.getDepartmentId());
        List<RoleDeptAddCmd> roleDeptAddCmdList = Collections.singletonList(roleDeptAddCmd);
        userAddCmd.setRoleDepts(roleDeptAddCmdList);

        SingleResponse<Long> gbsResult = userFacade.add(userAddCmd);
        userDO.setId(gbsResult.getData());
        if(userDO.getSort() == null){
            userDO.setSort(9999);
        }
        // 新增用户默认在职
        userDO.setEmploymentFlag(1);
        save(userDO);
    }

    @Override
    public void saveRegisterUser(UserDO userDO) {
        if(StringUtils.isEmpty(userDO.getUsername())){
            userDO.setUsername(userDO.getPhone());
        }
        UserAddCmd userAddCmd = new UserAddCmd();
        userAddCmd.setAccount(userDO.getPhone());
        userAddCmd.setMobile(userDO.getPhone());
        RoleDeptAddCmd roleDeptAddCmd = new RoleDeptAddCmd();
        roleDeptAddCmd.setRoleId(1994326788804837377L);
        roleDeptAddCmd.setDeptId(userDO.getDepartmentId());
        List<RoleDeptAddCmd> roleDeptAddCmdList = Collections.singletonList(roleDeptAddCmd);
        userAddCmd.setRoleDepts(roleDeptAddCmdList);
        userAddCmd.setTenantId(userDO.getCorpinfoId());

        SingleResponse<Long> gbsResult = userFacade.add(userAddCmd);
        userDO.setId(gbsResult.getData());
        if(userDO.getSort() == null){
            userDO.setSort(9999);
        }
        // 新增用户默认入职待审核
    //    userDO.setEmploymentFlag(11);
        // 默认不是主账号
        userDO.setMainCorpFlag(0);
        userDO.setUserId(UuidUtil.get32UUID());
        // 相关方
        userDO.setCorpinfoId(null);
        save(userDO);
    }

    @Override
    public void saveUserXgf(UserDO userDO) {
        if(StringUtils.isEmpty(userDO.getUsername())){
            userDO.setUsername(userDO.getPhone());
        }

        //TODO 流动人员同步gbs需要指定特殊tenantId
//        if(UserFlowFlagEnum.FLOW.getCode().equals(userDO.getFlowFlag())){
//            FacadeUserRegisterCmd facadeUserRegisterCmd = new FacadeUserRegisterCmd();
//            facadeUserRegisterCmd.setAccount(userDO.getUsername());
//            facadeUserRegisterCmd.setName(userDO.getName());
//            facadeUserRegisterCmd.setMobile(userDO.getPhone());
//            facadeUserRegisterCmd.setPassword(userDO.getPassword());
//            facadeUserRegisterCmd.setTenantId(1111111L);
//            facadeUserRegisterCmd.setAppKey("");
//            facadeUserRegisterCmd.setOrgId(11111L);
////            facadeUserRegisterCmd.setRoleCodes(Collections.singletonList(userDO.getRoleId()));
//
//            SingleResponse<Long> register = userFacade.register(facadeUserRegisterCmd);
//            userDO.setId(register.getData());
//            userDO.setCorpinfoId(null);
//        }else{
            UserAddCmd userAddCmd = new UserAddCmd();
            userAddCmd.setAccount(userDO.getUsername());
            userAddCmd.setName(userDO.getName());
            RoleDeptAddCmd roleDeptAddCmd = new RoleDeptAddCmd();
            roleDeptAddCmd.setRoleId(userDO.getRoleId());
            roleDeptAddCmd.setDeptId(userDO.getDepartmentId());
            List<RoleDeptAddCmd> roleDeptAddCmdList = Collections.singletonList(roleDeptAddCmd);
            userAddCmd.setRoleDepts(roleDeptAddCmdList);
            SingleResponse<Long> gbsResult = userFacade.add(userAddCmd);
            userDO.setId(gbsResult.getData());
//        }

        if(userDO.getSort() == null){
            userDO.setSort(9999);
        }


        save(userDO);
    }

    @Override
    public void updateInfoById(UserDO userDO) {
        updateById(userDO);
        UserUpdateCmd userUpdateCmd = new UserUpdateCmd();
        userUpdateCmd.setId(userDO.getId());
        userUpdateCmd.setAccount(userDO.getUsername());
        userUpdateCmd.setName(userDO.getName());
        userFacade.update(userUpdateCmd);
    }

    @Override
    public void deleteUserById(Long id) {
        UpdateWrapper<UserDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id)
                .eq("delete_enum", "FALSE")
                .set("delete_enum", "TRUE");
        update(updateWrapper);
        userFacade.delete(id);
    }

    @Override
    public void changePassword(Long id, String password) {
        UserUpdatePasswordCmd userUpdatePasswordCmd = new UserUpdatePasswordCmd();
        userUpdatePasswordCmd.setId(id);
        userUpdatePasswordCmd.setPassword(password);
        userFacade.updatePassword(userUpdatePasswordCmd);
    }

    @Override
    public void updateUserName(UserDO userDO) {
        updateById(userDO);
        if (!ObjectUtils.isEmpty(userDO.getName())){
            UserUpdateCmd userUpdateCmd = new UserUpdateCmd();
            userUpdateCmd.setId(userDO.getId());
            userUpdateCmd.setName(userDO.getName());
            userUpdateCmd.setAccount(userDO.getName());
            userFacade.update(userUpdateCmd);
        }
    }

    @Override
    public Map<Long, String> getDepartmentLeaderByDepartmentId(List<Long> departmentIds) {
        List<DepartmentLeaderStatictiscDO> departmentLeaderList = userMapper.getDepartmentLeaderByDepartmentId(departmentIds);
        Map<Long, String> departmentLeaderMap = departmentLeaderList.stream()
                .collect(Collectors.toMap(DepartmentLeaderStatictiscDO::getDepartmentId, DepartmentLeaderStatictiscDO::getDepartmentLeaderNameList));
        return departmentLeaderMap;
    }

    @Override
    public Long getDefaultRoleId() {
        MultiResponse<RoleCO> multiResponse = roleFacade.listRoles();
        if (multiResponse.isSuccess()){
            List<RoleCO> roleCOList = multiResponse.getData();
            for (RoleCO roleCO : roleCOList) {
                if ("默认通用角色".equals(roleCO.getRoleName())){
                    return roleCO.getId();
                }
            }
        }
        return null;
    }

    @Override
    public Map<String, Long> getRoleMap() {
        MultiResponse<RoleCO> multiResponse = roleFacade.listRoles();
        if (multiResponse.isSuccess()){

            return multiResponse.getData().stream()
                    .collect(Collectors.toMap(RoleCO::getRoleName, RoleCO::getId));
        }
        return null;
    }

    @Override
    public Response updatePassword(UserDO userDO) {
        //  TODO 验证老密码是否正确
        if(userDO.getPassword() != null && !userDO.getPassword().equals("")){
            AccountPasswordCheckCmd accountPasswordCheckCmd = new AccountPasswordCheckCmd();
            accountPasswordCheckCmd.setUserId(userDO.getId());
            accountPasswordCheckCmd.setPassword(userDO.getPassword());
            SingleResponse<Long> response = accountFacade.checkPassword(accountPasswordCheckCmd);
            if(!response.isSuccess()){
                return Response.buildFailure("原密码不正确");
            }
        }

//          更新密码
        UserUpdatePasswordCmd userUpdatePasswordCmd = new UserUpdatePasswordCmd();
        userUpdatePasswordCmd.setId(userDO.getId());
        userUpdatePasswordCmd.setPassword(userDO.getNewPassword());
        return userFacade.updatePassword(userUpdatePasswordCmd);
    }

    @Override
    public Boolean updateFaceUrl(UserDO userDO) {
        return updateById(userDO);
    }

    @Override
    public List<UserDO> listByPhone(String phone) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        return list(queryWrapper);
    }

    @Override
    public UserDO getEncryInfo(UserE userE) {
        //   验证老密码是否正确
        AccountPasswordCheckCmd accountPasswordCheckCmd = new AccountPasswordCheckCmd();
        accountPasswordCheckCmd.setUserId(AuthContext.getUserId());
        accountPasswordCheckCmd.setPassword(userE.getPassword());
        SingleResponse<Long> response = accountFacade.checkPassword(accountPasswordCheckCmd);
        if(!response.isSuccess()){
            throw new BizException("密码错误");
        }
        return getById(userE.getId());
    }

    @Override
    public Boolean checkUserPassWordEncryInfo(String password) {
        //   验证老密码是否正确
        AccountPasswordCheckCmd accountPasswordCheckCmd = new AccountPasswordCheckCmd();
        accountPasswordCheckCmd.setUserId(AuthContext.getUserId());
        accountPasswordCheckCmd.setPassword(password);
        SingleResponse<Long> response = accountFacade.checkPassword(accountPasswordCheckCmd);
        if(!response.isSuccess()){
            return false;
        }
        return true;
    }

    @Override
    public PageResponse<UserDO> listXgf(Map<String, Object> params) {
        IPage<UserDO> iPage = new Query<UserDO>().getPage(params);
        String menuPerms = "";
        if (!ObjectUtils.isEmpty(params.get("menuPath"))){
            menuPerms = MenuEnum.getMenuKeyByPath(params.get("menuPath").toString());
        }
        IPage<UserDO> result = userMapper.listXgf(iPage, params, menuPerms);
        return PageHelper.pageToResponse(result, result.getRecords());
    }


    @Override
    public UserDO getByPhone(String phone) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        return getOne(queryWrapper);
    }

    @Override
    public UserDO getByPhoneAndIdCard(String phone, String idCardNumber) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        queryWrapper.eq("user_id_card", idCardNumber);
        return getOne(queryWrapper);
    }
}

