package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.AppUserLeaderEnum;
import com.ruoyi.common.constant.AppUserTypeEnum;
import com.ruoyi.common.constant.DeletedEnum;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.MySysPost;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.JWTUtil;
import com.ruoyi.common.utils.SecurityUtils;

import com.ruoyi.system.domain.AppLogin;
import com.ruoyi.system.dto.ContractorUserDTO;
import com.ruoyi.system.mapper.AppLoginMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.IAppLoginService;
import com.ruoyi.system.service.IContractorUserService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * app登录用户Service业务层处理
 *
 * @author ruoyi
 * @date 2023-08-04
 */
@Service
public class AppLoginServiceImpl extends ServiceImpl<AppLoginMapper, AppLogin> implements IAppLoginService {
    @Autowired
    private AppLoginMapper appLoginMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IContractorUserService contractorUserService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private SysUserMapper userMapper;

    @Override
    public AjaxResult loginForApp(String userName, String password) {

        //SELECT * FROM tb_app_login WHERE is_del =0 AND user_name = 'admin'
        List<AppLogin> appLogins = selectAppLoginListByUserName(userName);

        if (CollectionUtils.isEmpty(appLogins)) {
            return new AjaxResult(HttpStatus.WARN, "用户不存在或密码错误");
        } else if (appLogins.size() > 1) {
            return new AjaxResult(HttpStatus.WARN, "存在多个用户，请联系管理员！");
        }
        AppLogin appLogin = appLogins.get(0);
        boolean flag = SecurityUtils.matchesPassword(password, appLogin.getPassword());
        if (!flag) {
            return new AjaxResult(HttpStatus.WARN, "用户不存在或密码错误");
        }
        String secretKey = redisCache.getSecretKey(appLogin.getId().toString(), appLogin.getCompanyCode());
        Map<String, String> payload = new HashMap<>();
        payload.put("id", appLogin.getId().toString());
        //内部用户时设置用户ID（sys_user.user_id）
        if (appLogin.getUserType().equals(AppUserTypeEnum.USER.getValue())) {
            payload.put("pcUserId", appLogin.getUserId().toString());//内部用户ID
        } else if (appLogin.getUserType().equals(AppUserTypeEnum.CONTRACTOR.getValue())) {
            payload.put("contractorUserId", appLogin.getContractorUserId());//承包商用户ID
        }
        payload.put("userType", appLogin.getUserType().toString());//用户类型：1内部，2承包商
        payload.put("companyCode", appLogin.getCompanyCode());
        payload.put("userName", appLogin.getUserName());

        String nickName = null;

        //1、设置是否为领导
        //2、用户昵称

        //用户类型：1内部，2承包商
        if (appLogin.getUserType().equals(AppUserTypeEnum.USER.getValue())) {
            //设置人员姓名
            SysUser sysUser = sysUserService.selectUserById(Long.parseLong(appLogin.getUserId().toString()));
            if (Objects.nonNull(sysUser)) {
                nickName = sysUser.getNickName();
            }
            //查询是否领导
            //先设置为普通员工，发现是领导后再覆盖
            payload.put("leader", AppUserLeaderEnum.EMPLOYEES.getValue());
            List<SysRole> sysRoleList = sysRoleService.selectUserRoleList(appLogin.getUserId());
            if (!CollectionUtils.isEmpty(sysRoleList)) {
                List<SysRole> roleList = sysRoleList
                        .stream()
                        .filter(n -> "leader".equals(n.getRoleKey().toLowerCase()))
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(roleList)) {
                    payload.put("leader", AppUserLeaderEnum.LEADER.getValue());
                }
            }
            //设置当前登录人的岗位信息
            Set<Long> userIdSet = new HashSet<>();
            userIdSet.add(appLogin.getUserId());//PC用户ID
            List<MySysPost> postList = userMapper.selectUserPostList(userIdSet);
            if (CollectionUtils.isEmpty(postList)) {
                payload.put("postIdList", "");
            } else {
                List<Long> postIdList = postList.stream().map(MySysPost::getPostId).distinct().collect(Collectors.toList());
                String postIdListJoin = StringUtils.join(postIdList, ",");
                payload.put("postIdList", postIdListJoin);
            }
        } else if (appLogin.getUserType().equals(AppUserTypeEnum.CONTRACTOR.getValue())) {
            ContractorUserDTO contractorUserDTO = contractorUserService.selectContractorUserById(appLogin.getContractorUserId());
            if (Objects.nonNull(contractorUserDTO)) {
                nickName = contractorUserDTO.getCompellation();
            }
        }
        payload.put("nickName", nickName);


        //生成JWt的令牌
        String token = JWTUtil.getToken(payload, secretKey);
        payload.put("token", token);
        return new AjaxResult(HttpStatus.SUCCESS, "登录成功", payload);
    }


    /**
     * 查询app登录用户
     *
     * @param id app登录用户主键
     * @return app登录用户
     */
    @Override
    public AppLogin selectAppLoginById(String id) {
        return appLoginMapper.selectById(id);
    }

    /**
     * 用户名称查询用户信息
     *
     * @param userName app登录用户
     * @return app登录用户
     */
    public List<AppLogin> selectAppLoginListByUserName(String userName) {
        Map<String, Object> param = new HashMap<>();
        param.put("user_name", userName);
        param.put("is_del", DeletedEnum.VALID.getValue());
        return appLoginMapper.selectByMap(param);
    }

    /**
     * 新增app登录用户
     *
     * @param appLogin app登录用户
     * @return 结果
     */
    @Override
    public int insertAppLogin(AppLogin appLogin) {
        return appLoginMapper.insert(appLogin);
    }

    /**
     * 修改app登录用户
     *
     * @param appLogin app登录用户
     * @return 结果
     */
    @Override
    public int updateAppLogin(AppLogin appLogin) {
        return appLoginMapper.updateById(appLogin);
    }

    /**
     * 批量删除app登录用户
     *
     * @param ids 需要删除的app登录用户主键
     * @return 结果
     */
    @Override
    public int deleteAppLoginByIds(String[] ids) {
        return appLoginMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除app登录用户信息
     *
     * @param id app登录用户主键
     * @return 结果
     */
    @Override
    public int deleteAppLoginById(String id) {
        return appLoginMapper.deleteById(id);
    }

    /**
     * 根据PC用户ID查询APP用户对象
     *
     * @param userId
     * @return
     */
    @Override
    public AppLogin selectAppLoginByUserId(Long userId) {
        LambdaQueryWrapper<AppLogin> workTicketGasAnalysisLambdaQueryWrapper = new LambdaQueryWrapper<>();
        workTicketGasAnalysisLambdaQueryWrapper.eq(AppLogin::getUserId, userId);
        workTicketGasAnalysisLambdaQueryWrapper.eq(AppLogin::getUserType, 1);//用户类型：1内部，2承包商
        workTicketGasAnalysisLambdaQueryWrapper.eq(AppLogin::getIsDel, DeletedEnum.VALID.getValue());

        List<AppLogin> appLoginList = appLoginMapper.selectList(workTicketGasAnalysisLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(appLoginList) || appLoginList.size() != 1) {
//            throw new RuntimeException("APP用户表存在重复记录，系统用户ID：" + userId);
            return null;
        }
        return appLoginList.get(0);
    }

    /**
     * 根据承包商用户ID查询APP用户对象
     *
     * @param contractorUserId
     * @return
     */
    @Override
    public AppLogin selectAppLoginByContractorUserId(String contractorUserId) {
        LambdaQueryWrapper<AppLogin> workTicketGasAnalysisLambdaQueryWrapper = new LambdaQueryWrapper<>();
        workTicketGasAnalysisLambdaQueryWrapper.eq(AppLogin::getContractorUserId, contractorUserId);
        workTicketGasAnalysisLambdaQueryWrapper.eq(AppLogin::getUserType, 2);//用户类型：1内部，2承包商
        workTicketGasAnalysisLambdaQueryWrapper.eq(AppLogin::getIsDel, DeletedEnum.VALID.getValue());

        List<AppLogin> appLoginList = appLoginMapper.selectList(workTicketGasAnalysisLambdaQueryWrapper);

        if (CollectionUtils.isEmpty(appLoginList) || appLoginList.size() != 1) {
            throw new RuntimeException("APP用户表存在重复记录，承包商用户ID：" + contractorUserId);
        }
        return appLoginList.get(0);
    }
}
