/**
 * 
 */
package com.pcloud.book.consumer.resource;

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.channelcenter.base.exceptions.ChannelBizException;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.BeanUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.ThreadUtil;
import com.pcloud.resourcecenter.product.dto.ProDto;
import com.pcloud.resourcecenter.product.dto.Product4BookDTO;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.resourcecenter.product.dto.ProductLabelDto;
import com.pcloud.resourcecenter.product.dto.ProductTypeDto;
import com.pcloud.resourcecenter.product.dto.UpdateAppProductParamDTO;
import com.pcloud.resourcecenter.product.entity.Article;
import com.pcloud.resourcecenter.product.entity.Product;
import com.pcloud.resourcecenter.product.service.ProductService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @描述：商品中间件
 * @作者：songx
 * @创建时间：2016年11月17日,下午4:53:51 @版本：1.0
 */
@Component("productConsr")
public class ProductConsr {

	/**
	 * logger
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(ProductConsr.class);

	@Autowired
	private ProductService productService;

	/**
	 * 微信端，资源中心拉取商品信息
	 */
	public Map<Long, ProductDto> listProDetail4Wechat(List<Long> productIds, Long channelId) throws BizException {
		LOGGER.info("【资源中心(消)】微信端，获取商品信息,<START>.[productIds]=" + productIds.toString() + ",[channelId]=" + channelId);
		if (ListUtils.isEmpty(productIds) || channelId == null) {
			return null;
		}
		try {
			return ResponseHandleUtil.parseMapResponse(productService.listProDetail4Wechat(productIds, channelId),
					Long.class, ProductDto.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】微信端，获取商品信息失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】微信端，获取商品信息.[listProDetail4Wechat]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
	}

	/**
	 * 获取商品ID集合获取商品的标签
	 */
	public Map<Long, ProductLabelDto> getLabelByProIds(List<Long> productIds) throws BizException {
		LOGGER.info("【资源中心(消)】获取商品ID集合获取商品的标签,<START>.[productIds]=" + productIds);
		if (ListUtils.isEmpty(productIds)) {
			return null;
		}
		try {
			return ResponseHandleUtil.parseMapResponse(productService.getLabelByProIds(productIds),
					Long.class, ProductLabelDto.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取商品ID集合获取商品的标签失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】获取商品ID集合获取商品的标签.[listProDetail4Wechat]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
	}

	/**
	 * 资源中心拉取商品基本信息
	 */
	public Map<Long, ProductDto> getProBasesByIds(List<Long> productIds) throws BizException {
		LOGGER.info("【资源中心(消)】获取商品基本信息,<START>.[productIds]=" + productIds + "]");
		if (productIds == null || productIds.isEmpty()) {
			return null;
		}
		Map<Long, ProductDto> productDtoMap = new HashMap<>();
		productIds = productIds.stream().distinct().collect(Collectors.toList());
		Integer size = productIds.size();
		if (productIds.size() > 1000) {
			Integer[] queryCountArray = {0, 1, 2, 3};
			Integer queryCount = 4;
			//并发查询
			List<Long> finalProductIds = productIds;
			Map<Long, ProductDto> finalProductDtoMap = productDtoMap;
			CompletableFuture[] completableFutures = Arrays.stream(queryCountArray).
					map(x -> CompletableFuture.supplyAsync(() -> {
						Integer startIndex = size / queryCount * x;
						Integer endIndex = size / queryCount * (x + 1);
						List<Long> queryList = finalProductIds.subList(startIndex, endIndex);
						Map<Long, ProductDto> productMap = ResponseHandleUtil.parseMapResponse(productService.getProBasesByIds(queryList), Long.class,
								ProductDto.class);
						return productMap;
					}, ThreadPoolUtils.EXPORT_THREAD_POOL).whenComplete(((productMap, throwable) -> {
						finalProductDtoMap.putAll(productMap);
					}))).toArray(CompletableFuture[]::new);

			try {
				CompletableFuture.allOf(completableFutures).get();
			} catch (InterruptedException | ExecutionException e) {
				LOGGER.warn("[getProBasesByIds] 填充信息失败，err：{}", e.getMessage(), e);
			}
			return finalProductDtoMap;
		} else {
			try {
				productDtoMap = ResponseHandleUtil.parseMapResponse(productService.getProBasesByIds(productIds), Long.class, ProductDto.class);
			} catch (BizException e) {
				LOGGER.warn("调用：productService.getProBasesByIds报错", e.getMessage(), e);
			}
			return productDtoMap;
		}
	}


	/**
	 * 资源中心拉取商品基本信息
	 */
	public Map<Long, Product4BookDTO> getProBasesWithSceneByIds(List<Long> productIds) throws BizException {
		LOGGER.info("【资源中心(消)】获取商品基本信息,<START>.[productIds]=" + productIds + "]");
		if (productIds == null || productIds.isEmpty()) {
			return null;
		}
		try {
			return ResponseHandleUtil.parseMapResponse(productService.getProInfoListWithScene(productIds), Long.class,
					Product4BookDTO.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取商品基本信息失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】获取商品基本信息.[getProInfoListWithScene]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
	}

	/**
	 * 获取问答商品信息
	 */
	public Map<Long, ProductDto> getQaProRetailBase4Group(List<Long> productIds, Long channelId, Long agentId)
			throws BizException {
		LOGGER.info("【资源中心(消)】获取问答商品信息,参数列表[productIds]:" + productIds);

		Map<Long, ProductDto> productDtoMap = new HashMap<>();
		if (productIds == null || productIds.isEmpty()) {
			LOGGER.info("【资源中心(消)】获取问答商品信息,参数为空");
			return productDtoMap;
		}
		try {
			productDtoMap = ResponseHandleUtil.parseMapResponse(
					productService.getQaProRetailBase4Group(productIds, channelId, agentId), Long.class,
					ProductDto.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取问答商品信息失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("获取问答商品信息失败:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "获取问答商品信息失败!");
		}
		return productDtoMap;
	}

	public Product postUpdateBookGroupProduct(UpdateAppProductParamDTO updateAppProductParamDTO) {
		try {
			Product product = ResponseHandleUtil.parseResponse(productService.postUpdateBookGroupProduct(updateAppProductParamDTO), Product.class);
			return product;
		} catch (BizException e) {
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "设置商品失败！");
		}
	}

	/**
	 * 资源中心拉取商品基本信息
	 */
	public ProductDto getProBaseById(Long productId) throws BizException {
		LOGGER.info("【资源中心(消)】获取商品基本信息,<START>.[productId]=" + productId + "]");
		if (productId == null) {
			return null;
		}
		try {
			return ResponseHandleUtil.parseResponse(productService.getProBaseById(productId), ProductDto.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取商品基本信息失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】获取商品基本信息.[getProBasesByIds]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		} finally {
		}
	}

	/**
	 * 自动上架
	 */
	public Map<Long, String> productAutoOnShelves(Long channelId, List<Long> productIds) throws BizException {
		LOGGER.info("【资源中心(消)】自动上架,<START>.[channelId]=" + channelId + " [productIds]=" + productIds + "]");
		Map<Long, String> resultMap = new HashMap<>();
		if (channelId == null || ListUtils.isEmpty(productIds)) {
			LOGGER.info("【资源中心(消)】自动上架,参数为空");
			return resultMap;
		}
		try {
			resultMap = ResponseHandleUtil.parseMapResponse(productService.productAutoOnShelves(channelId, productIds), Long.class, String.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】自动上架:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】自动上架.[productAutoOnShelves]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
		return resultMap;
	}

	/**
	 * 判断是否是超级作者
	 */
	public Map<Long, Boolean> getIsSuperByProductIdList(List<Long> productIds) throws BizException {
		LOGGER.info("【资源中心(消)】判断是否是超级作者,<START>. [productIds]=" + productIds + "]");
		Map<Long, Boolean> resultMap = new HashMap<>();
		if (ListUtils.isEmpty(productIds)) {
			LOGGER.info("【资源中心(消)】判断是否是超级作者,参数为空");
			return resultMap;
		}
		try {
			resultMap = ResponseHandleUtil.parseMapResponse(productService.getIsSuperByProductIdList(productIds), Long.class, Boolean.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】判断是否是超级作者:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】判断是否是超级作者.[getIsSuperByProductIdList]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
		return resultMap;
	}

	/**
	 * 获取商品基本信息（含编号）
	 * @param productId
	 * @return
	 * @throws BizException
	 */
	public ProDto getProBasesInfoById(Long productId)throws BizException{
		LOGGER.info("【资源中心(消)】获取商品基本信息,<START>.[productIds]=" + productId + "]");
		if (productId == null) {
			return null;
		}
		try {
			List<Long> productIds = new ArrayList<>();
			productIds.add(productId);
			Map<Long, ProDto> resultMap = ResponseHandleUtil.parseMapResponse(productService.getProBasesInfoByIds(productIds), Long.class,
					ProDto.class);
			if (null == resultMap){
				return null;
			}
			return resultMap.get(productId);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取商品基本信息失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】获取商品基本信息.[getProBasesInfoById]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
	}

	public Long getOneChannelIdByProId(Long productId) throws BizException {
		LOGGER.info("【资源中心(消)】获取作品已上架的某个运营平台,<START>.[productId]=" + productId + "]");
		if (productId == null) {
			return null;
		}
		try {
			return ResponseHandleUtil.parseResponse(productService.getOneChannelIdByProId(productId), Long.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取作品已上架的某个运营平台失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】获取作品已上架的某个运营平台.[getOneChannelIdByProId]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
	}

	public List<Long> getChannelIdsByProId(Long productId) throws BizException {
		LOGGER.info("【资源中心(消)】获取作品已上架的所有运营平台,<START>.[productId]=" + productId + "]");
		if (productId == null) {
			return null;
		}
		try {
			return ResponseHandleUtil.parseList(productService.getChannelIdsByProId(productId), Long.class);
		} catch (BizException e) {
			LOGGER.warn("【资源中心(消)】获取作品已上架的所有运营平台失败:" + e.getMessage(), e);
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】获取作品已上架的所有运营平台.[getChannelIdsByProId]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.INVOKE_RES_ERROR, "服务内部错误，请稍后重试");
		}
	}

	/**
	 * 获取商品信息
	 *
	 * @return
	 * @throws BizException
	 */
	public Map<Long, ProductDto> getProPriceInfo(List<Long> productIds, Long channelId) throws BizException {
		Map<Long, ProductDto> productMap = null;
		if (ListUtils.isEmpty(productIds)) {
			return null;
		}
		try {
			productMap = ResponseHandleUtil.parseMapResponse(productService.getProPriceInfo(productIds, channelId),
				Long.class, ProductDto.class);
		} catch (BizException e) {
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("获取商品信息失败[productService.getProRetailBase]:" + e.getMessage(), e);
			throw new ChannelBizException(ChannelBizException.INVOKE_RES_ERROR, "获取商品信息失败~!");
		}
		return productMap;
	}

    public Map<Long, ProductDto> getProductInfoByIds(List<Long> proIds) {
		LOGGER.info("获取商品id集合对应商品信息,参数列表[proIds]:" + proIds);
		Map<Long, ProductDto> productDtoMap = new HashMap<>();
		if (ListUtils.isEmpty(proIds)) {
			return productDtoMap;
		}

		try {
			productDtoMap = ResponseHandleUtil.parseMapResponse(productService.getProBasesByIds(proIds), Long.class,
					ProductDto.class);
		} catch (BizException e) {
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("获取商品id集合对应商品信息失败[productService.getProBasesByIds]:" + e.getMessage(), e);
			throw new ChannelBizException(ChannelBizException.INVOKE_RES_ERROR, "获取商品信息失败~!");
		}
		LOGGER.info("获取商品id集合对应商品信息【end】 [productService.getProBasesByIds]");
		return productDtoMap == null ? new HashMap<>() : productDtoMap;
    }

	public Map<String, ProductTypeDto> getProType() {
		Map<String, ProductTypeDto> productDtoMap = new HashMap<>();
		try {
			List<ProductTypeDto> productTypeDtos = ResponseHandleUtil.parseListResponse(productService.getProType(), ProductTypeDto.class);
			if(CollectionUtils.isEmpty(productTypeDtos)){
				return productDtoMap;
			}
			productDtoMap = productTypeDtos.stream().collect(Collectors.toMap(x->x.getTypeCode(),x->x,(v1,v2)->v2));
		} catch (BizException e) {
			throw new BizException(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("获取商品id集合对应商品信息失败[productService.getProBasesByIds]:" + e.getMessage(), e);
			throw new ChannelBizException(ChannelBizException.INVOKE_RES_ERROR, "获取商品信息失败~!");
		}
		return productDtoMap == null ? new HashMap<>() : productDtoMap;
	}

    public Long addProductStepOne(Product product) {
		Long productId = null;
		try {
			productId = ResponseHandleUtil.parseResponse(productService.addProductStepOne(product), Long.class);
		} catch (Exception e) {
			LOGGER.error("创建作品第一步[productService.addProductStepOne]:创建失败：product:{}" + e.getMessage(), product);
		}
		return productId;
	}

	public void addArticle(Article article) {
		try {
			productService.addArticle(article);
		} catch (Exception e) {
			LOGGER.error("创建精品文章第二步[productService.addArticle]:创建失败：article:{}" + e.getMessage(), article);
		}
	}

	public void selfAudit(Product product) {
		try {
			productService.selfAudit(product);
		} catch (Exception e) {
			LOGGER.error("自主审核失败[productService.selfAudit]:创建失败：article:{}" + e.getMessage(), product);
		}
	}
	public void setOffShelvesProductOnShelves(Long channelId, List<Long> productIds) throws BizException {
		LOGGER.info("【资源中心(消)】设置下架作品上架,<START>.[channelId]=" + channelId + " [productIds]=" + productIds + "]");
		if (channelId == null || ListUtils.isEmpty(productIds)) {
			return;
		}
		try {
			productService.setOffShelvesProductOnShelves(channelId, productIds);
		} catch (Exception e) {
			LOGGER.error("【资源中心(消)】调用失败[setOffShelvesProductOnShelves]:" + e.getMessage(), e);
		}
	}
}
