package com.diagbot.facade;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.diagbot.client.UserServiceClient;
import com.diagbot.dto.EnShowOptionDTO;
import com.diagbot.dto.GetConsoleOnTrialDTO;
import com.diagbot.dto.GetConsoleOpenedDTO;
import com.diagbot.dto.OpenProductCheckDTO;
import com.diagbot.dto.OpenUpOnTrialDTO;
import com.diagbot.dto.ProductServiceDTO;
import com.diagbot.dto.RespDTO;
import com.diagbot.entity.LantoneProduct;
import com.diagbot.entity.OpenedProducts;
import com.diagbot.entity.ProductService;
import com.diagbot.entity.ServiceInfo;
import com.diagbot.entity.ServiceToken;
import com.diagbot.entity.User;
import com.diagbot.entity.UserRenewals;
import com.diagbot.enums.AccessTypeEnum;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.enums.RenewalsEnum;
import com.diagbot.enums.ServiceTypeEnum;
import com.diagbot.enums.StatusEnum;
import com.diagbot.enums.TokenTypeEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.service.impl.OpenedProductsServiceImpl;
import com.diagbot.util.DateUtil;
import com.diagbot.util.StringUtil;
import com.diagbot.util.UserUtils;
import com.diagbot.vo.ModifyOpeningTimeVO;
import com.diagbot.vo.OpenProductCheckVO;
import com.diagbot.vo.OpenUpOnTrialVO;
import com.diagbot.vo.ProductServiceSaveVO;
import com.diagbot.vo.StartAndendByUserIdVO;

/**
 * @Description:已开通产品业务层
 * @author: zhaops
 * @time: 2018/9/19 16:55
 */
@Component
public class OpenedProductsFacade extends OpenedProductsServiceImpl {
    @Autowired
    private ServiceInfoFacade serviceInfoFacade;
    @Autowired
    private ProductServiceFacade productServiceFacade;
    @Autowired 
    private UserRenewalsFacade userRenewalsFacade;
    @Autowired
    private LantoneProductFacade lantoneProductFacade;
    @Autowired
    private OpenedProductsFacade openedProductsFacade;
    @Autowired
    private ProductOrderFacade productOrderFacade;
    @Autowired
    private UserServiceClient userServiceClient;
    @Autowired
    private ServiceTokenFacade serviceTokenFacade;

    public List<OpenedProducts> getByAppkeyAndSecretFac(Map map) {
        return this.getByAppkeyAndSecret(map);
    }

    /**
     * 得到所有已开通的产品
     *
     * @return 所有已经开通的产品
     */
    public List<GetConsoleOpenedDTO> getConsoleOpened() {
    	Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
        
        List<GetConsoleOpenedDTO> retList = baseMapper.getConsoleOpened(userId);
        for(GetConsoleOpenedDTO i : retList){
        	String accessTypeMsg = "";
        	for(String j:i.getAccessType().split(",")){
        		accessTypeMsg+=AccessTypeEnum.getName(Integer.parseInt(j))+" ";
        	}
        	i.setAccessTypeMsg(accessTypeMsg);
        	i.setServiceStatusMsg(StatusEnum.getName(i.getServiceStatus()));
        	
        	if(i.getAccessType().indexOf("1")!=-1){
        		i.setIsInto(1);
        	}else{
        		i.setIsInto(0);
        		i.setUrl("");
        	}
        	if(i.getAccessType().replace("1", "").replace(",", "").length()>0){
        		i.setIsCreateToken(1);
        	}else{
        		i.setIsCreateToken(0);
        	}
        	if(DateUtil.parseDateTime(i.getEndTime()).getTime()<DateUtil.now().getTime()){
        		i.setIsExpire(0);
        	}else{
        		i.setIsExpire(1);
        	}
        	i.setEndTime(i.getEndTime().substring(0, 10));
        }
        
        return retList;
    }

    /**
     * 得到所有可试用的产品
     *
     * @return 所有可试用的产品
     */
    public List<GetConsoleOnTrialDTO> getConsoleOnTrial() {
        Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
        List<GetConsoleOnTrialDTO> retList = baseMapper.getConsoleOnTrial(userId);
        
        Date now = new Date();
        Date expirTime = null;
        for(GetConsoleOnTrialDTO i : retList){
        	String accessTypeMsg = "";
        	for(String j:i.getAccessType().split(",")){
        		accessTypeMsg+=AccessTypeEnum.getName(Integer.parseInt(j))+" ";
        	}
        	i.setAccessTypeMsg(accessTypeMsg);
        	i.setServiceStatusMsg(StatusEnum.getName(i.getServiceStatus()));
        	
        	if(StringUtil.isBlank(i.getAppKeyId())){
        		i.setIsUsed("Y");
        	}else{
        		expirTime = DateUtil.parseDateTime(i.getExpiringDate());
        		if(expirTime.getTime()<now.getTime()
            			||i.getServiceStatus()==StatusEnum.Disable.getKey()
            			||i.getTokenStatus()==StatusEnum.Disable.getKey()){
            		i.setIsUsed("N");
            	}else{
            		i.setIsUsed("Y");
            	}
        		i.setSurplusTime(getDatePoor(expirTime, now));
        		i.setTokenStatusMsg(StatusEnum.getName(i.getTokenStatus()));
        	}
        	
        }
        
        return retList;
    }

    /**
     * 产品立即试用接口，返回所需要的token
     *
     * @param openUpOnTrialVO 产品立即试用接口请求参数
     * @return 包含token
     */
    public OpenUpOnTrialDTO openUpOnTrial(OpenUpOnTrialVO openUpOnTrialVO) {
    	OpenUpOnTrialDTO openUpOnTrialDTO = new OpenUpOnTrialDTO();
    	
        LantoneProduct lantoneProduct =new LantoneProduct();
        lantoneProduct.setId(openUpOnTrialVO.getProductId());
        LantoneProduct lantoneProducts = lantoneProductFacade.getById(lantoneProduct);
        if (null == lantoneProducts || IsDeleteEnum.Y.getKey().equals(lantoneProducts.getIsDeleted())){
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "该产品已删除");
        }
        if(StatusEnum.Disable.getKey()==lantoneProducts.getServiceStatus()){
        	throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "该产品已停用");
        }
        openUpOnTrialDTO.setTrialUrl(lantoneProducts.getTrialUrl());
        Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
        //验证用户是否生成过试用
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("userId", userId.toString());
        paramMap.put("productId", openUpOnTrialVO.getProductId());
        ServiceToken serviceToken = serviceTokenFacade.getTryTokenByUserIdAndProductId(paramMap);
        if (serviceToken!=null){
        	Date now = new Date();
            if(serviceToken.getExpiringDate().getTime()<now.getTime()){
            	throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "该产品已过期");
            }
            openUpOnTrialDTO.setAppKeyId(serviceToken.getAppKeyId());
            openUpOnTrialDTO.setAppKeySecret(serviceToken.getAppKeySecret());
            return openUpOnTrialDTO;
        }
        
        Date now = new Date();
        ServiceInfo serviceInfo = new ServiceInfo();
        serviceInfo.setType(ServiceTypeEnum.Sys_Create.getKey());
        serviceInfo.setUserId(userId);
        serviceInfo.setDescription("用户试用产品-" + lantoneProducts.getDecription());
        serviceInfo.setName("用户试用产品-" + lantoneProducts.getName());
        serviceInfo.setCreator(userId.toString());
        serviceInfo.setGmtCreate(now);
        serviceInfo.setIsDeleted(IsDeleteEnum.N.getKey());
        serviceInfoFacade.save(serviceInfo);

        ProductService productService = new ProductService();
        productService.setServiceId(serviceInfo.getId());
        productService.setProductId(openUpOnTrialVO.getProductId());
        productService.setCreator(userId.toString());
        productService.setGmtCreate(now);
        productService.setIsDeleted(IsDeleteEnum.N.getKey());
        productServiceFacade.save(productService);

        ProductServiceSaveVO productServiceSaveVO = new ProductServiceSaveVO();
        productServiceSaveVO.setProductId(openUpOnTrialVO.getProductId());
        productServiceSaveVO.setServiceId(serviceInfo.getId());
        productServiceSaveVO.setType(TokenTypeEnum.Trial.getKey());
        ProductServiceDTO poroductServiceDTO = productServiceFacade.genProductService(productServiceSaveVO);

        openUpOnTrialDTO.setAppKeyId(poroductServiceDTO.getServiceToken().getAppKeyId());
        openUpOnTrialDTO.setAppKeySecret(poroductServiceDTO.getServiceToken().getAppKeySecret());

        return openUpOnTrialDTO;
    }

    /**
     * 计算可展示的选项卡
     *
     * @return 可展是的选项卡
     */
    public EnShowOptionDTO enShowOption() {
        Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
        int openedCount = baseMapper.getConsoleOpenedCount(userId);
        int onTrialCount = baseMapper.getConsoleOnTrialCount(userId);

        EnShowOptionDTO enShowOptionDTO = new EnShowOptionDTO();
        enShowOptionDTO.setOrderCount(productOrderFacade.getUserProductOrderCount(userId));
        enShowOptionDTO.setOrderAuthFailCount(productOrderFacade.getOrderAuthFailCount(userId));
        enShowOptionDTO.setOpenedCount(openedCount);
        enShowOptionDTO.setOnTrialCount(onTrialCount);
        
        List<Integer> list = userServiceClient.getAuthInfoCount(userId).data;
        enShowOptionDTO.setAuthIngCount(list.get(0));
        enShowOptionDTO.setAuthRejectCount(list.get(1));

        return enShowOptionDTO;
    }
    
    /**
     * 控制台-已开通产品状态校验
     * @param openProductCheckVO
     * @return
     */
    public OpenProductCheckDTO openProductCheck(OpenProductCheckVO openProductCheckVO){
    	OpenProductCheckDTO openProductCheckDTO = new OpenProductCheckDTO();
    	openProductCheckDTO.setHasPermission(false);
    	
    	LantoneProduct lantoneProduct =new LantoneProduct();
        lantoneProduct.setId(openProductCheckVO.getProductId());
        lantoneProduct = lantoneProductFacade.getById(lantoneProduct);
        
    	if(lantoneProduct==null){
    		throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该产品不存在，请刷新页面");
    	}
    	if(lantoneProduct.getIsDeleted().equals("Y")){
			 throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "【"+lantoneProduct.getName()+"】已删除，请刷新页面");
		}
    	if(lantoneProduct.getServiceStatus()==StatusEnum.Disable.getKey()){
			throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "【"+lantoneProduct.getName()+"】已停用，请刷新页面");
		}
    	
    	Long userId = Long.parseLong(UserUtils.getCurrentPrincipleID());
    	if(openProductCheckVO.getOpenId()!=null){
    		OpenedProducts openedProducts = new OpenedProducts();
    		openedProducts.setId(openProductCheckVO.getOpenId());
    		openedProducts.setUserId(userId);
    		openedProducts = this.getById(openedProducts);
    		if(openedProducts==null||openedProducts.getProductId().longValue()!=openProductCheckVO.getProductId().longValue()){
    			throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "您的产品不存在，请刷新页面");
    		}
    		if(openedProducts.getIsDeleted().equals("Y")){
    			 throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "您的产品已删除，请刷新页面");
    		}
    		if(openedProducts.getEndTime().getTime()<DateUtil.now().getTime()){
    			throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "【"+lantoneProduct.getName()+"】已到期，请刷新页面");
    		}
    		if(openedProducts.getServiceStatus()==StatusEnum.Disable.getKey()){
    			throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "您的产品已停用，请刷新页面");
    		}
    	}
    	
    	
    	
    	openProductCheckDTO.setHasPermission(true);
    	return openProductCheckDTO;
    }
    

    /**
     * @param startAndendByUserIdVO
     * @return 根据用户id和产品id，删除开通信息
     */
    public RespDTO<StartAndendByUserIdVO> startAndendByuserIds(StartAndendByUserIdVO startAndendByUserIdVO) {
        OpenedProducts openedProducts = new OpenedProducts();
        openedProducts.setUserId(startAndendByUserIdVO.getUserId());
        openedProducts.setProductId(startAndendByUserIdVO.getProductId());
        openedProducts.setCreator(UserUtils.getCurrentPrincipleID());
        openedProducts.setGmtCreate(DateUtil.now());
        openedProducts.setServiceStatus(startAndendByUserIdVO.getServiceStatus());
         RespDTO<User> userData = userServiceClient.getUserAuthStatus(startAndendByUserIdVO.getUserId());
         User user = userData.data;
         if(user.getIsDeleted().equals("Y")){
           	 return RespDTO.onError("该用户已不存在"); 
            }
         //当用户是操作是启用的时候，先判断该产品是否是启用状态
		if (startAndendByUserIdVO.getServiceStatus().equals(StatusEnum.Enable.getKey())) {
			LantoneProduct lantoneProduct = new LantoneProduct();
			lantoneProduct.setId(startAndendByUserIdVO.getProductId());
			LantoneProduct lantone = lantoneProductFacade.getById(lantoneProduct);
			if (lantone.getServiceStatus().equals(StatusEnum.Disable.getKey())) {
				return RespDTO.onError("该产品线已停用");
			}
		}
		//判断该用户是否有续费申请单
     	UserRenewals userRenewals = new UserRenewals();
     	userRenewals.setUserId(startAndendByUserIdVO.getUserId());
     	userRenewals.setProductId(startAndendByUserIdVO.getProductId());
     	int userSum = userRenewalsFacade.getUserWaitingRenewal(userRenewals);
     	if(userSum>0){
      		 return RespDTO.onError("该产品无法停用，请先处理续费申请信息");
         	}
     	//验证是否有别的管理员操作过
     	Map<String, Object> map = new HashMap<String, Object>();
        map.put("userId", startAndendByUserIdVO.getUserId());
        map.put("productId", startAndendByUserIdVO.getProductId());
        List<OpenedProducts> OpenedProductsData = selectOpenedProducts(map);
        if(OpenedProductsData != null){
        	for(OpenedProducts openedProductsNew : OpenedProductsData){
        		if(openedProductsNew.getServiceStatus().equals(startAndendByUserIdVO.getServiceStatus())){
        			return RespDTO.onError("该产品已被"+StatusEnum.getName(startAndendByUserIdVO.getServiceStatus())+"无需处理");	
        		}
        	}	
        }
        boolean res = startAndendByuserId(openedProducts);
        if (!res) {
            throw new CommonException(CommonErrorCode.UPDATE_INFO_FAIL);
        }
        return RespDTO.onSuc(res);
    }

    /**
     * @param userId
     * @param productId
     * @return 根据用户id和产品id，删除开通信息
     */
    public RespDTO delInformationAvailables(Long userId, Long productId) {
        OpenedProducts openedProducts = new OpenedProducts();
        openedProducts.setUserId(userId);
        openedProducts.setProductId(productId);
        openedProducts.setModifier(UserUtils.getCurrentPrincipleID());
        openedProducts.setGmtModified(DateUtil.now());
        boolean res = delInformationAvailable(openedProducts);
        if (!res) {
            throw new CommonException(CommonErrorCode.UPDATE_INFO_FAIL);
        }
        return RespDTO.onSuc(res);
    }

    /**
     * @param modifyOpeningTimeVO
     * @return 根据用户id和产品id，修改开通时间
     */
    public RespDTO<Boolean> modifyOpeningTimes(ModifyOpeningTimeVO modifyOpeningTimeVO) {
        OpenedProducts openedProducts = new OpenedProducts();
        openedProducts.setUserId(modifyOpeningTimeVO.getUserId());
        openedProducts.setProductId(modifyOpeningTimeVO.getProductId());
        Map map =new HashMap();
        map.put("userId",modifyOpeningTimeVO.getUserId());
        map.put("productId",modifyOpeningTimeVO.getProductId());
        List<OpenedProducts> opendList = openedProductsFacade.selectOpenedProducts(map);
        List<Long> renewalsList = userRenewalsFacade.selectProductIdByUserId(map);
        for (OpenedProducts opened:opendList) {
            if(opened.getServiceStatus().intValue() == StatusEnum.Disable.getKey()){
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "用户产品已停用，请刷新页面");
            }
        }
        if(!renewalsList.contains(modifyOpeningTimeVO.getProductId())){
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "续费单已审核,请刷新重试");
        }
        for (OpenedProducts openedProducts1 :opendList) {
            if(beforeTime(openedProducts1.getEndTime(),modifyOpeningTimeVO.getEndTime())){
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "输入有误,续费时间需大于到期时间");
            }
        }
        openedProducts.setEndTime(DateUtil.parseDateTime(DateUtil.formatDateTime(DateUtil.getLastTimeOfDay(DateUtil.parseDate(modifyOpeningTimeVO.getEndTime())))));
        openedProducts.setModifier(UserUtils.getCurrentPrincipleID());
        openedProducts.setGmtModified(DateUtil.now());
        UserRenewals userRenewals = new UserRenewals();
        userRenewals.setRenewalsStatus(RenewalsEnum.RENEWALS.getKey());
        userRenewals.setGmtModified(DateUtil.now());
        userRenewals.setModifier(UserUtils.getCurrentPrincipleID());
        userRenewals.setEndTime(DateUtil.parseDateTime(DateUtil.formatDateTime(DateUtil.getLastTimeOfDay(DateUtil.parseDate(modifyOpeningTimeVO.getEndTime())))));
        userRenewals.setRenewalsNo(modifyOpeningTimeVO.getRenewalsNo());
       //修改续费时间
        boolean res = modifyOpeningTime(openedProducts);
        if (!res) {
            throw new CommonException(CommonErrorCode.UPDATE_INFO_FAIL);
        }
        //修改续费状态
        res = userRenewalsFacade.updateRenewalStatus(userRenewals);
        if (!res) {
            throw new CommonException(CommonErrorCode.UPDATE_INFO_FAIL);
        }
        return RespDTO.onSuc(res);
    }
    private String getDatePoor(Date endDate, Date nowDate) {
    	if(endDate.getTime()<nowDate.getTime()){
    		return "";
    	}
    	
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }
    private Boolean beforeTime(Date startTime,String endTime) {
        DateUtil dateUtil = new DateUtil();
        //将日期转成Date对象作比较
        Date fomatDate2 = dateUtil.parseDate(endTime);
        //比较两个日期
        int result = fomatDate2.compareTo(startTime);
        //如果日期相等返回0
        if (result == 0 || result < 0) {
            //小于0，参数startTime大于endTime
            return true;
        }
            //大于0，参数startTime小于endTime
        return false;
    }
}
