package com.iformall.service.invest.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iformall.domain.dto.InvestDemandDto;
import com.iformall.domain.dto.InvestTaskDto;
import com.iformall.domain.po.*;
import com.iformall.domain.po.invest.*;
import com.iformall.domain.vo.invest.*;
import com.iformall.enums.*;
import com.iformall.service.MallUserInfoService;
import com.iformall.service.WxBrandService;
import com.iformall.service.WxRentContractService;
import com.iformall.service.WxShopService;
import com.iformall.service.invest.*;
import com.iformall.utils.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class InvestBizServiceImpl implements InvestBizService {

	@Autowired
	private InvestDemandService demandService;
	@Autowired
	private InvestTaskService taskService;
	@Autowired
	private InvestFollowRecordService followRecordService;
	@Autowired
	private InvestOperateRecordService operateRecordService;
	@Autowired
	private InvestRemindService remindService;
	@Autowired
	private InvestMessageService messageService;
	@Autowired
	private WxShopService shopService;
	@Autowired
	private InvestCustomerService customerService;
	@Autowired
	private WxBrandService brandService;
	@Autowired
	private MallUserInfoService userInfoService;
	@Autowired
	private WxRentContractService rentContractService;

	@Override
	public InvestPageResult<InvestDemandVo> queryPageDemand(InvestDemandQuery params) {
		InvestDemandDto queryParams = convert(params, this::doConvertDemand);
		InvestCustomerEntity customerParams = null;
		InvestDemandEntity demandParams = null;
		if (Objects.nonNull(queryParams)) {
			customerParams = queryParams.getCustomer();
			demandParams = queryParams.getDemand();
		}
		InvestPageResult<InvestDemandVo> investPage = new InvestPageResult<>();
		List<InvestDemandEntity> demandList = demandService.list(new LambdaQueryWrapper<>(demandParams));
		LambdaQueryWrapper<InvestCustomerEntity> queryWrapperCustomer = new LambdaQueryWrapper<>(customerParams);
		InvestPageResult<InvestCustomerEntity> customers;
		if (Objects.isNull(InvestUserContext.getDataUser())) {
			queryWrapperCustomer.in(ObjectUtils.allNotNull(params.getDemandOwner()),InvestCustomerEntity::getId, getIds(demandList, InvestDemandEntity::getCustomerId));
		} else {
			if(CollectionUtils.isEmpty(demandList)) {
				return investPage;
			} else {
				queryWrapperCustomer.in(InvestCustomerEntity::getId, getIds(demandList, InvestDemandEntity::getCustomerId));
			}
		}
		customers = customerService.queryPage(buildPageQuery(params, null), queryWrapperCustomer);
		List<InvestDemandVo> resultList = getTargeInfoList(demandList, customers.getRecords());
		BeanUtils.copyProperties(customers, investPage);
		investPage.setRecords(resultList);
		if (CollectionUtils.isEmpty(customers.getRecords())) {
			return investPage;
		}

		return investPage;
	}

	@Override
	public List<InvestDemandVo> queryCustomer() {
		List<InvestCustomerEntity> customerEntities = customerService.list();
		return getTargeInfoList(new ArrayList<>(), customerEntities);
	}

	private InvestDemandDto doConvertDemand(InvestDemandQuery params) {
		InvestCustomerEntity customerEntity = null;
		if (ObjectUtils.anyNotNull(params.getCustomerId(), params.getCustomerType(), params.getBusinessId())) {
			customerEntity = new InvestCustomerEntity();
			customerEntity.setId(params.getCustomerId());
			customerEntity.setType(params.getCustomerType());
			customerEntity.setBusinessId(params.getBusinessId());
		}

		InvestDemandEntity demandEntity = new InvestDemandEntity();
		if (ObjectUtils.anyNotNull(params.getDemandOwner())) {
			demandEntity.setOwner(params.getDemandOwner());
		} else {
			demandEntity.setOwner(InvestUserContext.getDataUser());
		}

		InvestDemandDto demandDto = new InvestDemandDto();
		demandDto.setCustomer(customerEntity);
		demandDto.setDemand(demandEntity);
		return demandDto;
	}

	@Override
	public InvestPageResult<InvestTaskVo> queryPageTask(InvestTaskQuery params) {
		InvestTaskDto queryParams = convert(params, this::doConvertTask);
		InvestTaskEntity taskParams = null;
		WxShop shopParams = null;
		if (Objects.nonNull(queryParams)) {
			shopParams = queryParams.getShop();
			taskParams = queryParams.getTask();
		}
		LambdaQueryWrapper<InvestTaskEntity> taskQueryWrapper = new LambdaQueryWrapper<>();
		InvestPageResult<InvestTaskVo> investPage = new InvestPageResult<>();
		taskQueryWrapper.apply(StringUtils.isNotEmpty(taskParams.getOwner()), "`owner` REGEXP {0}", taskParams.getOwner());
		taskParams.setOwner(null);
		taskQueryWrapper.setEntity(taskParams);

		if (Objects.nonNull(shopParams)) {
			Collection<WxShop> shops = shopService.selectList(new QueryWrapper<>(shopParams));
			if (CollectionUtils.isEmpty(shops)) {
				return investPage;
			}
			taskQueryWrapper.in(InvestTaskEntity::getTargetId, getIds(shops, WxShop::getId));
		}

		InvestPageResult<InvestTaskEntity> taskPage = taskService.queryPage(buildPageQuery(params, null), taskQueryWrapper);
		if (CollectionUtils.isEmpty(taskPage.getRecords())) {
			return investPage;
		}

		Collection<InvestTaskEntity> taskList = taskPage.getRecords();
		//2、目标信息
		Collection<WxShop> shops = shopService.getByIds(getIds(taskList, InvestTaskEntity::getTargetId));
		//3、商品合同信息
		Map<Long, WxRentContract> shopContractMap = new HashMap<>();
		if (CollectionUtils.isNotEmpty(shops)) {
			Collection<Long> shopPointIds = buildShopContractQuery(shops, EnumRentShopType.POINT);
			Collection<Long> shopIds = buildShopContractQuery(shops, EnumRentShopType.SHOP);
			shopContractMap = rentContractService.selectRentContractByShopIds(shopPointIds, StringUtils.join(shopIds, "|"),
					InvestUserContext.getUser().getTenantId());
		}
		for (WxShop shop : shops) {
			WxRentContract contract = shopContractMap.get(shop.getId());
			if (Objects.nonNull(contract)) {
				shop.setStartdate(contract.getRentalStartDate());
				shop.setEnddate(contract.getRentalEndDate());
			}
		}

		Map<Long, WxShop> shopsMap = getMap(shops, WxShop::getId);
		//4、用户信息
		Map<Long, MallUserInfo> usersMap = getMap(this.queryUserList(null), MallUserInfo::getId);
		List<InvestTaskVo> resultList = new ArrayList<>();
		for (InvestTaskEntity item : taskList) {
			WxShop shop = shopsMap.get(item.getTargetId());
			resultList.add(buildTaskItem(item, shop, usersMap));
		}
		BeanUtils.copyProperties(taskPage, investPage);
		investPage.setRecords(resultList);
		return investPage;
	}

	private Collection<Long> buildShopContractQuery(Collection<WxShop> shops, EnumRentShopType shopType) {
		Collection<Long> shopIds = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(shops)) {
			shopIds = InvestHelper.getIds(shops, wxShop -> Objects.equals(wxShop.getType(), shopType.getCode()), WxShop::getId);
		}
		if (CollectionUtils.isEmpty(shopIds)) {
			shopIds.add(00L);
		}
		return shopIds;
	}


	private InvestTaskDto doConvertTask(InvestTaskQuery params) {
		InvestTaskEntity task = new InvestTaskEntity();
		if (Objects.nonNull(params.getTaskOwner())) {
			task.setOwner(params.getTaskOwner());
		} else {
			task.setOwner(Objects.isNull(InvestUserContext.getDataUser()) ? "" : String.valueOf(InvestUserContext.getDataUser()));
		}
		task.setStatus(params.getTaskStatus());

		WxShop shop = null;
		if (ObjectUtils.anyNotNull(params.getShopNumber(), params.getShopStatus(), params.getBusinessId())) {
			shop = new WxShop();
			shop.setShopNumber(params.getShopNumber());
			shop.setStatus(params.getShopStatus());
			shop.setBusinessId(params.getBusinessId());
		}

		InvestTaskDto taskDto = new InvestTaskDto();
		taskDto.setShop(shop);
		taskDto.setTask(task);
		return taskDto;
	}

	@Override
	public InvestPageResult<InvestFollowRecordVo> queryPageFollowRecord(InvestFollowQuery params) {
		InvestHelper.notNull(params);
		InvestFollowRecordEntity followRecordEntity = new InvestFollowRecordEntity();
		followRecordEntity.setFollowId(params.getFollowId());
		followRecordEntity.setType(params.getType());
		InvestPageQuery<InvestFollowRecordEntity> pageQuery = buildPageQuery(params, followRecordEntity);

		InvestPageResult<InvestFollowRecordEntity> recordPage = followRecordService.queryPage(pageQuery);

		InvestPageResult<InvestFollowRecordVo> investPage = new InvestPageResult<>();
		if (CollectionUtils.isEmpty(recordPage.getRecords())) {
			return investPage;
		}

		Collection<InvestFollowRecordEntity> recordList = recordPage.getRecords();

		//2、用户信息
		Map<Long, MallUserInfo> usersMap = getMap(this.queryUserList(null), MallUserInfo::getId);

		//3、客户
		Collection<InvestCustomerEntity> customers = customerService.listByIds(getIds(recordList, InvestFollowRecordEntity::getCustomerId));
		Map<Long, InvestCustomerEntity> customerMap = getMap(customers, InvestCustomerEntity::getId);
		//4、 品牌
		Map<Long, WxBrand> brandMap = getMap(brandService.getByIds(getIds(customers, InvestCustomerEntity::getBrandId)), WxBrand::getId);

		List<InvestFollowRecordVo> resultList = new ArrayList<>();
		for (InvestFollowRecordEntity item : recordList) {
			InvestCustomerEntity customerEntity = customerMap.get(item.getCustomerId());
			WxBrand brand = null;
			if (Objects.nonNull(customerEntity)) {
				brand = brandMap.get(customerEntity.getBrandId());
			}
			resultList.add(buildFollowRecordItem(usersMap, item, customerEntity, brand));
		}

		BeanUtils.copyProperties(recordPage, investPage);
		investPage.setRecords(resultList);
		return investPage;
	}

	@Override
	public InvestPageResult<InvestRemindVo> queryPageRemind(InvestRemindQuery params) {
		InvestHelper.notNull(params);
		InvestPageResult<InvestRemindVo> investPage = new InvestPageResult<>();
		InvestPageQuery<InvestRemindEntity> remindPageQuery = new InvestPageQuery<>();
		BeanUtils.copyProperties(params, remindPageQuery);
		InvestRemindEntity remindQuery = new InvestRemindEntity();
		if (Objects.isNull(params.getOwnerId())) {
			remindQuery.setOwner(InvestUserContext.getDataUser());
		} else {
			remindQuery.setOwner(params.getOwnerId());
		}
		remindPageQuery.setQueryData(remindQuery);
		LambdaQueryWrapper<InvestRemindEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.ge(Objects.nonNull(params.getRemindDate()), InvestRemindEntity::getBeginDate, getDayStart(params.getRemindDate()));
		queryWrapper.le(Objects.nonNull(params.getRemindDate()), InvestRemindEntity::getEndDate, getDayEnd(params.getRemindDate()));
		InvestPageResult<InvestRemindEntity> recordPage = remindService.queryPage(remindPageQuery, queryWrapper);
		if (CollectionUtils.isEmpty(recordPage.getRecords())) {
			return investPage;
		}
		Collection<InvestRemindEntity> recordList = recordPage.getRecords();
		Collection<InvestRemindVo> resultList = new ArrayList<>(Collections.emptyList());
		for (InvestRemindEntity investRemindEntity : recordList) {
			resultList.add(buildRemindItem(investRemindEntity));
		}

		//2、用户信息
		Map<Long, MallUserInfo> usersMap = getMap(userInfoService.getByIds(getIds(recordList, InvestRemindEntity::getOwner)), MallUserInfo::getId);

		//3、客户
		Collection<InvestCustomerEntity> customers = customerService.listByIds(getIds(resultList, InvestRemindVo::getCustomerId));
		Map<Long, InvestCustomerEntity> customerMap = getMap(customers, InvestCustomerEntity::getId);
		//4、 品牌
		Map<Long, WxBrand> brandMap = getMap(brandService.getByIds(getIds(customers, InvestCustomerEntity::getBrandId)), WxBrand::getId);

		for (InvestRemindVo remindVo : resultList) {
			InvestCustomerEntity customerEntity = customerMap.get(remindVo.getCustomerId());
			if (Objects.nonNull(customerEntity)) {
				remindVo.setCustomer(customerEntity);
				remindVo.setBrand(brandMap.get(customerEntity.getBrandId()));
			}
			remindVo.setOwnerInfo(usersMap.get(remindVo.getOwner()));
		}

		BeanUtils.copyProperties(recordPage, investPage);
		investPage.setRecords(resultList);

		return investPage;
	}

	private String getDayEnd(Date date) {
		return DateUtils.format(date) + " 23:59:59";
	}

	private String getDayStart(Date date) {
		return DateUtils.format(date) + " 00:00:00";
	}

	@Override
	public InvestPageResult<InvestMessageEntity> queryPageMessage(InvestMessageQuery params) {
		InvestHelper.notNull(params);
		InvestPageQuery<InvestMessageEntity> query = new InvestPageQuery<>();
		BeanUtils.copyProperties(params, query);
		InvestMessageEntity messageEntity = new InvestMessageEntity();
		messageEntity.setOwner(InvestUserContext.getUserId());
		query.setQueryData(messageEntity);
		return messageService.queryPage(query);
	}

	private void buildQueryWrapper(LambdaQueryWrapper<InvestOperateRecordEntity> wrapper, String tbl, Long tId) {
		if (ObjectUtils.allNotNull(tbl, tId)) {
			wrapper.eq(InvestOperateRecordEntity::getTbl, tbl);
			wrapper.eq(InvestOperateRecordEntity::getTid, tId);
		}
	}

	private List<MallUserInfo> getMallUserInfos(Map<Long, MallUserInfo> usersMap, InvestFollowRecordEntity item) {
		List<MallUserInfo> ownerInfo = null;
		Map contentMap = JSON.parseObject(item.getContent(), Map.class);
		if (MapUtils.isNotEmpty(contentMap)) {
			Object followMember = contentMap.get(InvestFollowRecordEntity.KEY_MEMBER);
			ownerInfo = getMallUserInfos(followMember, usersMap);
		}
		return ownerInfo;
	}

	@Override
	public List<MallUserInfo> queryUserList() {
		return queryUserList(EnumInvestUserType.USER);
	}

	public List<MallUserInfo> queryUserList(EnumInvestUserType userType) {
		LambdaQueryWrapper<MallUserInfo> queryWrapper = new LambdaQueryWrapper<>();
		if (Objects.nonNull(userType)) {
			queryWrapper.eq(MallUserInfo::getInvestRule, userType.getCode());
		}
		return userInfoService.selectList(queryWrapper);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean saveCustomerAndDemand(InvestDemandDto demandDto) {
		InvestHelper.notNull(demandDto, demandDto.getCustomer(), demandDto.getDemand());
		InvestCustomerEntity customerEntity = demandDto.getCustomer() ;
		customerService.save(customerEntity);
		InvestDemandEntity demandEntity = demandDto.getDemand();
		demandEntity.setCustomerId(customerEntity.getId());
		return demandService.save(demandEntity);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean updateCustomerAndDemand(InvestDemandDto demandDto) {
		InvestHelper.notNull(demandDto, demandDto.getCustomer(), demandDto.getDemand());
		Long customerId = demandDto.getCustomer().getId();
		if (Objects.isNull(customerId)) {
			customerId = demandDto.getDemand().getCustomerId();
			demandDto.getCustomer().setId(customerId);
		}
		customerService.updateById(demandDto.getCustomer());
		InvestDemandEntity demandEntity = demandDto.getDemand();
		if (Objects.isNull(demandEntity.getCustomerId())) {
			demandEntity.setCustomerId(customerId);
		}
		return demandService.updateById(demandEntity);
	}

	@Override
	public boolean saveTask(InvestTaskEntity investTaskEntity) {
		syncTargetStatus(investTaskEntity);
		return taskService.save(investTaskEntity);
	}

	@Override
	public boolean updateTask(InvestTaskEntity investTaskEntity) {
		syncTargetStatus(investTaskEntity);
		return taskService.updateById(investTaskEntity);
	}

	@Override
	public InvestDemandVo findDemandById(Long id) {
		InvestCustomerEntity customerEntity = customerService.getByIdNotNull(id);
		InvestDemandEntity demandEntity = demandService.getByCustomerId(customerEntity.getId());
		WxBrand brand = brandService.getById(customerEntity.getBrandId());
		WxShop shop = shopService.getById(demandEntity.getTargetId());
		Map<Long, MallUserInfo> usersMap = getMap(this.queryUserList(null), MallUserInfo::getId);
		return buildDemindItem(demandEntity, customerEntity, brand, shop, usersMap);
	}

	@Override
	public InvestTaskVo findTaskById(Long id) {
		InvestTaskEntity taskEntity = taskService.getByIdNotNull(id);
		WxShop shop = shopService.getById(taskEntity.getTargetId());
		Map<Long, MallUserInfo> usersMap = getMap(this.queryUserList(null), MallUserInfo::getId);
		return buildTaskItem(taskEntity, shop, usersMap);
	}

	@Override
	public InvestRemindVo findRemindById(Long id) {
		InvestRemindEntity remindEntity = remindService.getByIdNotNull(id);
		InvestRemindVo remindVo = buildRemindItem(remindEntity);

		InvestCustomerEntity customerEntity = customerService.getByIdNotNull(remindVo.getCustomerId());
		if (Objects.nonNull(customerEntity)) {
			remindVo.setCustomer(customerEntity);
			remindVo.setBrand(brandService.getById(customerEntity.getBrandId()));
		}
		remindVo.setOwnerInfo(userInfoService.getById(remindEntity.getOwner()));

		return remindVo;
	}

	@Override
	public Collection<InvestOperateRecordVo> findOperateById(InvestOperateRecordQuery params) {
		InvestHelper.notNull(params, params.getRecordType(), params.getTid());
		LambdaQueryWrapper<InvestOperateRecordEntity> recordQueryWrapper = new LambdaQueryWrapper<>();
		InvestDemandEntity demandEntity = null;
		if (Objects.equals(params.getRecordType(), EnumFollowType.DEMAND)) {
			InvestCustomerEntity customerEntity = customerService.getByIdNotNull(params.getTid());
			demandEntity = demandService.getOne(new LambdaQueryWrapper<InvestDemandEntity>().eq(InvestDemandEntity::getCustomerId, customerEntity.getId()));
			buildQueryWrapper(recordQueryWrapper, InvestOperateRecordEntity.TLB_CUSTOMER, customerEntity.getId());
		} else if (Objects.equals(params.getRecordType(), EnumFollowType.TASK)) {
			buildQueryWrapper(recordQueryWrapper, InvestOperateRecordEntity.TLB_TASK, params.getTid());
		}

		Collection<InvestOperateRecordVo> resultList = new ArrayList<>();
		List<InvestOperateRecordEntity> recordPage = operateRecordService.list(recordQueryWrapper);
		if (CollectionUtils.isEmpty(recordPage)) {
			return resultList;
		}

		List<InvestOperateRecordEntity> demandRecord = new ArrayList<>();
		if (Objects.nonNull(demandEntity)) {
			LambdaQueryWrapper<InvestOperateRecordEntity> demandQueryWrapper = new LambdaQueryWrapper<>();
			buildQueryWrapper(demandQueryWrapper, InvestOperateRecordEntity.TLB_DEMAND, demandEntity.getId());
			demandRecord.addAll(operateRecordService.list(demandQueryWrapper));
		}

		recordPage.addAll(demandRecord);
		List<InvestOperateRecordEntity> mixRecordPage = recordPage.parallelStream().sorted((o1, o2) -> {
			if (Objects.equals(o1.getCreateDate(), o2.getCreateDate())) {
				return 0;
			} else if (o1.getCreateDate().after(o2.getCreateDate())) {
				return 1;
			} else {
				return -1;
			}
		}).collect(Collectors.toList());

		Map<Long, MallUserInfo> usersMap = getMap(userInfoService.getByIds(getIds(mixRecordPage, InvestOperateRecordEntity::getOperator)), MallUserInfo::getId);
		for (InvestOperateRecordEntity recordEntity : mixRecordPage) {
			List<TableTriple> record = JSONArray.parseArray(recordEntity.getContent(), TableTriple.class);
			resultList.addAll(getRecordList(recordEntity, record, usersMap.get(recordEntity.getOperator())));
		}
		return resultList;
	}

	private List<InvestOperateRecordVo> getRecordList(InvestOperateRecordEntity recordEntity, Collection<TableTriple> contentList, MallUserInfo userInfo) {
		List<InvestOperateRecordVo> recordVo = new ArrayList<>();
		if (CollectionUtils.isEmpty(contentList)) {
			return recordVo;
		}

		for (TableTriple record : contentList) {
			InvestOperateRecordVo itemVo = new InvestOperateRecordVo();
			BeanUtils.copyProperties(recordEntity, itemVo);
			if (Objects.nonNull(userInfo)) {
				itemVo.setOperatorName(userInfo.getName());
			}
			itemVo.setRecord(record);
			recordVo.add(itemVo);
		}
		return recordVo;
	}

	@Override
	public InvestFollowRecordVo findFollowRecordById(Long id) {
		InvestFollowRecordEntity followRecordEntity = followRecordService.getByIdNotNull(id);
		Map<Long, MallUserInfo> usersMap = getMap(this.queryUserList(null), MallUserInfo::getId);
		InvestCustomerEntity customerEntity = customerService.getByIdNotNull(followRecordEntity.getCustomerId());
		WxBrand brand = brandService.getById(customerEntity.getBrandId());
		return buildFollowRecordItem(usersMap, followRecordEntity, customerEntity, brand);
	}

	private void syncTargetStatus(InvestTaskEntity investTaskEntity) {
		WxRentContract contractQuery = new WxRentContract();
		contractQuery.setTenantId(InvestUserContext.getUser().getTenantId());
		contractQuery.setShopId(investTaskEntity.getTargetId());
		contractQuery.setStatus(EnumRentContractStatus.INTENTION.getCode());
		int count = rentContractService.selectContractCountByShopId(contractQuery);
		if (count > 0) {
			investTaskEntity.setStatus(EnumTaskStatus.INTENTION);
		} else {
			if (StringUtils.isNotEmpty(investTaskEntity.getOwner())) {
				investTaskEntity.setStatus(EnumTaskStatus.NEGOTIATING);
			}
		}
	}

	private InvestFollowRecordVo buildFollowRecordItem(Map<Long, MallUserInfo> usersMap, InvestFollowRecordEntity item,
	                                                   InvestCustomerEntity customerEntity, WxBrand brand) {
		List<MallUserInfo> ownerInfo = getMallUserInfos(usersMap, item);
		InvestFollowRecordVo followRecordVo = new InvestFollowRecordVo();
		followRecordVo.setCustomer(customerEntity);
		followRecordVo.setMemberInfo(ownerInfo);
		followRecordVo.setBrand(brand);
		followRecordVo.setOwnerInfo(usersMap.get(item.getOwner()));
		BeanUtils.copyProperties(item, followRecordVo);
		return followRecordVo;
	}

	private InvestDemandVo buildDemindItem(InvestDemandEntity item, InvestCustomerEntity customer, WxBrand brand,
	                                       WxShop shop, Map<Long, MallUserInfo> usersMap) {
		InvestDemandVo resultItemVo = new InvestDemandVo();
		BeanUtils.copyProperties(customer, resultItemVo);
		resultItemVo.setBrand(brand);
		resultItemVo.setDemand(item);
		resultItemVo.setTargetInfo(shop);
		if (Objects.nonNull(item)) {
			if (Objects.nonNull(usersMap.get(item.getOwner()))) {
				resultItemVo.setOwnerInfo(usersMap.get(item.getOwner()));
			}
		}
		return resultItemVo;
	}

	private InvestTaskVo buildTaskItem(InvestTaskEntity item, WxShop shop, Map<Long, MallUserInfo> usersMap) {
		List<MallUserInfo> ownerInfo = getMallUserInfos(item.getOwner(), usersMap);
		InvestTaskVo resultItemVo = new InvestTaskVo();
		resultItemVo.setTargetInfo(shop);
		resultItemVo.setOwnerInfo(ownerInfo);
		BeanUtils.copyProperties(item, resultItemVo);
		return resultItemVo;
	}


	private InvestRemindVo buildRemindItem(InvestRemindEntity remindEntity) {
		InvestRemindVo remindVo = new InvestRemindVo();
		BeanUtils.copyProperties(remindEntity, remindVo);
		Map contentMap = JSON.parseObject(remindEntity.getContent(), Map.class);
		if (MapUtils.isNotEmpty(contentMap)) {
			Object customerId = contentMap.get(InvestRemindEntity.KEY_CUSTOMER);
			remindVo.setCustomerId(Objects.isNull(customerId) ? null : Long.parseLong((String) customerId));
			Object negotiationType = contentMap.get(InvestRemindEntity.KEY_NEGOTIATIONTYPE);
			remindVo.setNegotiationType(EnumNegotiationType.getEnum(Integer.valueOf((String) negotiationType)));
		}
		return remindVo;
	}

	private List<MallUserInfo> getMallUserInfos(Object userJson, Map<Long, MallUserInfo> usersMap) {
		List<MallUserInfo> ownerInfo = Lists.newArrayList();
		JSONArray ownerList;
		if (userJson instanceof String) {
			ownerList = JSONArray.parseArray((String) userJson);
		} else {
			ownerList = (JSONArray) userJson;
		}
		if (CollectionUtils.isNotEmpty(ownerList)) {
			for (Object userId : ownerList) {
				if (userId instanceof Long) {
					ownerInfo.add(usersMap.get(userId));
				} else {
					ownerInfo.add(usersMap.get(Long.parseLong((String) userId)));
				}
			}
		}
		return ownerInfo;
	}

	private List<InvestDemandVo> getTargeInfoList(List<InvestDemandEntity> demandList, Collection<InvestCustomerEntity> customers) {
		Map<Long, InvestDemandEntity> demindsMap = getMap(demandList, InvestDemandEntity::getCustomerId);

		//3、目标信息
		Collection<WxShop> shops = shopService.getByIds(getIds(demandList, InvestDemandEntity::getTargetId));
		Map<Long, WxShop> shopsMap = getMap(shops, WxShop::getId);

		//4、品牌
		Map<Long, WxBrand> brandMap = getMap(brandService.getByIds(getIds(customers, InvestCustomerEntity::getBrandId)), WxBrand::getId);
		//5、用户
		Map<Long, MallUserInfo> usersMap = getMap(userInfoService.getByIds(getIds(demandList,InvestDemandEntity::getOwner)), MallUserInfo::getId);

		List<InvestDemandVo> resultList = new ArrayList<>();
		for (InvestCustomerEntity costomerItem : customers) {
			InvestDemandEntity demandItem = demindsMap.get(costomerItem.getId());
			WxShop shop = null;
			if (Objects.nonNull(demandItem)) {
				shop = shopsMap.get(demandItem.getTargetId());
			}
			WxBrand brand = brandMap.get(costomerItem.getBrandId());
			resultList.add(buildDemindItem(demandItem, costomerItem, brand, shop, usersMap));
		}
		return resultList;
	}

	private <T> InvestPageQuery<T> buildPageQuery(InvestPageQuery params, T t) {
		InvestPageQuery<T> pageQuery = new InvestPageQuery<>();
		BeanUtils.copyProperties(params, pageQuery);
		if (Objects.nonNull(t)) {
			pageQuery.setQueryData(t);
		}
		return pageQuery;
	}

	public <R, T> R convert(T params, Function<T, R> function) {
		InvestHelper.notNull(params);
		return function.apply(params);
	}

	private <T, R> Map<R, T> getMap(Collection<T> dataList, Function<T, R> keyMapper) {
		if(CollectionUtils.isEmpty(dataList)) {
			return new HashMap<>() ;
		}
		return InvestHelper.getMap(dataList, keyMapper);
	}

	private <T, R> Collection<R> getIds(Collection<T> dataList, Function<? super T, R> mapper) {
		return InvestHelper.getIds(dataList, mapper);
	}
}
