package ${basePackage}.module.system.mgr;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import ${basePackage}.frame.auth.LocalData;
import ${basePackage}.frame.auth.Token;
import ${basePackage}.frame.base.ErrorType;
import ${basePackage}.frame.utils.IDgenerator;
import ${basePackage}.frame.utils.MD5Util;
import ${basePackage}.frame.utils.MapperUtil;
import ${basePackage}.frame.utils.Message;
import ${basePackage}.frame.utils.ValidationUtil;
import ${basePackage}.module.system.ent.Dept;
import ${basePackage}.module.system.ent.Role;
import ${basePackage}.module.system.ent.User;
import ${basePackage}.module.system.mpr.UserMapper;
import ${basePackage}.module.system.req.DeptFindRequest;
import ${basePackage}.module.system.req.RoleFindRequest;
import ${basePackage}.module.system.req.UserCreateRequest;
import ${basePackage}.module.system.req.UserDeleteRequest;
import ${basePackage}.module.system.req.UserFindRequest;
import ${basePackage}.module.system.req.UserGetRequest;
import ${basePackage}.module.system.req.UserRoleCreateRequest;
import ${basePackage}.module.system.req.UserUpdateRequest;
import ${basePackage}.module.system.rsp.DeptFindResponse;
import ${basePackage}.module.system.rsp.RoleFindResponse;
import ${basePackage}.module.system.rsp.UserCreateResponse;
import ${basePackage}.module.system.rsp.UserDeleteResponse;
import ${basePackage}.module.system.rsp.UserFindResponse;
import ${basePackage}.module.system.rsp.UserGetResponse;
import ${basePackage}.module.system.rsp.UserRoleCreateResponse;
import ${basePackage}.module.system.rsp.UserUpdateResponse;

/**
 * USER - 用户
 *
 * @author wangbing
 * @version 0.0.1
 * @since 2017-01-01
 */
@Transactional
@Service
public class UserManagerImpl implements UserManager {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DeptManager deptManager;
    @Autowired
    private RoleManager roleManager;
    @Autowired
    private UserRoleManager userRoleManager;

    /**
     * 插入
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public UserCreateResponse create(UserCreateRequest request, Token token) {
        UserCreateResponse response = new UserCreateResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        long id = IDgenerator.nextId();
        User entity = MapperUtil.map(request, User.class);
        entity.setId(id);
        entity.setUserPwd(MD5Util.generatePwd(entity.getUserPwd()));

        {// 检查是否与设置的超级管理员账户相同
            String admin = LocalData.getEnvironment().getProperty("web.url.auth.admin", "admin");
            if (admin.equals(request.getUserName())) {
                response.addError(ErrorType.BUSINESS_ERROR, "[" + request.getUserName() + "]用户名已被超级管理员占用");
                return response;
            }
        }

        {// 检查机构设置是否正确
            DeptFindRequest deptFindRequest = new DeptFindRequest();
            deptFindRequest.setDeptCode(request.getDeptCode());
            deptFindRequest.setPageSize(1);
            DeptFindResponse deptFindResponse = deptManager.find(deptFindRequest, token);
            if (deptFindResponse.hasError()) {
                response.addErrors(deptFindResponse.getErrors());
                return response;
            }
            if (deptFindResponse.getResult().size() == 0) {
                response.addError(ErrorType.BUSINESS_ERROR, "[" + request.getDeptCode() + "]机构代码不存在");
                return response;
            }
            Dept dept = deptFindResponse.getResult().get(0);
            entity.setDeptId(dept.getId());
            entity.setDeptName(dept.getDeptName());
        }

        long result = userMapper.insert(entity, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE);
            return response;
        }

        // 检查角色设置是否正确
        for (String code : request.getRoleCodeList()) {
            RoleFindRequest roleFindRequest = new RoleFindRequest();
            roleFindRequest.setCode(code);
            RoleFindResponse roleFindResponse = roleManager.find(roleFindRequest, token);
            if (roleFindResponse.hasError()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                response.addErrors(roleFindResponse.getErrors());
                return response;
            } else if (roleFindResponse.getResult().size() == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                response.addError(ErrorType.BUSINESS_ERROR, "[" + code + "]角色代码不存在!");
                return response;
            }

            Role role = roleFindResponse.getResult().get(0);
            UserRoleCreateRequest userRoleCreateRequest = new UserRoleCreateRequest();
            userRoleCreateRequest.setUserId(id);
            userRoleCreateRequest.setUserCode(request.getUserCode());
            userRoleCreateRequest.setRoleId(role.getId());
            userRoleCreateRequest.setRoleCode(role.getCode());
            UserRoleCreateResponse userRoleCreateResponse = userRoleManager.create(userRoleCreateRequest, token);
            if (userRoleCreateResponse.hasError()) {
                response.addErrors(userRoleCreateResponse.getErrors());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return response;
            }
        }

        response.setId(id);

        return response;
    }

    /**
     * 逻辑删除
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public UserDeleteResponse delete(UserDeleteRequest request, Token token) {
        UserDeleteResponse response = new UserDeleteResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        long result = userMapper.delete(request, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE);
            return response;
        }
        response.setResult(result);

        return response;
    }

    /**
     * 更新
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public UserUpdateResponse update(UserUpdateRequest request, Token token) {
        UserUpdateResponse response = new UserUpdateResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        long result = userMapper.update(request, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE);
            return response;
        }
        response.setResult(result);

        return response;
    }

    /**
     * 查询
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    @Transactional(readOnly = true)
    public UserFindResponse find(UserFindRequest request, Token token) {
        UserFindResponse response = new UserFindResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        if (request.getPageSize() != 0) {
            PageHelper.startPage(request.getPageNumber(), request.getPageSize());
        }
        if (StringUtil.isNotEmpty(request.getSortKey())) {
            PageHelper.orderBy(request.getSortKey() + " " + request.getSortType());
        }
        PageInfo<User> pageInfo = new PageInfo<>(userMapper.find(request, token));

        response.setResult(pageInfo.getList());
        response.setTotalCount(pageInfo.getTotal());

        return response;
    }

    /**
     * 获得对象
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    @Transactional(readOnly = true)
    public UserGetResponse get(UserGetRequest request, Token token) {
        UserGetResponse response = new UserGetResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        User po = userMapper.get(request, token);

        if (po != null) {
            response.setUser(po);
        } else {
            response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE);
        }

        return response;
    }
}
