package com.kuyuntech.vrv.coreservice.service.core.impl;


import com.kuyuntech.vrv.coreapi.service.core.UserService;
import com.kuyuntech.vrv.coreapi.until.core.PasswordEncryptUtils;
import com.kuyuntech.vrv.coreservice.dao.core.RoleDao;
import com.kuyuntech.vrv.coreservice.dao.core.UserDao;
import com.kuyuntech.vrv.coreservice.domain.core.Role;
import com.wbspool.fastboot.core.common.bean.ResponseBean;
import org.hibernate.criterion.MatchMode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.kuyuntech.vrv.coreapi.bean.core.UserBean;
import com.kuyuntech.vrv.coreservice.domain.core.User;
import com.wbspool.fastboot.core.common.bean.PagerBean;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import java.util.ArrayList;

import org.hibernate.criterion.Order;
import com.wbspool.fastboot.core.jpa.service.AbstractFastbootService;
import org.springframework.util.Assert;

import static com.wbspool.fastboot.core.jpa.constant.DataValidTypes.*;


/**
 * UserService
 */
@Service("userService")
@Transactional(rollbackFor = Exception.class, transactionManager = "vrvCoreServiceTransactionManager")
public class UserServiceImpl extends AbstractFastbootService<User, UserBean> implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    UserDao userDao;

    @Autowired
    RoleDao roleDao;

    @Override
    public UserBean add(UserBean userBean) {

        User user = new User();
        beanToDomain(userBean, user, "id");
        userDao.save(user);
        domainToBean(user, userBean);
        return userBean;

    }

    @Override
    public UserBean login(UserBean userBean) {

        if (userBean == null) {
            return null;
        }

        User user = userDao.findByAccountAndPasswordAndValid(userBean.getAccount(), userBean.getPassword(), VALID);

        if (user == null) {
            return null;
        }

        domainToBean(user, userBean);

        return userBean;
    }

    @Override
    public UserBean update(UserBean userBean) {

        if (userBean == null) {
            return null;
        }


        User user = userDao.findByCodeAndValid(userBean.getCode(), VALID);


        if (user == null) {
            return null;
        }

        beanToDomain(userBean, user, "id", "code", "version", "createTime", "updateTime", "valid");

        userDao.save(user);

        domainToBean(user, userBean);

        return userBean;
    }

    @Override
    public UserBean delete(UserBean userBean) {

        if (userBean == null) {
            return null;
        }


        User user = userDao.findByCodeAndValid(userBean.getCode(), VALID);


        if (user == null) {
            return null;
        }


        user.setValid(INVALID);
        userDao.save(user);


        domainToBean(user, userBean);

        return userBean;
    }

    @Override
    public UserBean find(UserBean userBean) {
        if (userBean == null) {
            return null;
        }


        User user = userDao.findByCodeAndValid(userBean.getCode(), VALID);


        if (user == null) {
            return null;
        }
        BeanUtils.copyProperties(user, userBean);
        return userBean;
    }

    @Override
    public UserBean find(String code) {
        return this.find(UserBean.builder().code(code).build());
    }

    @Override
    public List<UserBean> findAll(UserBean userBean, PagerBean pagerBean) {
        List<UserBean> userBeans = new ArrayList<>();
        DetachedCriteria detachedCriteria = createListCriteria(userBean);
        List<User> users = userDao.findAll(detachedCriteria, pagerBean);
        for (User user : users) {
            UserBean userBeanTemp = new UserBean();
            domainToBean(user, userBeanTemp);
            userBeans.add(userBeanTemp);
        }
        return userBeans;
    }

    @Override
    public List<UserBean> findAll(UserBean userBean) {
        return this.findAll(userBean, null);
    }

    @Override
    public Long countAll(UserBean userBean) {
        DetachedCriteria detachedCriteria = createListCriteria(userBean);
        return userDao.countAll(detachedCriteria);
    }

    @Override
    public PagerBean<UserBean> findPager(UserBean userBean, PagerBean pagerBean) {
        List<UserBean> userBeans = this.findAll(userBean, pagerBean);
        Long count = this.countAll(userBean);
        PagerBean<UserBean> userPageBean = new PagerBean<>();
        BeanUtils.copyProperties(pagerBean, userPageBean);
        userPageBean.setItemCount(count.intValue());
        userPageBean.init();
        userPageBean.setItems(userBeans);
        return userPageBean;
    }

    /**
     * 创建列表查询条件
     *
     * @param userBean 查询参数
     * @return
     */
    private static DetachedCriteria createListCriteria(UserBean userBean) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);

        if (userBean != null) {
            if (StringUtils.isNotBlank(userBean.getRealname())) {
                detachedCriteria.add(Restrictions.like("realname", userBean.getRealname(), MatchMode.ANYWHERE));
            }
            if (StringUtils.isNotBlank(userBean.getAccount())) {
                detachedCriteria.add(Restrictions.like("account", userBean.getAccount(), MatchMode.ANYWHERE));
            }
            if (StringUtils.isNotBlank(userBean.getRoleFlag())) {
                detachedCriteria.add(Restrictions.eq("roleFlag", userBean.getRoleFlag()));
            }
            if (StringUtils.isNotBlank(userBean.getPhone())) {
                detachedCriteria.add(Restrictions.like("phone", userBean.getPhone(), MatchMode.ANYWHERE));
            }

        }

        detachedCriteria.add(Restrictions.eq("valid", VALID));
        return detachedCriteria;
    }


    @Override
    public void batchDelete(List<UserBean> userBean) {
        if (userBean.isEmpty()) {
            return;
        }
        List<String> codes = new ArrayList<>();
        userBean.forEach((e) -> {
            codes.add(e.getCode());
        });
        batchDeleteByCodes(codes);

    }


    @Override
    public void batchDeleteByCodes(List<String> codes) {

        if (codes.isEmpty()) {
            return;
        }

        for (String code : codes) {
            Assert.notNull(this.delete(UserBean.builder().code(code).build()), "batch delete by codes error! ");
        }

    }

    @Override
    public UserBean bindRole(UserBean userBean) {

        if (userBean == null) {
            return null;
        }

        User user = userDao.findByCodeAndValid(userBean.getCode(), VALID);

        if (user == null) {
            return null;
        }

        String roleFlag = userBean.getRoleFlag();

        Role role = roleDao.findByFlagAndValid(roleFlag, VALID);

        user.setRoleCode(role.getCode());

        userDao.save(user);

        domainToBean(user, userBean);

        return userBean;
    }

    @Override
    public boolean updateUserPassword(UserBean userBean, String newPassword) {

        Assert.hasText(userBean.getCode(), "userBean.code不能为空");

        User user = this.userDao.findByCodeAndValid(userBean.getCode(), VALID);

        Assert.notNull(user, "用户不存在");

        user.setPassword(newPassword);

        this.userDao.save(user);

        return true;
    }


}
