package com.persagy.calendar.controller;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.persagy.calendar.constant.WorkCalendarConstant;
import com.persagy.calendar.handle.CommonHandler;
import com.persagy.calendar.handle.WorkCalendarDateHandler;
import com.persagy.calendar.pojo.dto.WorkCalendar;
import com.persagy.calendar.pojo.dto.WorkCalendarDate;
import com.persagy.calendar.pojo.dto.WorkCalendarDict;
import com.persagy.calendar.pojo.dto.WorkCalendarRule;
import com.persagy.calendar.pojo.vo.DictCodeCreate;
import com.persagy.calendar.pojo.vo.DictCreateVO;
import com.persagy.calendar.pojo.vo.DictQueryVO;
import com.persagy.calendar.pojo.vo.WorkCalendarDateQueryVO;
import com.persagy.calendar.service.IWorkCalendarDictService;
import com.persagy.calendar.service.IWorkCalendarService;
import com.persagy.common.enums.ResponseCode;
import com.persagy.common.exception.BusinessException;
import com.persagy.common.utils.DateUtil;
import com.persagy.common.utils.IdGenerator;
import com.persagy.common.utils.ResponseResult;
import com.persagy.common.utils.ResponseUtil;
import com.persagy.common.utils.StringUtil;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;

/**
 * 通用接口
 * @version 1.0.0
 * @company persagy 
 * @author zhangqiankun
 * @date 2020-10-03 13:54:22
 */
@RestController
@RequestMapping(value = "/v2.0/common", method = RequestMethod.POST)
public class CommonController {

	@Value("${integrated.calendar.group-code:BR}")
	private String defaultGroupCode;
	
    @Autowired
    private IWorkCalendarService workCalendarService;
	
	@Autowired
	private CommonHandler commonHandler;
	
	@Autowired
	private IWorkCalendarDictService workCalendarDictService;
	
	@Autowired
	private WorkCalendarDateHandler workCalendarDateHandler;
	
	/**
	 * 规则解析可以不需要集团编码和项目ID
	 * 当日的作息时间，在查询时，实时解析
     * 手动解析规则信息
     * 非自定义已存在的作息时间信息被更新，不存在的被插入，自定义的不动
     */
    @RequestMapping(value = "handleParseCalendarRule")
    public ResponseResult handleParseCalendarRule(@RequestBody @Validated WorkCalendarDateQueryVO queryVO) {
    	if ("Pj1111111111".equalsIgnoreCase(queryVO.getProjectId())) {
    		queryVO.setProjectId(null);
		}
    	
    	DateTime dateStart = DateUtil.parse(queryVO.getWorkDateStart(), DateUtil.FORMAT_DATE_YYYYMMDD);
		DateTime dateEnd = DateUtil.parse(queryVO.getWorkDateEnd(), DateUtil.FORMAT_DATE_YYYYMMDD);
		if (dateEnd.before(dateStart)) {
			throw new BusinessException(ResponseCode.A0400.getCode(), "结束日期不能早于开始日期");
		}
		
		// 相等时，往前偏移一天，临时方案，后续可删除，在xxl-job更新后
		if (dateStart.equals(dateEnd)) {
    		dateStart.offset(DateField.DAY_OF_YEAR, -1);
    		queryVO.setWorkDateStart(dateStart.toString(DateUtil.FORMAT_DATE_YYYYMMDD));
		}
    	
    	// 2.获取此段时间内的自定义的规则信息
    	List<WorkCalendarDate> customDateList = this.workCalendarDateHandler.selectWorkCalendarDateList(queryVO, WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES, null);
    	
    	// 3.获取此段时间内的规则信息
		Map<String, List<WorkCalendarDate>> calendarDateMap = new HashMap<String, List<WorkCalendarDate>>();
		List<WorkCalendarRule> ruleList = this.workCalendarDateHandler.selectWorkCalendarRuleList(queryVO, null);
		long betweenDay = DateUtil.between(dateStart, dateEnd, DateUnit.DAY) + 1;
		this.workCalendarDateHandler.paserWorkCalendarRule(calendarDateMap, ruleList, dateStart, betweenDay);
		
		// 4.自定义与规则的进行判断，存在的自定义的将不再进行插入
		List<WorkCalendarDate> workCalendarDates = this.workCalendarDateHandler.handleParseCalendarRule(queryVO, customDateList, calendarDateMap);
		
		// 5.删除更新
    	boolean result = this.workCalendarDateHandler.createCalendarDateByDelete(workCalendarDates, queryVO.getWorkDateStart(), queryVO.getWorkDateEnd());
		return result ? ResponseUtil.successResult("执行成功") : ResponseUtil.errorResult("执行失败");
    }
    
	/**
     * 字典值查询
     */
    @RequestMapping(value = "dictQuery")
    public ResponseResult dictQuery(@RequestBody @Validated DictQueryVO queryVO) {
    	if (StringUtil.isBlank(queryVO.getGroupCode())) {
			queryVO.setGroupCode(defaultGroupCode);
		}
    	int dictTypeLevel = this.workCalendarDictService.getDictTypeLevel(queryVO.getGroupCode(), queryVO.getDictType());
    	
    	LambdaQueryWrapper<WorkCalendarDict> queryWrapper = new WorkCalendarDict.BuilderQueryWrapper().groupCodeEq(queryVO.getGroupCode())
    			.calendarIdEq(queryVO.getCalendarId(), dictTypeLevel).dictTypeEq(queryVO.getDictType()).builder();
    	List<WorkCalendarDict> list = this.workCalendarDictService.list(queryWrapper);
    	if (CollectionUtil.isEmpty(list)) {
			return ResponseUtil.successResult(Lists.newArrayList());
		}
    	
    	Map<String, String> dictTypeCode = new HashMap<String, String>(8);
    	String dictType = null;
    	for (WorkCalendarDict dict : list) {
    		dictType = dict.getDictType();
    		if (WorkCalendarConstant.CUSTOM_CALENDAR_DICT_TYPE.equals(dictType)) {
    			dictTypeCode.put(StringUtil.isBlank(dict.getDictCode()) ? dict.getDictDesc() : dict.getDictCode(), dict.getDictDesc());
			} else {
				dictTypeCode.put(dict.getDictCode(), dict.getDictDesc());
			}
		}
		return ResponseUtil.successResult(dictTypeCode);
    }
    
    @RequestMapping(value = "dictCreate")
    public ResponseResult dictCreate(@RequestBody @Validated DictCreateVO<DictCodeCreate> createVO) {
    	if (StringUtil.isBlank(createVO.getGroupCode())) {
			createVO.setGroupCode(defaultGroupCode);
		}
    	
    	List<WorkCalendarDict> calendarDicts = new ArrayList<WorkCalendarDict>();
    	List<DictCodeCreate> codes = createVO.getCodes();
    	for (DictCodeCreate dictCodeCreate : codes) {
    		WorkCalendarDict calendarDict = new WorkCalendarDict();
    		calendarDict.setGroupCode(createVO.getGroupCode());
    		calendarDict.setProjectId(createVO.getProjectId());
    		calendarDict.setCalendarId(createVO.getCalendarId());
    		calendarDict.setId(IdGenerator.getUUID());
    		calendarDict.setDictType(createVO.getDictType());
    		calendarDict.setDictCode(dictCodeCreate.getDictCode());
    		calendarDict.setDictDesc(dictCodeCreate.getDictDesc());
    		calendarDicts.add(calendarDict);
		}
    	
    	boolean result = this.workCalendarDictService.batchCreateDictTypeByDelete(calendarDicts);
    	return result ? ResponseUtil.successResult("创建成功") : ResponseUtil.successResult("创建失败");
    }
    
    /**
     * 项目字典数据初始化
     * 
     * @param queryVO
     * @return
     */
    @RequestMapping(value = "initProjectDict")
    public ResponseResult initProjectDict(@RequestBody DictQueryVO queryVO) {
    	if (StringUtil.isBlank(queryVO.getGroupCode())) {
    		return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "集团编码，不可为空");
		}
    	if (CollectionUtil.isEmpty(queryVO.getDictTypes())) {
    		return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "字典类型，不可为空");
		}
    	String result = this.commonHandler.initProjectDict(queryVO.getGroupCode(), queryVO.getDictTypes());
    	return StringUtil.isBlank(result) ? ResponseUtil.successResult("初始化成功") : ResponseUtil.errorResult(result);
    }
    
    /**
     * 数据转换
     * 
     * @param queryVO
     * @return
     */
    @RequestMapping(value = "switchData")
    public ResponseResult switchData(@RequestBody DictQueryVO queryVO) {
    	// 获取该集团下所有的工作历类型
    	QueryWrapper<WorkCalendar> queryWrapper = new WorkCalendar.Builder().createQueryWrapper()
    			.groupCodeEq(queryVO.getGroupCode()).builderQueryWrapper();
    	List<WorkCalendar> workCalendars = this.workCalendarService.list(queryWrapper);
    	if (CollectionUtil.isEmpty(workCalendars)) {
    		return ResponseUtil.errorResult("该集团下不存在工作历");
		}
    	
    	this.commonHandler.switchData(workCalendars, queryVO.getGroupCode());
    	return ResponseUtil.successResult("转换成功");
    }
    
}
