package com.rf.psychological.user.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.rf.psychological.scale.dao.model.SubjectEntity;
import com.rf.psychological.scale.service.UserRecordService;
import com.rf.psychological.user.dao.model.UserEntity;
import com.rf.psychological.scale.dao.repository.SubjectRepository;
import com.rf.psychological.enums.UserRole;
import com.rf.psychological.plan.dao.repository.TestPlanUserRepository;
import com.rf.psychological.scale.dao.repository.UserRecordRepository;
import com.rf.psychological.user.dao.repository.UserRepository;
import com.rf.psychological.user.service.UserService;
import com.rf.psychological.utils.PageRequestUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author zsy
 * @description:登录认证
 * @date 2021/6/17 15:55
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private SubjectRepository subjectRepository;

    @Autowired
    private UserRecordRepository userRecordRepository;

    @Autowired
    private UserRecordService userRecordService;

    @Autowired
    private TestPlanUserRepository testPlanUserRepository;


    /**
     * 根据手机号查询
     *
     * @return
     */
    @Override
    public UserEntity findPhone(String phone) {
        return userRepository.findPhone(phone);
    }

    /**
     * 根据用户id
     *
     * @return
     */
    @Override
    public UserEntity getOne(String userId) {
        return userRepository.findById(userId).orElse(null);
    }

    @Override
    public UserEntity findOne(String userId) {
        return userRepository.findById(userId).orElse(null);
    }

    /**
     * 保存
     *
     * @param userEntity
     */
    @Override
    @CachePut(value = "user",key = "#result.phone+','+#result.institutionNo+','+#result.roleType",unless = "#result == null")
    public UserEntity save(UserEntity userEntity) {
        return this.userRepository.save(userEntity);
    }

    /**
     * 根据手机号修改密码
     *
     * @return
     */
    @Override
    public void updatePassword(String phone, String password, String institutionNo, String roleType) {
        this.userRepository.updatePassword(phone, password, institutionNo,roleType);
    }

    /**
     * 20210916 添加机构信息之后新增的接口  ---start
     */
    @Override
    public List<UserEntity> getUserListByInstitutionNo(int pageNum, int pageSize, String searchKey, String institutionNo, String status, String groupId) {
        int beginIndex = (pageNum - 1) * pageSize;
        return this.userRepository.getUserListByInstitutionNo(beginIndex, pageSize, searchKey, institutionNo, status, groupId);
    }

    @Override
    public int allNum(String searchKey, String institutionNo, String status, String groupId) {
        return this.userRepository.allNum(searchKey, institutionNo, status, groupId);
    }

    @Override
    public void updateUserStatus(String status, String userId) {
        this.userRepository.updateUserStatus(status, userId);
    }

    @Override
    public List<UserEntity> getTestListByInstitutionNo(int pageNum, int pageSize, String institutionNo, String searchKey, String groupId) {
        int beginIndex = (pageNum - 1) * pageSize;
        return this.userRepository.getTestListByInstitutionNo(beginIndex, pageSize, institutionNo, searchKey, groupId);
    }

    @Override
    public int allNumByInstitutionNo(String institutionNo, String searchKey, String groupId) {
        return this.userRepository.allNumByInstitutionNo(institutionNo, searchKey, groupId);
    }

    @Override
    @Cacheable(value = "user",key = "#root.args",unless = "#result == null")
    public UserEntity findPhoneAndInstitutionNoAndRoleType(String phone, String institutionNo, String roleType) {
        return this.userRepository.findByPhoneAndInstitutionNoAndRoleType(phone, institutionNo,roleType);
    }

    /**
     * 20210916 添加机构信息之后新增的接口  ---end
     */

    /*@Override
    @CacheEvict(value = "user",key = "#root.args")
    public void deleteByPhoneAndInstitutionNo(String phone, String institutionNo) {
        this.userRepository.deleteByPhoneAndInstitutionNo(phone, institutionNo);
    }*/

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "user", key = "#userEntity.phone+','+#userEntity.institutionNo+','+#userEntity.roleType" )
    public void delete(UserEntity userEntity) {
        this.userRepository.delete(userEntity);
        //删除该用户下的相关数据
        //删除用户记录
        userRecordService.deleteAllByPhoneAndInstitutionNo(userEntity.getPhone(), userEntity.getInstitutionNo());
        //删除测试计划
        testPlanUserRepository.deleteAllByuId(userEntity.getId());
    }

    @Override
    @CacheEvict(value = "user",allEntries = true)
    public void updateUserGroup(String gId, String id) {
        UserEntity userEntity = this.findOne(id);
        userEntity.setGId(gId);
        this.save(userEntity);
       // this.userRepository.updateUserGroup(gId, id);
    }


    @Override
    public List<UserEntity> findUsersInGroup(String gId) {
        return this.userRepository.findUsersInGroup(gId);
    }

    @Override
    public Page<SubjectEntity> findUserAuth(String uId, int pageNum, int pageSize, String scaleName) {
        return this.subjectRepository.findUserAuth(uId, scaleName, PageRequest.of(pageNum - 1, pageSize));
    }

    @Override
    public Page<UserEntity> findUserNoGroup(int pageNum, int pageSize, String institutionNo, String gId, String searchKey) {
        return userRepository.findUserNoGroup(institutionNo, gId, searchKey, PageRequest.of(pageNum - 1, pageSize));
    }

    @Override
    public String checkUser(String phone) {
        return this.userRepository.checkUser(phone);
    }

    @Override
    public Page<UserEntity> findUserNoTestPlan(String institutionNo, String testPlanId, String searchKey, int beginNum, int pageSize) {
        return userRepository.findUserNoTestPlan(institutionNo, testPlanId, searchKey, PageRequest.of(beginNum - 1, pageSize));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserEntity updateUserInfo(String phone, String institutionNo, String newModelPhone, String petName, String gender, String birthday, String profession) {
        UserEntity userEntity = userRepository.findByPhoneAndInstitutionNo(phone,institutionNo);
        if (userEntity == null){
            return null;
        }
        userEntity.setModelPhone(newModelPhone);
        userEntity.setPetName(petName);
        userEntity.setGender(gender);
        userEntity.setBirthday(birthday);
        userEntity.setProfession(profession);
        return userRepository.save(userEntity);
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public UserEntity findModelPhone(String phone, String institutionNo) {
        UserEntity qUser = new UserEntity();
        qUser.setInstitutionNo(institutionNo);
        qUser.setUserStatus(null);
        qUser.setPhone(phone);
        Optional<UserEntity> one = userRepository.findOne(Example.of(qUser));
        return one.orElse(null);
    }

    @Override
    public List<UserEntity> getuserListByMPhone(String id) {
        return this.userRepository.getuserListByMPhone(id);
    }

    /**
     * 查询分组编号==0 的用户所在的组织编号,用于定时任务
     *
     * @param groupId
     * @return
     */
    @Override
    public List<String> findInstitutionNosByGroupId(String groupId) {
        return this.userRepository.findInstitutionNosByGroupId(groupId);
    }

    /**
     * 更新用户分组信息
     *
     * @param institutionNo 机构编号
     * @param oldGroupId    原分组编号
     * @param newGroupId    新分组编号
     */
    @Override
    @CacheEvict(value = "user",allEntries = true)
    public void updateUserGroup(String institutionNo, String oldGroupId, String newGroupId) {
        this.userRepository.updateUserGroup(institutionNo, oldGroupId, newGroupId);
    }

    /**
     * 查询用户分页
     *
     * @param jsonObject
     * @return
     */
    @Override
    public Page<UserEntity> findUsersInGroup(JSONObject jsonObject) {
        Page<UserEntity> result = null;
        int pageNum = 0;
        int pageSize = 0;
        if (!jsonObject.containsKey("pageNum") || jsonObject.getInteger("pageNum") <= 0) {
            pageNum = 1;
        } else {
            pageNum = jsonObject.getInteger("pageNum");
        }
        if (!jsonObject.containsKey("pageSize") || jsonObject.getInteger("pageSize") <= 0) {
            pageSize = 10;
        } else {
            pageSize = jsonObject.getInteger("pageSize");
        }
        try {
            Specification specification = (Specification<UserEntity>) (root, query, cb) -> {
                List<Predicate> list = new ArrayList<>();

                if (StringUtils.isNotEmpty(jsonObject.getString("userName"))) {

                    list.add(cb.like(root.get("petName"), "%" + jsonObject.getString("userName") + "%"));
                }
                if (StringUtils.isNotEmpty(jsonObject.getString("gId"))) {
                    list.add(cb.equal(root.get("gId"), jsonObject.getString("gId")));
                }
                query.where(cb.and(list.toArray(new Predicate[list.size()])));
                //排序的升序和倒叙的写法
                query.orderBy(cb.desc(root.get("id")));
                return query.getRestriction();
            };
            result = userRepository.findAll(specification, PageRequest.of(pageNum - 1, pageSize));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * userIds -->List<UserEntity>
     *
     * @param userIdList
     * @return
     */
    @Override
    public List<UserEntity> getUserByIds(List<String> userIdList) {
        return this.userRepository.getUserByIds(userIdList);
    }

    /**
     * 检索账号或机构名称下的用户
     * @param pageNum 页码
     * @param pageSize 数量
     * @param searchKey 检索字段
     * @return
     */
    @Override
    public Page<UserEntity> findUserByPhoneOrInstitutionName(int pageNum, int pageSize, String searchKey) {
        Page<UserEntity> result = null;
        try {
            Specification specification = (Specification<UserEntity>) (root, query, cb) -> {
                List<Predicate> list = new ArrayList<>();
                list.add(cb.equal(root.get("roleType"), UserRole.ADMIN.getType()));
                if (StringUtils.isNotEmpty(searchKey)) {
                    list.add(cb.or(cb.like(root.get("phone"),"%"+searchKey+"%"),cb.like(root.get("institutionName"),"%"+searchKey+"%")));
                }
                query.where(cb.and(list.toArray(new Predicate[list.size()])));
                //排序的升序和倒叙的写法
                //query.orderBy(cb.desc(root.get("id")));
                return query.getRestriction();
            };
            result = userRepository.findAll(specification, PageRequestUtil.of(pageNum , pageSize));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /*@Override
    public UserEntity findPhoneAndInstitutionNo(String phone, String institutionNo) {
        return userRepository.findByPhoneAndInstitutionNo(phone,institutionNo);
    }*/

    @Override
    public UserEntity findUserById(String id) {
        return this.userRepository.findById(id).orElse(null);
    }

    /**
     * 查询用户
     * @param modelPhone 手机号
     * @param institutionNo 机构编号
     * @return
     */
    @Override
    public UserEntity findByModelPhoneAndeInstitution(String modelPhone, String institutionNo,String type) {
        return userRepository.findByModelPhoneAndInstitutionNoAndRoleType(modelPhone,institutionNo,type);
    }

    //查询机构下待审核人员
    @Override
    public List<UserEntity> findByStatus(String institutionNo, String Status) {
        return userRepository.findByStatus(institutionNo,Status);
    }

    /**
     * 改变用户状态
     * @param phone 账号
     * @param userStatus 状态值
     * @param institutionNo 机构编号
     */
    @Override
    public void updateUserStatusByPhone(String phone, String userStatus, String institutionNo) {
        userRepository.updateUserStatusByPhone(phone,userStatus,institutionNo);
    }

    /**
     * 查询机构下用户
     * @param pageNum 页码
     * @param pageSize 数量
     * @param institutionNo 机构编号
     * @param searchKey 查询值
     * @param role 用户角色
     * @param like 是否模糊查询
     * @return
     */
    @Override
    public Page<UserEntity> findUserByPhoneOrNameInInstitutionNo(int pageNum, int pageSize, String institutionNo, String searchKey, UserRole role,boolean like) {
        Page<UserEntity> result = null;
        try {
            Specification specification = (Specification<UserEntity>) (root, query, cb) -> {
                List<Predicate> list = new ArrayList<>();
                list.add(cb.equal(root.get("institutionNo"),institutionNo));
                list.add(cb.equal(root.get("roleType"),role.getType()));
                if (StringUtils.isNotEmpty(searchKey)) {
                    if(like){
                        list.add(cb.or(cb.like(root.get("phone"),"%"+searchKey+"%"),cb.like(root.get("petName"),"%"+searchKey+"%")));
                    }else {
                        list.add(cb.or(cb.equal(root.get("phone"),searchKey),cb.equal(root.get("petName"),searchKey)));
                    }

                }
                query.where(cb.and(list.toArray(new Predicate[list.size()])));
                //排序的升序和倒叙的写法
                //query.orderBy(cb.desc(root.get("id")));
                return query.getRestriction();
            };
            result = userRepository.findAll(specification, PageRequestUtil.of(pageNum , pageSize));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 查询机构下用户
     * @param institutionNo 机构编号
     * @param searchKey 查询值
     * @param role 用户角色
     * @param like 是否模糊查询
     * @return
     */
    @Override
    public List<UserEntity> findUserByPhoneOrNameInInstitutionNo(String institutionNo, String searchKey, UserRole role,boolean like) {
        List<UserEntity> result = null;
        try {
            Specification<UserEntity> specification = (root, query, cb) -> {
                List<Predicate> list = new ArrayList<>();
                list.add(cb.equal(root.get("institutionNo"),institutionNo));
                list.add(cb.equal(root.get("roleType"),role.getType()));
                if(like){
                    list.add(cb.or(cb.like(root.get("phone"),"%"+searchKey+"%"),cb.like(root.get("petName"),"%"+searchKey+"%")));
                }else {
                    list.add(cb.or(cb.equal(root.get("phone"),searchKey),cb.equal(root.get("petName"),searchKey)));
                }
                query.where(cb.and(list.toArray(new Predicate[0])));
                //排序的升序和倒叙的写法
                //query.orderBy(cb.desc(root.get("id")));
                return query.getRestriction();
            };
            result = userRepository.findAll(specification);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


}
