package com.diagbot.facade;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diagbot.client.UserServiceClient;
import com.diagbot.dto.AuthDetailDTO;
import com.diagbot.dto.OrderDetialsDTO;
import com.diagbot.dto.ProductAuthProgressDTO;
import com.diagbot.dto.ProductLineDTO;
import com.diagbot.dto.ProductOrderDTO;
import com.diagbot.dto.ProductOrderExportDTO;
import com.diagbot.dto.RespDTO;
import com.diagbot.dto.UserOrgDTO;
import com.diagbot.dto.WaitExamOrderCouDTO;
import com.diagbot.entity.OrderDetailStatus;
import com.diagbot.entity.OrderDetails;
import com.diagbot.entity.ProductOrder;
import com.diagbot.entity.ProductOrderIndex;
import com.diagbot.entity.User;
import com.diagbot.entity.wrapper.ProductOrderWrapper;
import com.diagbot.enums.AuditStatusEnum;
import com.diagbot.enums.AuthStatusEnum;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.enums.NotPassEnum;
import com.diagbot.enums.StatusEnum;
import com.diagbot.enums.VisibleIdTypeEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.idc.VisibleIdCreater;
import com.diagbot.service.impl.ProductOrderServiceImpl;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.DateUtil;
import com.diagbot.util.EntityUtil;
import com.diagbot.util.ExportBeanExcelUtil;
import com.diagbot.util.GsonUtil;
import com.diagbot.util.UserUtils;
import com.diagbot.vo.AddOrderVO;
import com.diagbot.vo.OrderDetialsVO;
import com.diagbot.vo.ProductOrderExportVO;
import com.diagbot.vo.ProductOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单业务
 *
 * @author Administrator
 */
@Component
public class ProductOrderFacade extends ProductOrderServiceImpl {
    @Autowired
    private VisibleIdCreater visibleIdCreater;
    @Autowired
    private OrderDetailsFacade orderDetailsFacade;
    @Autowired
    private ServiceInfoFacade serviceInfoFacade;
    @Autowired
    private LantoneProductFacade lantoneProductFacade;
    @Autowired
    private ProductServiceFacade productServiceFacade;
    @Autowired
    private UserServiceClient userServiceClient;
    @Autowired
    private ProductOrderFacade productOrderFacade;
    @Autowired
    private OpenedProductsFacade openedProductsFacade;
    @Autowired
    private ServiceTokenFacade serviceTokenFacade;


    /**
     * 获取产品的认证进度
     *
     * @return 包含产品当前的认证状态
     */
    public ProductAuthProgressDTO productAuthProgress() {
//        List<ProductAuthProgressDTO> retList = new ArrayList<ProductAuthProgressDTO>();
//        Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
//        List<ProductOrder> orderList = baseMapper.getUserProductOrder(userId);
//        List<String> nums = new ArrayList<>();
//        for (ProductOrder i : orderList) {
//            nums.add(i.getNum());
//        }
//        
//        if(nums.size()==0){
//        	return retList;
//        }
        
//        List<AuthDetailDTO> detailList = baseMapper.getOrderDetailsByNums(nums);
//        List<AuthDetailDTO> products = null;
//        Map<String, List<AuthDetailDTO>> detailMap = detailList.stream().collect(Collectors.groupingBy(AuthDetailDTO::getNum));
//        for (String num : detailMap.keySet()) {
//            ProductAuthProgressDTO productAuthProgressDTO = new ProductAuthProgressDTO();
//            productAuthProgressDTO.setNum(num);
//            products = detailMap.get(num);
//            for(AuthDetailDTO i : products){
//            	i.setAuditStatusMsg(AuditStatusEnum.getName(i.getAuditStatus()));
//            	if(i.getRejectType()!=null&&i.getRejectType()!=-1){
//            		i.setRejectReason(NotPassEnum.getName(i.getRejectType()));
//            	}
//            }
//            productAuthProgressDTO.setProducts(products);
//            retList.add(productAuthProgressDTO);
//        }
        Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
        List<AuthDetailDTO> detailList = baseMapper.getOrderDetailsByUserId(userId);
        List<AuthDetailDTO> passProduct = new ArrayList<>();
        List<AuthDetailDTO> failProduct = new ArrayList<>();
        for(AuthDetailDTO i : detailList){
        	i.setAuditStatusMsg(AuditStatusEnum.getName(i.getAuditStatus()));
        	if(i.getRejectType()!=null&&i.getRejectType()!=-1){
        		i.setRejectReason(NotPassEnum.getName(i.getRejectType()));
        	}
        	if(i.getAuditStatus()==0){
        		failProduct.add(i);
        	}else{
        		passProduct.add(i);
        	}
        }

        ProductAuthProgressDTO productAuthProgressDTO = new ProductAuthProgressDTO();
        productAuthProgressDTO.setPassProduct(passProduct);
        productAuthProgressDTO.setFailProduct(failProduct);
        return productAuthProgressDTO;
    }
    
    /**
     * 根据用户id查询订单信息数量
     * @param userId
     * @return
     */
    public int getUserProductOrderCount(Long userId){
    	return baseMapper.getUserProductOrderCount(userId);
    }
    
    /**
     * 根据用户id查询审核不通过订单信息数量
     * @param userId
     * @return
     */
    public int getOrderAuthFailCount(Long userId){
    	return baseMapper.getOrderAuthFailCount(userId);
    }


    /**
     * 根据用户选择的产品生成订单
     *
     * @param addOrderVO 需要提供参数（产品id）
     * @return Boolean true
     */
    @Transactional
    public Boolean addOrders(AddOrderVO addOrderVO) {
        Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
        List<Long> opendId = openedProductsFacade.getOpendCountByUserId(userId);
        List<Long> orderDetailsId = orderDetailsFacade.getOrderDetailsByUser(userId);
        List<ProductLineDTO> productList = lantoneProductFacade.productLinesB();
        List<Long> userIdList =new ArrayList<>();
        userIdList.add(userId);
        RespDTO<Map<Long, UserOrgDTO>> mapRespDTO = userServiceClient.getUserAndOrg(userIdList);
        if (mapRespDTO == null || !"0".equals(mapRespDTO.code)) {
            throw new CommonException(CommonErrorCode.RPC_ERROR,
                    "获取用户机构信息失败");
        }
        Map<Long, UserOrgDTO> dataMap =mapRespDTO.data;
        UserOrgDTO uo =dataMap.get(userId);
        if(uo.getAuStatus().intValue() != AuthStatusEnum.Authorized.getKey()){
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR,
                    "账号信息系不完善,请先认证");
        }
        for (int i =0; i<addOrderVO.getProductId().size();i++){
            for(int l = 0; l< productList.size(); l++){
                if(addOrderVO.getProductId().get(i).intValue() == productList.get(l).getId().intValue() && productList.get(l).getIsDeleted().equals(IsDeleteEnum.Y.getKey())){
                        throw new CommonException(CommonErrorCode.NOT_EXISTS,
                                "【"+productList.get(l).getName()+"】已删除,请刷新重试");
                }
                if(addOrderVO.getProductId().get(i).intValue() == productList.get(l).getId().intValue() && productList.get(l).getServiceStatus().intValue() == StatusEnum.Disable.getKey()){
                    throw new CommonException(CommonErrorCode.NOT_EXISTS,
                            "【"+productList.get(l).getName()+"】已停用,请刷新重试");
                }
            }
            for (int j =0; j<opendId.size();j++){
                if(addOrderVO.getProductId().get(i).longValue() == opendId.get(j).longValue()){
                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "请勿重复提交已开通产品");
                }
            }
            for (int k =0; k<orderDetailsId.size();k++){
                if(addOrderVO.getProductId().get(i).longValue() == orderDetailsId.get(k).longValue()){
                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "产品正在审核中请勿重复提交");
                }
            }
        }
        ProductOrder productOrder = new ProductOrder();
        productOrder.setCreator(UserUtils.getCurrentPrincipleID());
        productOrder.setGmtCreate(DateUtil.now());
        String orderNum = visibleIdCreater.getNextId(VisibleIdTypeEnum.IS_ORDER.getKey()).toString();
        productOrder.setNum(orderNum);
        productOrder.setUserId(userId);
        productOrder.setTime(DateUtil.now());
        if (!save(productOrder)) {
            throw new CommonException(CommonErrorCode.INSERT_DATA_FAILED, "添加订单失败");
        }
        OrderDetails orderDetails = null;
        List<OrderDetails> list =new ArrayList();
        List<Long> lantoneProductId =new ArrayList<>();
        for (Long o : addOrderVO.getProductId()) {
            lantoneProductId.add(o);
            orderDetails = new OrderDetails();
            orderDetails.setUserId(userId);
            orderDetails.setOrderNum(orderNum);
            orderDetails.setGmtCreate(DateUtil.now());
            orderDetails.setCreator(UserUtils.getCurrentPrincipleID());
            orderDetails.setProductId(o);
            list.add(orderDetails);
        }
        if (0 == lantoneProductFacade.listByIds(lantoneProductId).size()) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "获取产品信息失败");
        }
        if(orderDetailsFacade.saveOrderDetails(list)){
            throw new CommonException(CommonErrorCode.INSERT_DATA_FAILED, "添加订单失败");
        }
        return true;
    }


    /**
     * 根据订单号查询订单信息
     *
     * @param productOrder 参数
     * @return 订单信息
     */
    public ProductOrder selectByOrderNum(ProductOrder productOrder) {
        return selctOrderTimeByOrderNum(productOrder);
    }


    /**
     * 计算待审核的订单数量
     *
     * @return 待审核的订单数量
     */
    public WaitExamOrderCouDTO waitExamOrderCou() {
        WaitExamOrderCouDTO waitExamOrderCouDTO = new WaitExamOrderCouDTO();
        RespDTO<List<User>> userInfiList = userServiceClient.getUserAllInfo();
        if(userInfiList == null || !"0".equals(userInfiList.code) ) {
            throw new CommonException(CommonErrorCode.RPC_ERROR,
                    "获取用户和机构信息失败");
        }
        List<Long> userIds =new ArrayList<>();
        for (User user:userInfiList.data) {
            userIds.add(user.getId());
        }
        waitExamOrderCouDTO.setCount(baseMapper.waitExamOrderCou(userIds));
        return waitExamOrderCouDTO;
    }
    
	/**
	 * 产品申请查询所有订单信息
     *
	 * @param productOrderVO （订单编号，机构名称，申请状态）
	 * @return 所有订单信息
	 */
	public RespDTO<IPage<ProductOrderDTO>> selectAllProductOrder(ProductOrderVO productOrderVO){
	    Page page =new Page();
	    BeanUtil.copyProperties(productOrderVO,page);
		ProductOrderIndex productOrderIndex =new ProductOrderIndex();
		BeanUtil.copyProperties(productOrderVO, productOrderIndex);
		//TODO
        if(productOrderVO.getOrgName() != null && productOrderVO.getOrgName()!=""){
            RespDTO<List<Long>> rlist = userServiceClient.getUserByOrgName(productOrderVO.getOrgName());
            if(rlist == null || !"0".equals(rlist.code) ) {
                throw new CommonException(CommonErrorCode.RPC_ERROR,
                        "获取用户和机构信息失败");
            }
            if(rlist.data.size() == 0){
                rlist.data.add(-1L);
            }
            productOrderIndex.setUserId(rlist.data);
        }else{
            RespDTO<List<User>> userInfiList = userServiceClient.getUserAllInfo();
            if(userInfiList == null || !"0".equals(userInfiList.code) ) {
                throw new CommonException(CommonErrorCode.RPC_ERROR,
                        "获取用户和机构信息失败");
            }
            List<Long> userIds =new ArrayList<>();
            for (User user:userInfiList.data) {
                userIds.add(user.getId());
            }
            productOrderIndex.setUserId(userIds);
        }
		List<ProductOrderDTO> list =productOrderFacade.selectAllProductOrder(page,productOrderIndex).getRecords();
		List<Long> list1 =new ArrayList<>();
		List<String> orderNoList =new ArrayList<>();
		for (ProductOrderDTO productOrderWrapper:list) {
			Long longs = productOrderWrapper.getUserId();
			String orderNo =productOrderWrapper.getNum();
			list1.add(longs);
			orderNoList.add(orderNo);
		}
        OrderDetialsVO orderDetialsVO =new OrderDetialsVO();
		orderDetialsVO.setOrderNum(orderNoList);
		List<OrderDetialsDTO> orderDetilList = orderDetailsFacade.getAllOrderDetials(orderDetialsVO);
		RespDTO<Map<Long, UserOrgDTO>> mapRespDTO = userServiceClient.getUserAndOrg(list1);
		if(mapRespDTO == null || !"0".equals(mapRespDTO.code) ) {
			throw new CommonException(CommonErrorCode.RPC_ERROR,
					"获取用户和机构信息失败");
		}
		Map<Long, UserOrgDTO> dataMap = mapRespDTO.data;
		Map<String,List<OrderDetialsDTO>> odMap = EntityUtil.makeEntityListMap(orderDetilList,"orderNum");
		for(ProductOrderDTO bean : list) {
			UserOrgDTO uo = dataMap.get(bean.getUserId());
			if(uo != null) {
				bean.setUsername(uo.getUsername());
				bean.setLinkman(uo.getLinkman());
				bean.setEmail(uo.getEmail());
				bean.setOrgId(uo.getOrgId());
				bean.setOrgName(uo.getOrgName());
			}
			if (null != odMap && null != odMap.get(bean.getNum())){
                bean.setOrderDetial(odMap.get(bean.getNum()));
            }
		}
		return RespDTO.onSuc(page);
	}


    /**
     * 修改订单审核状态
     *
     * @param orderNum 参数
     * @return Boolean true
     */
	public Boolean updateProductOrderStatus(String orderNum){
        OrderDetailStatus  orderDetailStatus = orderDetailsFacade.selectAllOrderDetialsByOrderNum(orderNum);
        ProductOrder productOrder=new ProductOrder();
        productOrder.setNum(orderNum);
        productOrder= this.selctOrderTimeByOrderNum(productOrder);
        int satus =0;
        if(orderDetailStatus.getCt().intValue() == orderDetailStatus.getNotAudit().intValue()){
            satus = AuditStatusEnum.NotAudit.getKey();
            // ct == sh 待审核
        }else if(orderDetailStatus.getCt().intValue() > orderDetailStatus.getNotAudit().intValue() && orderDetailStatus.getNotAudit().intValue() != 0){
            satus = AuditStatusEnum.Audit_Part.getKey();
            // ct > sh && sh != 0 部分审核
        }else if(orderDetailStatus.getCt().intValue() == orderDetailStatus.getPass().intValue()){
            satus = AuditStatusEnum.Adopt.getKey();
            // ct == pass 通过
        }else if(orderDetailStatus.getCt().intValue() == orderDetailStatus.getNotPass().intValue()){
            satus = AuditStatusEnum.Veto.getKey();
            // ct == not_pass 不通过
        }else {
            satus = AuditStatusEnum.Adopt_Part.getKey();
            // 其他 部分通过
        }
        productOrder.setAuditStatus(satus);
        productOrder.setGmtModified(DateUtil.now());
        productOrder.setModifier(UserUtils.getCurrentPrincipleID());
        if(!this.updateById(productOrder)){
            throw new CommonException(CommonErrorCode.UPDATE_INFO_FAIL,
                    "用户订单审核状态修改失败");
        }
        return true;
    }

    /**
     *  导出产品订单相关信息
     * @param productOrderExportVO
     * @param response
     */
    public void export(ProductOrderExportVO productOrderExportVO,HttpServletResponse response){
	    ProductOrderVO productOrderVO =new ProductOrderVO();
	    BeanUtil.copyProperties(productOrderExportVO,productOrderVO);
	    if(DateUtil.getDaysBetweenTwoDate(DateUtil.parseDate(productOrderVO.getStartTime()), DateUtil.parseDate(productOrderVO.getEndTime()))>30 || DateUtil.getDaysBetweenTwoDate(DateUtil.parseDate(productOrderVO.getStartTime()), DateUtil.parseDate(productOrderVO.getEndTime())) < 0){
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR,
                    "日期超出限制，请重新输入");
        }
	    productOrderVO.setCurrent(1L);
        productOrderVO.setSize(999999999999999999L);
        Map<String, Object> userMap = new HashMap<String, Object>();
        userMap.put("startTime", productOrderExportVO.getStartTime());
        userMap.put("endTime", productOrderExportVO.getEndTime());
        RespDTO<IPage<ProductOrderDTO>> datas = this.selectAllProductOrder(productOrderVO);
        GsonUtil.toJson(datas.data.getRecords());
        List<String> listName = new ArrayList<>();

        listName.add("编号");
        listName.add("申请时间");
        listName.add("订单号");
        listName.add("申请机构");
        listName.add("申请人");
        listName.add("手机号");
        listName.add("邮箱");
        listName.add("审核状态");

        List<String> listId = new ArrayList<>();
        listId.add("id");//订单ID
        listId.add("time");//申请时间
        listId.add("num");// 订单号
        listId.add("orgName");//申请机构
        listId.add("linkman");// 申请人
        listId.add("userName");//手机号
        listId.add("email");//邮箱
        listId.add("auditStatus");//审核状态


        List<ProductOrderExportDTO> list = new ArrayList<>();
        for (int i = 0; i < datas.data.getRecords().size(); i++) {
            ProductOrderWrapper userInfo = datas.data.getRecords().get(i);
            list.add(new ProductOrderExportDTO(String.valueOf(i+1),
                    DateUtil.formatDateTime(userInfo.getTime()),
                    userInfo.getNum(),
                    userInfo.getOrgName(),
                    userInfo.getLinkman(),
                    userInfo.getUsername(),
                    userInfo.getEmail(),
                    String.valueOf(userInfo.getAuditStatus())));
        }
        response.setContentType("text/html;charset=UTF-8");
        /*String filePath = productOrderExportVO.getFilePath();//文件路径
        String fileName = productOrderExportVO.getFileName();//文件名
        ExportBeanExcelUtil ex = new ExportBeanExcelUtil();
        RespDTO resul = ex.exportExcel("测试POI导出EXCEL文档", listName, listId, list, filePath, fileName);*/
        ExportBeanExcelUtil ex = new ExportBeanExcelUtil();
        ex.exportExcelNew("产品申请相关信息", listName, listId, list,response);
    }
}


