package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.config.security.SecurityUserHolder;
import com.yiboshi.science.dao.SystemUserDAO;
import com.yiboshi.science.entity.SystemUser;
import com.yiboshi.science.param.dto.ComPersonDTO;
import com.yiboshi.science.param.dto.SystemUserDTO;
import com.yiboshi.science.param.dto.UserDTO;
import com.yiboshi.science.param.query.SystemUserQueryVO;
import com.yiboshi.science.service.SystemUserRoleService;
import com.yiboshi.science.service.SystemUserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 用户信息表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-26
 */
@Service
public class SystemUserServiceImpl extends BaseServiceImpl<SystemUserDAO, SystemUserQueryVO, SystemUserDTO, SystemUser> implements SystemUserService {

    @Autowired
    private SystemUserDAO systemUserDAO;

    @Autowired
    private SystemUserRoleService systemUserRoleService;

    @Override
    protected void setCriteriaForQuery(SystemUserQueryVO vo, QueryWrapper<SystemUserQueryVO> criteria) {
        if (Objects.nonNull(vo.getUsername())) {
            criteria.like("username", vo.getUsername());
        }
        if (Objects.nonNull(vo.getPassword())) {
            criteria.eq("password", vo.getPassword());
        }
        if (Objects.nonNull(vo.getLoginName())) {
            criteria.eq("login_name", vo.getLoginName());
        }
        if (Objects.nonNull(vo.getPersonId())) {
            criteria.eq("user_id", vo.getPersonId());
        }
        if (Objects.nonNull(vo.getUserType())) {
            criteria.eq("user_type", vo.getUserType());
        }
        if (Objects.nonNull(vo.getNoteState())) {
            criteria.eq("note_state", vo.getNoteState());
        }
        if (Objects.nonNull(vo.getRoleId())) {
            criteria.eq("role_id", vo.getRoleId());
        }
        if (Objects.nonNull(vo.getPersonName())) {
            criteria.like("e.person_name", vo.getPersonName());
        }
        if (Objects.nonNull(vo.getCertId())) {
            criteria.like("e.cert_id", vo.getCertId());
        }
        if (Objects.nonNull(vo.getSex())) {
            criteria.eq("sex", vo.getSex());
        }
        if (Objects.nonNull(vo.getMobile())) {
            criteria.like("e.mobile", vo.getMobile());
        }
    }

    @Override
    public Pagination<SystemUserDTO> getListByPage(SystemUserQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<SystemUserQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<SystemUserDTO> dtoList = systemUserDAO.getListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public SystemUserDTO findByName(String username) {
        SystemUserDTO systemUser = systemUserDAO.findByName(username);
        if (systemUser == null)
            throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
        systemUser.setRoles(systemUserRoleService.getRolesByUserId(systemUser.getId()));
        return systemUser;
    }

    public void updateRoleById(String userId, String id, String roleId) {
        systemUserRoleService.updateRoleByUserId(userId, id, roleId);
    }

    public String updateStateById(String id, Integer noteState) {
        SystemUser systemUser = new SystemUser();
        systemUser.setId(id);
        systemUser.setNoteState(noteState);
        id = this.update(systemUser);
        return id;
    }

    @Transactional
    public SystemUser CreateUser(String username, String password, String userId, String roleId, Integer noteState) {
        SystemUser systemUser = new SystemUser();
        if (!Objects.nonNull(username) || username.equals(""))
            systemUser.setUsername(systemUserDAO.getMaxUsername("1521"));
        else {
            if (this.isExist(username))
                throw new BusinessException("该用户名已注册，请更改后再试！");
            systemUser.setUsername(username);
        }
        systemUser.setPassword(password);
        systemUser.setPersonId(userId);
        systemUser.setNoteState(noteState);
        String id = this.insert(systemUser);
        systemUserRoleService.addRoleByUserId(id, roleId);
        return systemUser;
    }

    public String updatePwd(UserDTO user) {
        if (Objects.isNull(user.getUserId()) || !user.getUserId().equals(SecurityUserHolder.getUserId()))
            throw new BusinessException("修改失败，请刷新页面后重试");
        SystemUser systemUser = this.getById(user.getUserId());
        if (null == systemUser)
            throw new BusinessException("系统错误，请稍后再试");
        if (!systemUser.getPassword().equals(user.getOldPassword()))
            throw new BusinessException("原密码错误，请检查");
        SystemUser newUser = new SystemUser();
        newUser.setId(systemUser.getId());
        newUser.setPassword(user.getNewPassword());
        return this.update(newUser);
    }

    public SystemUser getByCode(String personCode) {
        SystemUser systemUser = new SystemUser();
        systemUser.setPersonCode(personCode);
        return this.getEntity(systemUser);
    }

    public Boolean isExist(String username) {
        Boolean state = false;
        if (Objects.nonNull(username) && !username.equals("")) {
            SystemUser systemUser = systemUserDAO.getByUserName(username);
            if (null != systemUser) {
                state = true;
            }
        }
        return state;
    }

    public String resetPwd(ComPersonDTO dto) {
        SystemUser systemUser = this.getById(dto.getId());
        if (null == systemUser)
            throw new BusinessException("用户不存在，请联系管理员");
        String pwd = "ky123456";
        systemUser = new SystemUser();
        systemUser.setId(dto.getId());
        systemUser.setPassword(pwd);
        return this.update(systemUser);
    }

    public Boolean checkUserNameById(String username, String id) {
        Boolean state = false;
        SystemUser systemUser = getSystemUserByUsername(username);
        if (null != systemUser) {
            if (Objects.nonNull(id) && !id.equals("")) {
                SystemUser user = this.getById(id);
                if (null != user && !systemUser.getId().equals(user.getId()))
                    state = true;
            } else {
                state = true;
            }
        }
        return state;
    }

    public SystemUser getSystemUserByUsername(String username) {
        if (username == null || username.equals(""))
            return null;
        SystemUser systemUser = new SystemUser();
        systemUser.setUsername(username);
        systemUser = this.getEntity(systemUser);
        if (null != systemUser)
            return systemUser;
        else
            return null;
    }

    public SystemUserDTO getSystemUserById(String id) {
        return systemUserDAO.getSystemUserById(id);
    }

    public SystemUser getByPersonId(String personId) {
        SystemUser systemUser = new SystemUser();
        systemUser.setPersonId(personId);
        systemUser = this.getEntity(systemUser);
        return systemUser;
    }

    public String updateSystemUser(SystemUserDTO dto) {
        SystemUser user = this.convert2Entity(dto);
        String r = StringUtils.join(dto.getRole().toArray(), ",");

        List<String> roles = systemUserRoleService.getRolesListByUserId(dto.getId());
        for (String e : roles) {
            if (!r.contains(e)) {
                systemUserRoleService.deleteRoleByUserId(dto.getId(), e);
            }
        }
        String s = StringUtils.join(roles.toArray(), ",");
        for (String e : dto.getRole()) {
            if (!s.contains(e)) {
                systemUserRoleService.addRoleByUserId(dto.getId(), e);
            }
        }
        return this.update(user);
    }
}
