package com.neusoft.smart.pos.advertisement.service;

import com.neusoft.smart.pos.advertisement.constants.AdvertisementErrorCode;
import com.neusoft.smart.pos.advertisement.persistent.domain.MediaStrategy;
import com.neusoft.smart.pos.advertisement.persistent.domain.MediaStrategyGroup;
import com.neusoft.smart.pos.advertisement.persistent.ext.domain.MediaResourceStrategyQuery;
import com.neusoft.smart.pos.advertisement.persistent.repository.MediaResourceStrategyRepository;
import com.neusoft.smart.pos.advertisement.task.MediaStrategyTask;
import com.neusoft.smart.pos.dto.advertisement.request.MediaResourceQueryRequest;
import com.neusoft.smart.pos.dto.advertisement.request.MediaResourceStrategyQueryRequest;
import com.neusoft.smart.pos.dto.advertisement.request.MediaResourceStrategyRequest;
import com.neusoft.smart.pos.dto.advertisement.response.DeviceMediaResponse;
import com.neusoft.smart.pos.dto.advertisement.response.MediaResourceResponse;
import com.neusoft.smart.pos.dto.advertisement.response.MediaResourceStrategyResponse;
import com.neusoft.smart.pos.dto.advertisement.response.MediaStrategyResponse;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.task.TaskExecutor;
import com.neusoft.smart.pos.framework.utils.BeanUtil;
import com.neusoft.smart.pos.redis.bean.DeviceMedias;
import com.neusoft.smart.pos.utils.RequestHeaderUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class MediaResourceStrategyService {
	
	@Autowired
	private MediaResourceStrategyRepository mediaResourceStrategyRepository;
	
	@Autowired
	private TaskExecutor taskExecutor;
	
	@Autowired
	private MediaResourceService mediaResourceService;
	
	
	@Resource(name = "deviceMediaMap")
	private BoundHashOperations<String, String, DeviceMedias> deviceAdMap;
	
	@Transactional
	public void create(MediaResourceStrategyRequest mediaResourceStrategyRequest) {
		if (mediaResourceStrategyRepository.countByName(mediaResourceStrategyRequest.getStrategyName()) > 0) {
			throw new BusinessCommonException(AdvertisementErrorCode.STRATEGY_NAME_DUPLICATE);
		}
		MediaStrategyGroup mediaStrategyGroup = new MediaStrategyGroup();
		mediaStrategyGroup.setStrategyName(mediaResourceStrategyRequest.getStrategyName());
		mediaStrategyGroup.setCacheTime(mediaResourceStrategyRequest.getCacheTime());
		mediaStrategyGroup.setCreatedBy(RequestHeaderUtil.getUserId());
		mediaStrategyGroup.setOrganizationId(RequestHeaderUtil.getOrgId());
		mediaResourceStrategyRepository.createGroup(mediaStrategyGroup);
		Integer groupId = mediaStrategyGroup.getId();
		List<MediaStrategy> strategyList = new ArrayList<>();
		mediaResourceStrategyRequest.getDeviceList().forEach(device ->
				mediaResourceStrategyRequest.getStrategyList().forEach(strategyRequest -> {
					MediaStrategy strategy = new MediaStrategy();
					BeanUtils.copyProperties(strategyRequest, strategy);
					strategy.setDeviceId(device.getId());
					strategy.setStrategyId(groupId);
					strategy.setStatus(0);
					strategyList.add(strategy);
					
				})
		);
		mediaResourceStrategyRepository.batchCreate(strategyList);
		MediaStrategyTask mediaStrategyTask = new MediaStrategyTask();
		mediaStrategyTask.setMediaResourceStrategyRequest(mediaResourceStrategyRequest);
		taskExecutor.getExecutorService().execute(mediaStrategyTask);
	}
	
	/**
	 * @param mediaResourceStrategyQueryRequest
	 * @return
	 */
	public List<MediaResourceStrategyResponse> getGroupList(MediaResourceStrategyQueryRequest mediaResourceStrategyQueryRequest) {
		List<MediaResourceStrategyResponse> result = new ArrayList<>();
		List<MediaStrategyGroup> poList = mediaResourceStrategyRepository.getGroupList(BeanUtil.parse(mediaResourceStrategyQueryRequest, MediaResourceStrategyQuery.class));
		poList.forEach(po -> {
			MediaResourceStrategyResponse response = new MediaResourceStrategyResponse();
			BeanUtils.copyProperties(po, response);
			result.add(response);
		});
		return result;
	}
	
	/**
	 * @param mediaResourceStrategyQueryRequest
	 * @return
	 */
	public Integer getGroupCount(MediaResourceStrategyQueryRequest mediaResourceStrategyQueryRequest) {
		return mediaResourceStrategyRepository.getGroupCount(BeanUtil.parse(mediaResourceStrategyQueryRequest, MediaResourceStrategyQuery.class));
	}
	
	/**
	 * @param groupId
	 * @return
	 */
	public List<MediaStrategyResponse> getList(Integer groupId) {
		List<MediaStrategyResponse> result = new ArrayList<>();
		List<MediaStrategy> poList = mediaResourceStrategyRepository.getList(groupId);
		List<Integer> resourceIds = new ArrayList<>();
		poList.forEach(po -> {
			resourceIds.add(po.getMediaResourceId());
			if (null != po.getBackgroundAudioId()) {
				resourceIds.add(po.getBackgroundAudioId());
			}
			MediaStrategyResponse response = new MediaStrategyResponse();
			BeanUtils.copyProperties(po, response);
			result.add(response);
		});
		MediaResourceQueryRequest mediaResourceQuery = new MediaResourceQueryRequest();
		mediaResourceQuery.setIds(resourceIds);
		List<MediaResourceResponse> resourceList = mediaResourceService.getList(mediaResourceQuery);
		result.forEach(response -> {
			response.setMediaResource(resourceList.stream().filter(resource -> resource.getId().equals(response.getMediaResourceId())).findAny().orElse(null));
			response.setBackgroundAudio(resourceList.stream().filter(resource -> resource.getId().equals(response.getBackgroundAudioId())).findAny().orElse(null));
		});
		return result;
	}
	
	/**
	 * @param groupId
	 */
	public void cancel(Integer groupId) {
		MediaStrategyGroup mediaStrategyGroup = new MediaStrategyGroup();
		mediaStrategyGroup.setId(groupId);
		mediaStrategyGroup.setStatus(1);
		mediaResourceStrategyRepository.updateGroup(mediaStrategyGroup);
		MediaStrategy mediaStrategy = new MediaStrategy();
		mediaStrategy.setStatus(1);
		mediaResourceStrategyRepository.updateByStrategyId(groupId, mediaStrategy);
	}
	
	
	/**
	 * 查询广告策略缓存
	 *
	 * @param sn
	 * @return
	 */
	public DeviceMediaResponse queryAd(String sn) {
		DeviceMediaResponse deviceMediaResponse = new DeviceMediaResponse();
		DeviceMedias deviceMedias = deviceAdMap.get(sn);
		try {
			if (null == deviceMedias) {
				deviceMediaResponse.setSt(-999);
				deviceMediaResponse.setMsg("查无此设备");
			} else {
				deviceMediaResponse.setCacheTime(deviceMedias.getCacheTime());
				deviceMediaResponse.setMediaList(deviceMedias.getMediaList());
				deviceMediaResponse.setSt(0);
				deviceMediaResponse.setMsg("success");
			}
			
		} catch (Exception e) {
			deviceMediaResponse.setSt(-999);
			deviceMediaResponse.setMsg("服务端异常");
		}
		return deviceMediaResponse;
	}
	
	
}
