package com.cyksj.service.sys.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.service.CropDutyServiceDateService;
import com.cyksj.common.util.Jsons;
import com.cyksj.mapper.corp.CorpFollowMapper;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.model.dto.DefaultShopConfig;
import com.cyksj.model.dto.YhServiceDto;
import com.cyksj.model.entity.CorpFollow;
import com.cyksj.model.entity.ShopConfig;
import com.cyksj.model.entity.SysConfig;
import com.cyksj.service.sys.SysConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chan
 * @date 2022/10/20 10:07 AM
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper,SysConfig> implements SysConfigService {
	private final CorpFollowMapper corpFollowMapper;

	@Override
	public String getDefaultShopConfigByType(String type) {
		SysConfig shopConfig = this.getOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.SYS_DEFAULT_SHOP_KEY).last("limit 1"));
		if (shopConfig == null) {
			return getShopIdByType(type);
		}
		String sysValue = shopConfig.getSysValue();
		try {
			DefaultShopConfig defaultShopConfig = Jsons.parseObject(sysValue, DefaultShopConfig.class);
			String wxDefaultAppId = defaultShopConfig.getWxDefaultAppId();
			String zfbDefaultAppId = defaultShopConfig.getZfbDefaultAppId();
			if ("wx".equals(type)) {
				return Optional.ofNullable(wxDefaultAppId).orElse(ShopConfig.WX_DEFAULT_APP_ID);
			}
			return Optional.ofNullable(zfbDefaultAppId).orElse(ShopConfig.ZFB_DEFAULT_APP_ID);
		} catch (Exception e) {

		}
		return getShopIdByType(type);
	}
	public String getShopIdByType(String type) {
		if ("wx".equals(type)) {
			return ShopConfig.WX_DEFAULT_APP_ID;
		}
		return ShopConfig.ZFB_DEFAULT_APP_ID;
	}


	@Override
	public List<Integer> getDutyServices() throws Exception {
		SysConfig sysConfig = this.getOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.serviceKeys.get(0))
				.last("limit 1"));
		//过滤被禁用的规格
		Map<String, List<CorpFollow>> followMap = corpFollowMapper.selectList(Wrappers.lambdaQuery(CorpFollow.class)
				.ne(CorpFollow::getStatus, 1)).stream().collect(Collectors.groupingBy(CorpFollow::getUserid));
		List<YhServiceDto> yhServiceDtos = null;

		if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
			yhServiceDtos = Jsons.parseList(sysConfig.getSysValue(), YhServiceDto.class);
			yhServiceDtos.stream().forEach(s -> {
				List<YhServiceDto.CustomerServiceDto> finalSelect = s.getSelect().stream().filter(select -> {
					List<CorpFollow> corpFollows = followMap.get(select);
					if (CollUtil.isNotEmpty(corpFollows)) {
						CorpFollow corpFollow = corpFollows.get(0);
						if (corpFollow.getStatus() != 1) {
							return false;
						}
					}
					return true;
				}).collect(Collectors.toList());
				s.setSelect(finalSelect);
			});
		}

		final List<YhServiceDto> dtoCs = yhServiceDtos;

		List<YhServiceDto> workdayServices = null;
		List<YhServiceDto> saturdayServices = null;
		List<YhServiceDto> sundayServices = null;
		Map<String, List<YhServiceDto>> holidayDateMap = null;

		if (CollUtil.isNotEmpty(dtoCs)) {
			Map<String, List<YhServiceDto>> dutyServices = yhServiceDtos.stream().collect(Collectors.groupingBy(YhServiceDto::getSign));
			workdayServices = dutyServices.get("workday");
			saturdayServices = dutyServices.get("Saturday");
			sundayServices = dutyServices.get("Sunday");

			List<YhServiceDto> holidayServices = dutyServices.get("holiday");
			if (CollUtil.isNotEmpty(holidayServices)) {
				holidayDateMap = holidayServices.stream().collect(Collectors.groupingBy(YhServiceDto::getDate));
			}
		}
		LocalDateTime now = LocalDateTime.now();
		List<Integer> dutyServices = getDutyServices(workdayServices, saturdayServices, sundayServices, holidayDateMap, now);
		return dutyServices;
	}

	public List<Integer> getDutyServices(List<YhServiceDto> workday, List<YhServiceDto> saturday, List<YhServiceDto> sunday, Map<String, List<YhServiceDto>> holidayDateMap, LocalDateTime now) {
		if (CollUtil.isNotEmpty(workday)) {
			DayOfWeek currentDayOfWeek = now.getDayOfWeek();

			List<YhServiceDto> carryServices = CropDutyServiceDateService.getDutyService(currentDayOfWeek, workday, saturday, sunday, holidayDateMap, now);
			//获取值班客服
			List<YhServiceDto> dutyServiceCodes = getTimeDutyServices(carryServices, workday, saturday, sunday, holidayDateMap, currentDayOfWeek, now);
			if (CollUtil.isNotEmpty(dutyServiceCodes)) {
				Set<Integer> collectFollow = new HashSet<>();
				for (YhServiceDto dutyServiceCode : dutyServiceCodes) {
					dutyServiceCode.getSelect().stream().filter(e -> e.getIndex() != null).forEach(cs -> collectFollow.add(cs.getIndex()));
				}
				return new ArrayList<>(collectFollow);
			}
		}
		return null;
	}

	/**
	 * 获取当前时间段值班的客服
	 */
	public List<YhServiceDto> getTimeDutyServices(List<YhServiceDto> carryServices, List<YhServiceDto> workday, List<YhServiceDto> saturday, List<YhServiceDto> sunday, Map<String, List<YhServiceDto>> holidayDateMap, DayOfWeek currentDayOfWeek, LocalDateTime now) {
		// 获取当前时间
		LocalTime currentTime = now.toLocalTime();

		List<YhServiceDto> collect = carryServices.stream().filter(time -> time.isBetween(currentTime)).collect(Collectors.toList());
		if (CollUtil.isEmpty(collect)) {
			collect = carryServices.stream().filter(time -> time.isAfter(currentTime)).collect(Collectors.toList());
			if (CollUtil.isEmpty(collect)) {
				// 如果没有下一个时间段，获取下一个工作时间段的开始时间
				DayOfWeek nextWorkDay = CropDutyServiceDateService.getNextWorkDay(currentDayOfWeek);
				collect = CropDutyServiceDateService.getDutyService(nextWorkDay, workday, saturday, sunday, holidayDateMap, now.plusDays(1));
			}
			collect.sort(Comparator.comparing(e -> DateUtil.parse(e.getSortTime() == null ? e.getStartTime() : e.getSortTime(), "HH:mm")));
			//获取下一天的早时
			return List.of(collect.get(0));
		}
		return collect;
	}

}
