package com.zcxk.service;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcxk.common.ToolUtil;
import com.zcxk.dao.OrgMapper;
import com.zcxk.dao.UserMapper;
import com.zcxk.dto.MaintainerCountDto;
import com.zcxk.dto.UserListDto;
import com.zcxk.entity.Org;
import com.zcxk.entity.UserEntity;
import com.zcxk.entity.UserRoleEntity;
import com.zcxk.entity.UserTagEntity;
import com.zcxk.model.LoginUser;
import com.zcxk.util.ByteArrayUtils;
import com.zcxk.util.RedisUtil;
import com.zcxk.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

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

/**
 *
 * 用户Service接口
 * @author: WYY
 * @date 2020-10-22 17:35
 */
@Service
public class UserService extends ServiceImpl<UserMapper,UserEntity> {

	@Resource
	private UserMapper userMapper;
	@Resource
	private UserTagService userTagService;
	@Resource
	private UserRoleService userRoleService;
	@Resource
	private OrgMapper orgMapper;
	@Autowired
	private RedisUtil redisUtil;
	@Value("${add_iot_user_url}")
	private String addIotUserUrl;

	/**
	 * 自定义分页查询，含关联实体对像
	 */
	public IPage<UserEntity> findPage(IPage<UserEntity> page, UserEntity userEntity) {
		LoginUser currentUser = UserUtil.getCurrentUser();
		userEntity.setTenantId(currentUser.getTenantId());
		userEntity.setProgramItems(currentUser.getProgramItemList());
		userEntity.setUserType(currentUser.getType());
		//1是公司，2是公司及以下，3部门，4部门及以下，5自定义
		userEntity.setPermissonType(currentUser.getPermissonType());
		Page<UserEntity> userPage = userMapper.findPage(page, userEntity);
		return userPage;
	}

	/**
	 * 查列表
	 */
	public List<UserEntity> findList(UserEntity userEntity) {
		LoginUser currentUser = UserUtil.getCurrentUser();
		userEntity.setTenantId(currentUser.getTenantId());
		return userMapper.findList(userEntity);
	}

	/**
	 * 批量删除
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean delUserByIds(Long[] ids) {
		for (Long id : ids) {
			UserEntity userEntity = findUserById(id);
			if (userEntity != null) {
				//將禁用的角色放入redis，作为登出判断
				if (userEntity.getEnableState().equals("0")) {
					String roleKey = "disableUser:" + id;
					redisUtil.setExpire(roleKey.getBytes(), ByteArrayUtils.objectToBytes("1").get(), 60 * 60 * 24);//15分钟过期

				}
				if (userEntity.getEnableState().equals("1")) {
					String roleKey = "disableUser:" + id;
					redisUtil.del(roleKey.getBytes());
				}
			}
		}
		return this.removeByIds(Arrays.asList(ids));
	}

	public boolean checkMobileUnique(String phone) {
		LoginUser currentUser = UserUtil.getCurrentUser();
		int count = this.count(new QueryWrapper<UserEntity>().eq("phone", phone).eq("tenant_id",currentUser.getTenantId()));
		if (count > 0) {
			return true;
		}
		return false;
	}

	public boolean checkMobileUnique(UserEntity user) {
		LoginUser currentUser = UserUtil.getCurrentUser();
		Long userId = ToolUtil.isEmpty(user.getId()) ? -1L : user.getId();
		UserEntity info = this.getOne(new QueryWrapper<UserEntity>().eq("phone", user.getPhone()).eq("tenant_id",currentUser.getTenantId()));
		if (ToolUtil.isNotEmpty(info) && !info.getId().equals(userId)) {
			return true;
		}
		return false;
	}

	/**
	 * 单个删除
	 */
	public boolean delUserById(Long id) {
		UserEntity userEntity = findUserById(id);
		if (userEntity != null) {
			//將禁用的角色放入redis，作为登出判断
			if (userEntity.getEnableState().equals("0")) {
			String roleKey = "disableUser:" + id;
			redisUtil.setExpire(roleKey.getBytes(), ByteArrayUtils.objectToBytes("1").get(), 60 * 60 * 24);//15分钟过期

		}
		if (userEntity.getEnableState().equals("1")) {
			String roleKey = "disableUser:" + id;
			redisUtil.del(roleKey.getBytes());
		}
	}
		return this.removeById(id);
	}

	/**
	 * 保存
	 */
	public boolean addUser(UserEntity user) {
		user.setUniqId(UUID.randomUUID().toString());
		if (this.save(user)) {
			Long pkId = user.getId();
			//添加用户标签
			if (user.getUserTags() != null) {
				for (Long item : user.getUserTags()) {
					UserTagEntity userTagEntity = new UserTagEntity();
					userTagEntity.setCreateBy(user.getCreateBy());
					userTagEntity.setUpdateBy(user.getUpdateBy());
					userTagEntity.setDateCreate(user.getDateCreate());
					userTagEntity.setDateUpdate(user.getDateUpdate());
					userTagEntity.setStatus(1);
					userTagEntity.setTagId(Long.valueOf(item));
					userTagEntity.setUserId(pkId);
					userTagService.addUserTag(userTagEntity);
				}
			}
			//添加角色
			if (user.getRoleId() != null) {
				UserRoleEntity userRoleEntity = new UserRoleEntity();
				userRoleEntity.setCreateBy(user.getCreateBy());
				userRoleEntity.setUpdateBy(user.getUpdateBy());
				userRoleEntity.setDateCreate(user.getDateCreate());
				userRoleEntity.setDateUpdate(user.getDateUpdate());
				userRoleEntity.setStatus(1);
				userRoleEntity.setRoleId(Long.valueOf(user.getRoleId()));
				userRoleEntity.setUserId(pkId);
				userRoleService.addUserRole(userRoleEntity);
			}
			addIotUser(user);
			return true;
		}
		return false;
	}
	private void addIotUser(UserEntity userEntity){
		try {
			HttpHeaders headers = new HttpHeaders();
			JSONObject args=new JSONObject();
			args.put("username",userEntity.getUsername());
			args.put("mobilePhone",userEntity.getPhone());
			args.put("tenantId",userEntity.getTenantId());
			args.put("uniqId",userEntity.getUniqId());
			headers.setContentType(MediaType.APPLICATION_JSON);
			HttpEntity<String> formEntity = new HttpEntity<>(args.toJSONString(), headers);

			RestTemplate restTemplate=new RestTemplate();
			restTemplate.postForEntity(addIotUserUrl, formEntity,String.class);
		 }catch (Exception e){
			log.error("添加物联网用户失败",e);
		}



	}

	/**
	 * 修改根居ID
	 */
	public boolean updateUserById(UserEntity user) {
		if (this.updateById(user)) {
			UserEntity userEntity = findUserById(user.getId());
			if (userEntity != null) {
				//將禁用的角色放入redis，作为登出判断
				if (userEntity.getEnableState().equals("0")) {
					String roleKey = "disableUser:" + user.getId();
					redisUtil.setExpire(roleKey.getBytes(), ByteArrayUtils.objectToBytes("1").get(), 60 * 60 * 24);//15分钟过期

				}
				if (userEntity.getEnableState().equals("1")) {
					String roleKey = "disableUser:" + user.getId();
					redisUtil.del(roleKey.getBytes());
				}
			}
			//更新关联附件信息						
			Long pkId = user.getId();
			//添加用户标签
			if (user.getUserTags() != null && user.getUserTags().size() > 0) {
				//先删除之前的标签
				List<UserTagEntity> userTagEntitys = new ArrayList<>();
				UserTagEntity userTagDelete = new UserTagEntity();
				userTagDelete.setUserId(pkId);
				userTagEntitys = userTagService.findList(userTagDelete);
				Long[] ids = new Long[userTagEntitys.size()];
				for (int i = 0; i < userTagEntitys.size(); i++) {
					ids[i] = userTagEntitys.get(i).getId();
				}
				userTagService.delUserTagByIds(ids);
				//新增标签
				for (Long item : user.getUserTags()) {
					UserTagEntity userTagEntity = new UserTagEntity();
					userTagEntity.setCreateBy(user.getCreateBy());
					userTagEntity.setUpdateBy(user.getUpdateBy());
					userTagEntity.setDateCreate(user.getDateCreate());
					userTagEntity.setDateUpdate(user.getDateUpdate());
					userTagEntity.setStatus(1);
					userTagEntity.setTagId(Long.valueOf(item));
					userTagEntity.setUserId(pkId);
					userTagService.addUserTag(userTagEntity);
				}
			}
			//修改角色
			if (user.getRoleId() != null) {
				List<UserRoleEntity> userRoleEntities = new ArrayList<>();
				UserRoleEntity userRoleEntity = new UserRoleEntity();
				userRoleEntity.setUserId(pkId);
				userRoleEntities = userRoleService.findList(userRoleEntity);
				if (userRoleEntities.size() > 0) {
					Long userRoleId = userRoleEntities.get(0).getId();
					userRoleService.delUserRoleById(userRoleId);
				}
				//新增角色
				UserRoleEntity userRole = new UserRoleEntity();
				userRole.setCreateBy(user.getCreateBy());
				userRole.setUpdateBy(user.getUpdateBy());
				userRole.setDateCreate(user.getDateCreate());
				userRole.setDateUpdate(user.getDateUpdate());
				userRole.setStatus(1);
				userRole.setRoleId(Long.valueOf(user.getRoleId()));
				userRole.setUserId(pkId);
				userRoleService.addUserRole(userRole);
			}
			return true;
		}
		return false;
	}

	/**
	 * 根居ID获取对象
	 */
	public UserEntity findUserById(Long id) {
		List<UserTagEntity> userTagEntitys = new ArrayList<>();
		UserTagEntity userTags = new UserTagEntity();
		userTags.setUserId(id);
		userTagEntitys = userTagService.findList(userTags);
		List<Long> ids = new ArrayList<>();
		for (int i = 0; i < userTagEntitys.size(); i++) {
			ids.add(userTagEntitys.get(i).getTagId());
		}
		UserEntity userEntity = userMapper.findUserById(id);
		userEntity.setUserTags(ids);
		return userEntity;
	}

    public List<Integer> getUserIdsByOrgId(List<Integer> orgIds) {
		List<Integer>userIds=new ArrayList<>();
		if(orgIds.size()>0){
			userIds=userMapper.getUserIdsByOrgId(orgIds);
		}


		return userIds;
    }
	public List<UserEntity> findUserIdsByOrgId(List<Integer> orgIds)
	{
		List<UserEntity> userEntities = new ArrayList<>();
		if(orgIds.size()>0){
			userEntities=userMapper.findUserIdsByOrgId(orgIds);
		}
		return userEntities;
	}
	public List<UserEntity> findUserIdsByOrgIdAndType(List<Integer> orgIds)
	{
		List<UserEntity> userEntities = new ArrayList<>();
		if(orgIds.size()>0){
			userEntities=userMapper.findUserIdsByOrgIdAndType(orgIds);
		}
		return userEntities;
	}
	public List<UserListDto> findUserList(Integer type)
	{
		List<UserListDto> userListDtos = new ArrayList<>();
		LoginUser currentUser = UserUtil.getCurrentUser();
		UserEntity userEntity=new UserEntity();
		userEntity.setTenantId(currentUser.getTenantId());
		userEntity.setProgramItems(currentUser.getProgramItemList());
		userEntity.setUserType(currentUser.getType());
		//1是公司，2是公司及以下，3部门，4部门及以下，5自定义
		userEntity.setPermissonType(currentUser.getPermissonType());
		List<UserEntity>userEntities=userMapper.findUserList(userEntity,type);
		List<UserEntity>companyUser=new ArrayList<>();
		List<UserEntity>departmentUser=new ArrayList<>();
		if(type==null){
			userEntities.forEach(user->{
				if(user.getDeptOrgId()!=null){
					departmentUser.add(user);
				}else{
					companyUser.add(user);
				}
			});
			Map<Long, List<UserEntity>> companyGroup = companyUser.stream()
					.collect(Collectors.groupingBy(d -> d.getCompanyOrgId()));
			Map<Long, List<UserEntity>> departMentGroup = departmentUser.stream()
					.collect(Collectors.groupingBy(d -> d.getDeptOrgId()));
			Iterator<List<UserEntity>> companyIterator = companyGroup.values().iterator();
			Iterator<List<UserEntity>> departmentIterator = departMentGroup.values().iterator();
			while(companyIterator.hasNext()){
				List<UserEntity> users = companyIterator.next();
				UserListDto userListDto=new UserListDto();
				UserEntity user = users.get(0);
				userListDto.setLabel(user.getCompanyOrgName());
				userListDto.setId(user.getCompanyOrgId());
				userListDto.setValue(user.getCompanyOrgName());
				userListDto.setChildren(setChildrens(users));
				userListDtos.add(userListDto);

			}
			while(departmentIterator.hasNext()){
				List<UserEntity> users = departmentIterator.next();
				UserListDto userListDto=new UserListDto();
				UserEntity user = users.get(0);
				userListDto.setLabel(user.getDeptOrgName());
				userListDto.setId(user.getDeptOrgId());
				userListDto.setValue(user.getDeptOrgName());
				userListDto.setChildren(setChildrens(users));
				userListDtos.add(userListDto);

			}
		}else{
			userEntities.forEach(userParam->{
				UserListDto userInfo=new UserListDto();
				userInfo.setLabel(userParam.getUsername());
				userInfo.setId(userParam.getId());
				userInfo.setValue(userParam.getUsername());
				userListDtos.add(userInfo);
			});
		}

		return userListDtos;
	}
	private List<UserListDto> setChildrens(List<UserEntity> users){
		List<UserListDto> childrens=new ArrayList<>();
		users.forEach(u->{
			UserListDto children=new UserListDto();
			children.setLabel(u.getUsername());
			children.setId(u.getId());
			children.setValue(u.getUsername());
			childrens.add(children);
		});
		return childrens;
	}
	public List<UserEntity> findUserIdsByUserIds(List<Integer> userIds) {
		List<UserEntity> userEntities = new ArrayList<>();
		if(userIds.size()>0){
			userEntities=userMapper.findUserIdsByUserIds(userIds);
		}
		return userEntities;
	}

    public List<UserEntity> findUserIdsForOrg() {
		LoginUser currentUser = UserUtil.getCurrentUser();
		Integer compayId = currentUser.getCompanyId();
		Integer deptId = currentUser.getDepartmentId();
		String ids = "";
		if (deptId != null)
			ids = orgMapper.findParentOrgByChildId(deptId);
		//查询公司
		String comps = orgMapper.findParentOrgByChildId(compayId);
		String[] compids = comps.split(",");
		List<Long> compList = new ArrayList<>();
		for (String item : compids) {
			if (!item.equals(compayId.toString()))
				compList.add(Long.valueOf(item));
		}

		List<Long> idList = new ArrayList<>();
		String[] as = ids.split(",");
		for (String item : as) {
			idList.add(Long.valueOf(item));
		}
		List<UserEntity> list = userMapper.findUserIdsForOrg(compayId, deptId, idList,compList);
		return list;
	}
	public List<Integer> findUserIdsByPermissonOrg(String tenantId,Integer companyOrgId,Integer deptOrgId){

		List<Integer> userIds = new ArrayList<>();

		//1是公司，2是公司及以下，3部门，4部门及以下，5自定义
		if(companyOrgId == null){
			return userIds;
		}
		//查询租户下所有公司部门
		List<Org> orgs = orgMapper.findOrgByTenant(tenantId);
		Map<Integer ,Org> orgMap = orgs.stream().collect(Collectors.toMap(Org::getId, a -> a, (k1, k2) -> k1));

		List<Integer> companyOrgIds = new ArrayList<>();
		List<Integer> deptOrgIds = new ArrayList<>();
		Integer deptOrgParentId =deptOrgId;
		if(deptOrgId != null){
			//权限类型为4部门及以下
			while(true){
				Org org = orgMap.get(deptOrgParentId);
				if(org == null ){
					break;
				}
				if(org.getOrgType().equals("company") ){
					break;
				}
				deptOrgIds.add(deptOrgParentId);
				deptOrgParentId = org.getParentOrgId();
			}
		}
		//权限类型为2是公司及以下
		Integer companyOrgParentId = companyOrgId ;
		while(true){
			Org org = orgMap.get(companyOrgParentId);
			if(org == null ){
				break;
			}
			companyOrgIds.add(companyOrgParentId);
			companyOrgParentId = org.getParentOrgId();
			if(org.getParentOrgId() == 0){
				break;
			}
		}
		//查询客户id
		if(companyOrgId != null && companyOrgIds.size() > 0){
			userIds = userMapper.findUserIdsByPermissonOrg(tenantId,companyOrgId,deptOrgId,companyOrgIds,deptOrgIds);
		}
		return userIds;
	}

	public List<UserEntity> findUserListBytype(Integer type) {
		List<UserListDto> userListDtos = new ArrayList<>();
		LoginUser currentUser = UserUtil.getCurrentUser();
		UserEntity userEntity = new UserEntity();
		userEntity.setTenantId(currentUser.getTenantId());
		userEntity.setProgramItems(currentUser.getProgramItemList());
		userEntity.setUserType(String.valueOf(type));
		//1是公司，2是公司及以下，3部门，4部门及以下，5自定义
		userEntity.setPermissonType(currentUser.getPermissonType());
		List<UserEntity> userEntities = userMapper.findUserListByType(userEntity);
		return userEntities;
	}

	/**
	 * 按类型租户及公司查询用户信息
	 * @param companyOrgId
	 * @param tenantId
	 * @param type
	 * @return
	 */
	public List<UserEntity> findAllUserList(Integer companyOrgId, String tenantId,int type) {
		UserEntity userEntity = new UserEntity();
		userEntity.setUserType(String.valueOf(type));
		userEntity.setTenantId(tenantId);
		userEntity.setCompanyOrgId(Long.valueOf(companyOrgId));
		List<UserEntity> userEntities = userMapper.findAllUserListByType(userEntity);
		return userEntities;
	}
	public MaintainerCountDto findMaintainer(String startDate, String endDate, Integer statsType){
		MaintainerCountDto result=new MaintainerCountDto();
		try {
			LoginUser currentUser = UserUtil.getCurrentUser();
			UserEntity userEntity = new UserEntity();
			userEntity.setTenantId(currentUser.getTenantId());
			userEntity.setProgramItems(currentUser.getProgramItemList());
			//1是公司，2是公司及以下，3部门，4部门及以下，5自定义
			userEntity.setPermissonType(currentUser.getPermissonType());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar c=Calendar.getInstance();
			Date thisDate=null, dateMtoM=null,dateYtoY=null;
			if(statsType==0){
				dateMtoM=sdf.parse(startDate+"-1");
				c.setTime(dateMtoM);
				c.add(Calendar.MONTH,1);
				thisDate=c.getTime();
				c.add(Calendar.YEAR,-1);
				dateYtoY=c.getTime();
			}else if(statsType==1){
				dateMtoM=sdf.parse(startDate+"-1-1");
				dateYtoY=dateMtoM;
				c.setTime(dateMtoM);
				c.add(Calendar.YEAR,1);
				thisDate=c.getTime();
			}else if(statsType==2){
				dateMtoM=sdf.parse(startDate+"-1");
				thisDate=sdf.parse(endDate+"-1");
				c.setTime(thisDate);
				c.add(Calendar.MONTH,1);
				thisDate=c.getTime();
				c.add(Calendar.YEAR,-1);
				dateYtoY=c.getTime();
			}
			userEntity.setDateCreate(thisDate);
			result.setCount(userMapper.findMaintainer(userEntity));
			userEntity.setDateCreate(dateMtoM);
			result.setCountMOnM(userMapper.findMaintainer(userEntity));
			userEntity.setDateCreate(dateYtoY);
			result.setCountYOnY(userMapper.findMaintainer(userEntity));
			result.setRateMOnM(result.getCountMOnM()!=0?(double)(result.getCount()-result.getCountMOnM())/result.getCountMOnM()*100:null);
			result.setRateYOnY(result.getCountYOnY()!=0?(double)(result.getCount()-result.getCountYOnY())/result.getCountYOnY()*100:null);
		}catch (Exception e){
			e.printStackTrace();
		}
		return result;
	}

	public Integer findMaintainerCount(String endDate){
		Integer maintainerCount=0;
		try {
			LoginUser currentUser = UserUtil.getCurrentUser();
			UserEntity userEntity = new UserEntity();
			userEntity.setTenantId(currentUser.getTenantId());
			userEntity.setProgramItems(currentUser.getProgramItemList());
			//1是公司，2是公司及以下，3部门，4部门及以下，5自定义
			userEntity.setPermissonType(currentUser.getPermissonType());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar c=Calendar.getInstance();
			c.setTime(sdf.parse(endDate+"-1"));
			c.add(Calendar.MONTH,1);
			userEntity.setDateCreate(c.getTime());
			maintainerCount=userMapper.findMaintainer(userEntity);
		}catch (Exception e){
			e.printStackTrace();
		}
		return maintainerCount;
	}
}
