package cn.com.ty.lift.system.user.service.impl;

import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.constants.CommonEnum;
import cn.com.ty.lift.common.model.PushMessage;
import cn.com.ty.lift.common.model.PushUserInfo;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.ty.lift.system.constants.CommonConstants;
import cn.com.ty.lift.system.settings.dao.entity.MaintenanceCompany;
import cn.com.ty.lift.system.settings.service.IMaintenanceCompanyService;
import cn.com.ty.lift.system.user.dao.entity.MtCompanyUser;
import cn.com.ty.lift.system.user.dao.entity.Role;
import cn.com.ty.lift.system.user.dao.entity.UserInfo;
import cn.com.ty.lift.system.user.dao.entity.UserRole;
import cn.com.ty.lift.system.user.dao.entity.model.*;
import cn.com.ty.lift.system.user.dao.mapper.MtCompanyUserMapper;
import cn.com.ty.lift.system.user.service.*;
import cn.com.xwy.boot.web.dto.RestResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author huangyuan
 * @date 2019-12-03
 * @description
 */
@Service
public class MtCompanyUserService extends ServiceImpl<MtCompanyUserMapper, MtCompanyUser> implements IMtCompanyUserService {

    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private IUserInfoService userInfoService;

    @Resource
    private IProjectService projectService;

    @Resource
    private IRoleService roleService;

    @Resource
    private IUserService userService;

    @Resource
    private PushUserService pushUserService;

    @Resource
    private IMaintenanceCompanyService maintenanceCompanyService;

    @Resource
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Override
    @Transactional
    public RestResponse assignRole(MtCompanyUserRequest mtCompanyUserRequest) {
        //获取用户是否已有mtCompanyUser信息。
        MtCompanyUser mtCompanyUser = this.getById(mtCompanyUserRequest.getId());
        //保存职业信息
        mtCompanyUser.setJob(mtCompanyUserRequest.getJob());
        this.updateById(mtCompanyUser);
        //保存用户角色关联信息
        Long roleId = mtCompanyUserRequest.getRoleId();
        Long userId = mtCompanyUser.getUserId();
        Long companyId = mtCompanyUser.getMtCompanyId();
        if (roleId != null) {
            UserRole userRole = userRoleService.getOne(new QueryWrapper<UserRole>()
                    .eq("company_id", companyId)
                    .eq("user_id", userId)
            );
            if (userRole != null) {
                //删除原有的关联关系
                boolean deleteUserRoleFlag = userRoleService.removeById(userRole.getId());
                if (!deleteUserRoleFlag) {
                    return RestResponse.fail(ApiConstants.RESULT_ERROR, "删除原有关联关系失败");
                }
            }
            //保存新的关联关系
            userRole = new UserRole();
            userRole.setCompanyId(companyId);
            userRole.setRoleId(roleId);
            userRole.setUserId(userId);
            boolean saveUserRoleFlag = userRoleService.save(userRole);
            if (!saveUserRoleFlag) {
                //事务强制回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return RestResponse.fail(ApiConstants.RESULT_ERROR, "保存角色信息失败");
            }
        }
        return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "分配角色成功");
    }

    @Override
    public RestResponse getCompanyMembers(MtCompanyUserRequest mtCompanyUserRequest) {
        List<UserResponse> userResponseList = new ArrayList<>();
        Long roleId = null;
        //如果角色编码不为空，则是获取指定公司指定角色的信息，如果角色编码为空则是获取所有成员信息
        if (StringUtils.isNotBlank(mtCompanyUserRequest.getRoleCode())) {
            Role role = roleService.getOne(new QueryWrapper<Role>()
                    .eq("code", mtCompanyUserRequest.getRoleCode())
                    .eq("company_id", mtCompanyUserRequest.getCompanyId())
            );
            //如果角色不存在则无用户可以获取
            if (role == null) {
                roleId = -1L;
            } else {
                roleId = role.getId();
            }
        }
        //获取公司下角色信息关联信息
        List<UserRole> userRoleList = userRoleService.list(new QueryWrapper<UserRole>()
                .eq(roleId != null, "role_id", roleId)
                .eq("company_id", mtCompanyUserRequest.getCompanyId())
        );
        //获取角色关联的用户信息
        List<Long> userIdList = ProjectUtils.getAttrList(userRoleList, "userId", null);
        if (userIdList.size() > 0) {
            List<MtCompanyUser> mtCompanyUserList = this.list(new QueryWrapper<MtCompanyUser>()
                    .in(userIdList != null && userIdList.size() > 0, "user_id", userIdList)
                    .eq("mt_company_id", mtCompanyUserRequest.getCompanyId())
                    .eq("status", ApiConstants.ApplicationConstants.APPLY_PASS)
            );
            userIdList = ProjectUtils.getAttrList(mtCompanyUserList, "userId", null);
        }
        Map<Long, Role> userIdToRole = roleService.getUserIdToRoleByUserIdsAndCompanyId(userIdList, mtCompanyUserRequest.getCompanyId());
        //获取用户信息集合
        if (userIdList != null && userIdList.size() > 0) {
            List<UserInfo> userInfoList = (List<UserInfo>) userInfoService.listByIds(userIdList);
            Map<Long, UserInfo> userIdToUserInfo = ProjectUtils.attrToObjMap(userInfoList, "userId", null);
            if (userIdToUserInfo != null && userIdToUserInfo.size() > 0) {
                for (Long userId : userIdList) {
                    //封装用户信息
                    UserResponse userResponse = new UserResponse();
                    userResponse.setUserId(userId);
                    UserInfo userInfo = userIdToUserInfo.get(userId);
                    //用户id->角色
                    Role role = userIdToRole.get(userId);
                    //设置角色编码
                    if (role != null) {
                        userResponse.setRoleCode(role.getCode());
                    }
                    if (userInfo != null) {
                        userResponse.setName(userInfo.getName());
                    }
                    userResponseList.add(userResponse);
                }
            }
        }
        return RestResponse.success(userResponseList, ApiConstants.RESULT_SUCCESS, "获取团队用户成功");
    }

    @Override
    public RestResponse kickOutTeam(MtCompanyUserRequest mtCompanyUserRequest) {
        MtCompanyUser mtCompanyUser = this.getById(mtCompanyUserRequest.getId());
        //判断用户是否可以踢出团队
        ProjectUser projectUser = new ProjectUser(mtCompanyUser.getUserId(), mtCompanyUser.getMtCompanyId());
        Map<String, String> judgeMsg = projectService.judgeKickOutTeam(projectUser);
        //获取判断返回的状态码
        String code = judgeMsg.get(CommonConstants.RETURN_CODE_FIELD);
        if (ApiConstants.RESULT_ERROR.equals(code)) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, judgeMsg.get(CommonConstants.RETURN_MSG_FIELD));
        }
        //设置用户为踢出团队状态
        mtCompanyUser.setStatus(ApiConstants.ApplicationConstants.APPLY_FAIL);
        //将用户原来关联的角色信息删除掉
        boolean deleteUserRoleFlag = userRoleService.remove(new QueryWrapper<UserRole>()
                .eq("user_id", mtCompanyUser.getUserId())
                .eq("company_id", mtCompanyUser.getMtCompanyId())
        );
        if (deleteUserRoleFlag) {
            if (this.updateById(mtCompanyUser)) {
                //踢出成功推送消息
                kickOutPushMessage(mtCompanyUser);
                return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "踢出用户成功");
            } else {
                //如果删除不成功，强制事务回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
        return RestResponse.fail(ApiConstants.RESULT_ERROR, "踢出用户失败");
    }

    @Override
    public RestResponse getCompanyUserList(MtCompanyUserRequest mtCompanyUserRequest) {

        List<Long> userQueryIdList = null;
        //通过用户名或手机号查找用户id
        if (StringUtils.isNotBlank(mtCompanyUserRequest.getQueryCondition())) {
            userQueryIdList = userService.getIdListByQueryCondition(mtCompanyUserRequest.getQueryCondition());
        }
        List<MtCompanyUserResponse> mtCompanyUserResponseList = new ArrayList<>();
        IPage mtCompanyUserPage = new Page(mtCompanyUserRequest.getPageNum(), mtCompanyUserRequest.getPageSize());
        mtCompanyUserPage = this.page(mtCompanyUserPage, new QueryWrapper<MtCompanyUser>()
                //判断用户是否在符合查询条件的用户列表中
                .in(userQueryIdList != null && userQueryIdList.size() > 0, "user_id", userQueryIdList)
                .eq("mt_company_id", mtCompanyUserRequest.getCompanyId())
                //获取在团队中的用户
                .eq("status", ApiConstants.ApplicationConstants.APPLY_PASS)
                .eq("delete_flag", ApiConstants.DELETE_NO)
        );
        List<MtCompanyUser> mtCompanyUserList = mtCompanyUserPage.getRecords();
        if (mtCompanyUserList != null && mtCompanyUserList.size() > 0) {

            /** 用户信息区域 **/
            //获取用户id集合
            List<Long> userIdList = ProjectUtils.getAttrList(mtCompanyUserList, "userId", null);
            Map<Long, UserResponse> userIdToUserResponse = userService.getUserResponseByUserIdList(userIdList);

            /** 角色信息区域 **/
            //获取用户角色关联关系
            Map<Long, Role> userIdToRole = roleService.getUserIdToRoleByUserIdsAndCompanyId(userIdList, mtCompanyUserRequest.getCompanyId());

            /** 操作证信息区域 **/
            //获取用户操作证信息
            List<LiftCertificate> liftCertificateList = projectService.getLiftCertificateList(new ProjectUser(mtCompanyUserRequest.getCompanyId(), userIdList));
            Map<Long, LiftCertificate> userIdToLiftCertificate = ProjectUtils.attrToObjMap(liftCertificateList, "userId", null);

            /** 公司用户信息组装区域 **/
            //组装公司用户信息
            for (MtCompanyUser mtCompanyUser : mtCompanyUserList) {
                MtCompanyUserResponse mtCompanyUserResponse = new MtCompanyUserResponse();
                mtCompanyUserResponse.setId(mtCompanyUser.getId());
                //基础信息
                mtCompanyUserResponse.setRepairFlag(mtCompanyUser.getRepairFlag());
                UserResponse userResponse = userIdToUserResponse.get(mtCompanyUser.getUserId());
                //设置用户角色信息
                mtCompanyUserResponse.setJob(mtCompanyUser.getJob());
                //设置公司用户基础信息
                if (userResponse != null) {
                    mtCompanyUserResponse.setUserId(mtCompanyUser.getUserId());
                    mtCompanyUserResponse.setUserMobile(userResponse.getMobile());
                    mtCompanyUserResponse.setUserName(userResponse.getName());
                }
                //设置公司用户角色名称
                Role role = userIdToRole.get(mtCompanyUser.getUserId());
                if (role != null) {
                    mtCompanyUserResponse.setRoleName(role.getName());
                }

                //设置用户操作证状态 0：无证，1：待审核，2：审核未通过，3：审核通过，4：超期
                LiftCertificate liftCertificate = userIdToLiftCertificate.get(mtCompanyUser.getUserId());
                if (liftCertificate != null) {
                    mtCompanyUserResponse.setCertificateStatus(liftCertificate.getStatus());
                }
                mtCompanyUserResponseList.add(mtCompanyUserResponse);
            }
        }
        //分页数据更换
        mtCompanyUserPage.setRecords(mtCompanyUserResponseList);
        return RestResponse.success(mtCompanyUserPage, ApiConstants.RESULT_SUCCESS, "获取公司成员列表成功");
    }

    @Override
    public RestResponse setRepair(MtCompanyUserRequest mtCompanyUserRequest) {
        MtCompanyUser mtCompanyUser = this.getById(mtCompanyUserRequest.getId());
        mtCompanyUser.setRepairFlag(mtCompanyUserRequest.getRepairFlag());
        this.updateById(mtCompanyUser);
        return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "设置急修信息成功");
    }

    @Override
    public RestResponse appGetCompanyMembers(MtCompanyUserRequest mtCompanyUserRequest) {
        IPage companyUserPage = new Page<>(mtCompanyUserRequest.getPageNum(), mtCompanyUserRequest.getPageSize());
        //分页获取团队成员信息
        companyUserPage = this.page(companyUserPage, new QueryWrapper<MtCompanyUser>()
                .eq("mt_company_id", mtCompanyUserRequest.getCompanyId())
                .eq("delete_flag", ApiConstants.DELETE_NO)
                .eq("status", ApiConstants.ApplicationConstants.APPLY_PASS)
        );
        List<MtCompanyUser> mtCompanyUserList = companyUserPage.getRecords();
        if (mtCompanyUserList != null && mtCompanyUserList.size() > 0) {
            List<AppCompanyUserResponse> appCompanyUserResponseList = new ArrayList<>();
            List<Long> userIdList = ProjectUtils.getAttrList(mtCompanyUserList, "userId", null);
            //获取团队用户基础信息
            List<UserInfo> userInfoList = (List<UserInfo>) userInfoService.listByIds(userIdList);
            Map<Long, UserInfo> userIdToUserInfo = ProjectUtils.attrToObjMap(userInfoList, "userId", null);
            //获取团队用户角色信息
            Map<Long, Role> userIdToRole = roleService.getUserIdToRoleByUserIdsAndCompanyId(userIdList,
                    mtCompanyUserRequest.getCompanyId());
            //获取团队用户操作证信息
            Map<Long, LiftCertificate> userIdToLiftCertificate = projectService
                    .getUserIdToLiftCertificateByUserIdListAndCompanyId(userIdList, mtCompanyUserRequest.getCompanyId());
            for (MtCompanyUser mtCompanyUser : mtCompanyUserList) {
                AppCompanyUserResponse appCompanyUserResponse = new AppCompanyUserResponse();
                //设置用户信息
                UserInfo userInfo = userIdToUserInfo.get(mtCompanyUser.getUserId());
                //如果用户信息为空，跳过该用户
                if (userInfo == null) {
                    break;
                }
                appCompanyUserResponse.setUserId(userInfo.getUserId());
                appCompanyUserResponse.setUserAvatarUrl(userInfo.getAvatarUrl());
                appCompanyUserResponse.setUserName(userInfo.getName());
                appCompanyUserResponse.setUserMobile(userInfo.getMobile());
                appCompanyUserResponse.setUserRemarks(userInfo.getRemarks());

                //设置角色信息
                Role role = userIdToRole.get(mtCompanyUser.getUserId());
                if (role != null) {
                    appCompanyUserResponse.setUserRoleId(role.getId());
                    appCompanyUserResponse.setUserRoleName(role.getName());
                }

                //设置操作证信息
                LiftCertificate liftCertificate = userIdToLiftCertificate.get(mtCompanyUser.getUserId());
                appCompanyUserResponse.setLiftCertificate(liftCertificate);
                appCompanyUserResponseList.add(appCompanyUserResponse);
            }
            companyUserPage.setRecords(appCompanyUserResponseList);
            return RestResponse.success(companyUserPage, ApiConstants.RESULT_SUCCESS, "获取公司用户信息成功");
        }
        return RestResponse.success(companyUserPage, ApiConstants.RESULT_SUCCESS, "获取公司用户信息成功");
    }

    @Override
    public RestResponse getUrgentRepairs(MtCompanyUserRequest mtCompanyUserRequest) {
        List<MtCompanyUser> mtCompanyUserList = this.list(new QueryWrapper<MtCompanyUser>()
                .eq("mt_company_id", mtCompanyUserRequest.getCompanyId())
                .eq("repair_flag", ApiConstants.CompanyConstants.REPAIR_YES)
                .eq("delete_flag", ApiConstants.DELETE_NO)
        );
        //获取用户信息
        List<Long> userIdList = ProjectUtils.getAttrList(mtCompanyUserList, "userId", null);
        Map<Long, UserResponse> userIdToUserResponse = userService.getUserResponseByUserIdList(userIdList);
        return RestResponse.success(userIdToUserResponse.values(), ApiConstants.RESULT_SUCCESS, "获取急修工成功");
    }

    @Override
    @Transactional
    public boolean updateLoginCompanyFlag(Long userId, Long currentCompanyId) {
        //重置当前登录公司
        boolean resetCurrentCompanyFlag = this.update(new UpdateWrapper<MtCompanyUser>()
                .set("is_current_company", 0)
                .eq("user_id", userId)
        );
        if (!resetCurrentCompanyFlag) {
            return false;
        }
        //将当前登录的公司 登录标识设置为1(即当前登录公司)
        boolean setCurrentCompanyFlag = this.update(new UpdateWrapper<MtCompanyUser>()
                .set("is_current_company", 1)
                .eq("user_id", userId)
                .eq("mt_company_id", currentCompanyId)
        );
        if (!setCurrentCompanyFlag) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        return true;
    }


    public List<MtCompanyUser> listByMtCompany(Long mtCompanyId) {
        LambdaQueryWrapper<MtCompanyUser> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(MtCompanyUser::getMtCompanyId, mtCompanyId);
        return list(lambdaQueryWrapper);
    }

    /**
     * @param
     * @return
     * @description 踢出成功 推送消息
     * @date 2020/5/3 4:43 下午
     */
    private void kickOutPushMessage(MtCompanyUser mtCompanyUser) {
        //踢出用户成功，进行消息推送
        //当前公司下的区域主管
        List<PushUserInfo> pushUserInfoList = pushUserService.getUserInfoByRoleCode(
                CommonEnum.DefaultRole.REGION_DIRECTOR.getCode());
        if (pushUserInfoList != null && pushUserInfoList.size() > 0) {
            //被踢出的人
            PushUserInfo kickOutUserInfo = pushUserService.getUserInfoByUserId(mtCompanyUser.getUserId());
            if (kickOutUserInfo != null) {
                MaintenanceCompany maintenanceCompany = maintenanceCompanyService.getById(
                        mtCompanyUser.getMtCompanyId());
                if (maintenanceCompany != null) {
                    pushUserInfoList.add(kickOutUserInfo);
                    PushMessage.teamKickOut(kickOutUserInfo.getUserName(), maintenanceCompany.getName())
                            .sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfoList);
                }
            }
        }
    }

}
