package com.cyksj.service.home.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.mapper.GoodsDonMapper;
import com.cyksj.mapper.manage.home.HomeManagementConfigMapper;
import com.cyksj.model.entity.GoodsDon;
import com.cyksj.model.entity.HomeManagementConfig;
import com.cyksj.model.entity.SysFuncTimingShelf;
import com.cyksj.model.request.HomeConfigTimingReq;
import com.cyksj.model.request.HomeManageConfigReq;
import com.cyksj.service.home.HomeManagementConfigService;
import com.cyksj.service.sys.SysFuncTimingShelfService;
import com.cyksj.task.JobManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/*
 *项目名: netflix
 *文件名: HomeManagementConfigServiceImpl
 *创建者: JavaZou
 *创建时间:2023/8/17 16:48
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class HomeManagementConfigServiceImpl extends ServiceImpl<HomeManagementConfigMapper, HomeManagementConfig> implements HomeManagementConfigService {
	private final GoodsDonMapper goodsDonMapper;

	private final SysFuncTimingShelfService sysFuncTimingShelfService;

	private final JobManager jobManager;

	@Override
	public void saveOrUpdateConfig(HomeManageConfigReq config) {
		if (isSpecialType(config.getType())) {
			Assert.notEmpty(config.getTitle(), "标题不为空");
			HomeManagementConfig homeManagementConfig = new HomeManagementConfig();
			BeanUtil.copyProperties(config, homeManagementConfig);
			if (config.getType() == HomeManagementConfig.Type.ad) {
				if (config.getAdType() == null) {
					throw BusinessRuntimeException.getInstance("请选择对应的广告配置类型");
				}
			}else if (config.getType() == HomeManagementConfig.Type.rg) {
				if (config.getRgType() == null) {
					throw BusinessRuntimeException.getInstance("请选择对应的实物配置类型");
				}
			}
			this.saveOrUpdate(homeManagementConfig);
			//定时上下架
			Long time = config.getTime();
			Long endTime = config.getEndTime();
			if (time != null && endTime != null) {
				HomeConfigTimingReq homeConfigTimingReq = new HomeConfigTimingReq();
				homeConfigTimingReq.setId(homeManagementConfig.getId());
				homeConfigTimingReq.setTime(time);
				homeConfigTimingReq.setEndTime(endTime);
				homeConfigTimingReq.setPreStatus(config.getStatus());
				timingUpdateStatus(homeConfigTimingReq);
			}
			return;
		}

		//首页平台推荐、首页精彩推荐
		List<Long> goodsIds = config.getGoodsIds();
		if (CollUtil.isEmpty(goodsIds)) {
			throw BusinessRuntimeException.getInstance("请选择对应的平台");
		}
		goodsIds.forEach(goodsId -> {
			GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
			if (goodsDon == null || !goodsDon.getStatus()) {
				return;
			}
			HomeManagementConfig homeManagementConfig = this.getOne(Wrappers.lambdaQuery(HomeManagementConfig.class)
					.ne(config.getId() != null, HomeManagementConfig::getId, config.getId())
					.eq(HomeManagementConfig::getGoodsId, goodsId)
					.eq(HomeManagementConfig::getType, config.getType())
					.eq(HomeManagementConfig::getDeleted, true).last("limit 1"));
			if (homeManagementConfig != null) {
				return;
			}
			homeManagementConfig = new HomeManagementConfig();
			BeanUtil.copyProperties(config, homeManagementConfig);
			homeManagementConfig.setGoodsId(goodsId);
			homeManagementConfig.setType(config.getType());
			this.saveOrUpdate(homeManagementConfig);
		});
	}


	public Boolean isSpecialType(HomeManagementConfig.Type type) {
		if (type == HomeManagementConfig.Type.rg || type == HomeManagementConfig.Type.ad) {
			return true;
		}
		return false;
	}


	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void timingUpdateStatus(HomeConfigTimingReq req) {
		Long id = req.getId();
		HomeManagementConfig config = this.getById(id);
		if (config == null || !config.getDeleted()) {
			throw BusinessRuntimeException.getInstance("对应配置不存在..");
		}
		Boolean preStatus = Optional.ofNullable(req.getPreStatus()).orElse(false);
		//上架状态
//		if (config.getStatus() && preStatus) {
//			throw BusinessRuntimeException.getInstance("该首页配置已上架,只能定时下架..");
//		}
//
//		if (!config.getStatus() && !preStatus) {
//			throw BusinessRuntimeException.getInstance("该首页配置已下架,只能定时上架..");
//		}

		//删除之前设置的定时任务
		cancelTimingJob(List.of(id));

		Long time = req.getTime();
		Long endTime = req.getEndTime();
		Long nowMills = System.currentTimeMillis();

		//直接将配置改为对应 定时上下架状态
		Boolean timingJob = true;
		config.setTime(time);
		config.setEndTime(endTime);
		if (time <= nowMills) {
			//配置上下架状态
			config.setStatus(true);
			config.setPreStatus(null);
//			timingJob = false;
		} else {
			//配置上下架状态
			config.setStatus(false);
			config.setPreStatus(preStatus);
		}
		this.updateById(config);

		//删除之前设置的定时任务
		cancelTimingJob(List.of(id));

		if (timingJob) {
			//定时上架
			timeUpateStatus(id, time, true, nowMills);
			//定时下架
			timeUpateStatus(id, endTime, false, nowMills);
		}
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void timingCancel(Long id) {
		HomeManagementConfig config = this.getById(id);
		if (config == null || !config.getDeleted()) {
			throw BusinessRuntimeException.getInstance("对应配置不存在..");
		}
		//删除之前设置的定时任务
		cancelTimingJob(List.of(id));

		if (config.getTime() != null) {
			config.setTime(null);
			config.setEndTime(null);
			config.setPreStatus(null);
			this.updateById(config);
		}
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void batchCancelTimingStatus(List<Long> ids) {
		cancelTimingJob(ids);
	}

	public void cancelTimingJob(List<Long> ids) {
		Integer count = sysFuncTimingShelfService.count(Wrappers.lambdaQuery(SysFuncTimingShelf.class)
				.eq(SysFuncTimingShelf::getType, SysFuncTimingShelf.Type.hc)
				.in(SysFuncTimingShelf::getFuncId, ids)
				.eq(SysFuncTimingShelf::getDeleted, 1));
		if (count > 0) {
			sysFuncTimingShelfService.update(null, Wrappers.lambdaUpdate(SysFuncTimingShelf.class)
					.set(SysFuncTimingShelf::getDeleted, 0)
					.eq(SysFuncTimingShelf::getType, SysFuncTimingShelf.Type.hc)
					.in(SysFuncTimingShelf::getFuncId, ids)
					.eq(SysFuncTimingShelf::getDeleted, 1));
			log.info("将之前设置的同配置下{},ids：{}的定时上下架删除", SysFuncTimingShelf.Type.hc.getDesc(), ids.toString());
		}
	}

	private void timeUpateStatus(Long id, Long time, boolean preStatus, Long nowMills) {
		SysFuncTimingShelf timingShelf = new SysFuncTimingShelf();
		timingShelf.setTime(time);
		timingShelf.setTimeStr(DateTime.of(time).toString());
		timingShelf.setPreStatus(preStatus);
		timingShelf.setFuncId(id);
		timingShelf.setType(SysFuncTimingShelf.Type.hc.name());
		sysFuncTimingShelfService.save(timingShelf);

		sysFuncTimingShelfService.addTimingJob(SysFuncTimingShelf.Type.hc.name(), id, timingShelf.getPreStatus(), time, nowMills);
	}
}
