package com.yeejoin.amos.boot.module.common.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.common.api.dto.DutyPersonDto;
import com.yeejoin.amos.boot.module.common.api.entity.DutyPersonShift;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormColumn;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormInstance;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.service.IDutyPersonService;
import com.yeejoin.amos.boot.module.common.biz.enums.DataDictionaryTypeEnum;
import com.yeejoin.amos.boot.module.common.biz.enums.DynamicGroupCodeEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author DELL
 */
@Service
public class DutyPersonServiceImpl extends DutyCommonServiceImpl implements IDutyPersonService{

    @Autowired
    EquipFeignClient equipFeign;



    private static final String USERNAME="userName";
    private static final String DEPTID="deptId";
    private static final String DEPTNAME="deptName";
    private static final String POSTTYPENAME="postTypeName";
    private static final String WXXFZ="微型消防站";
    private static final String VALUE="value";

@Override
    public String getGroupCode(){
        return "dutyPerson";
    }

    @Override
    public DutyPersonDto save(DutyPersonDto dutyPersonDto) {
        // BUG 2807 更新人员车辆排版值班的保存逻辑 如果没有填写数据则保存空数据 。 同步修改 查询 导出相关逻辑 by kongfm 2021-09-14
        //1.保存行数据
        String groupCode = this.getGroupCode();
        String userId = dutyPersonDto.getUserId();
        List<DynamicFormInstance> instances = dynamicFormInstanceService
                .list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getFieldCode, "userId")
                        .eq(DynamicFormInstance::getFieldValue, userId)
                        .eq(DynamicFormInstance::getGroupCode, this.getGroupCode()));
        Long instanceId = null;
        // 如果人员有区域id 则创建区域字段
        if(StringUtils.isNotEmpty(dutyPersonDto.getDutyAreaId())) {
            // 根据建筑id 查找建筑
            ResponseModel<Map<String, Object>> response = null;
            try {
                response = equipFeign.getFormInstanceById(Long.parseLong(dutyPersonDto.getDutyAreaId()));
            } catch (NumberFormatException e) {
                throw new BadRequest("值班区域id异常！");
            }
            Map<String, Object> result = response.getResult();
            dutyPersonDto.setDutyArea(result.get("name").toString());
        }

        Map<String, Object> map = Bean.BeantoMap(dutyPersonDto);
        buildDataMap(map, userId);
        if (!instances.isEmpty()) {
            // 0.定位instanceId，准备进行更新操作
            instanceId = instances.get(0).getInstanceId(); // 已经有了走更新方法
            //1.查询已有数据
            List<DynamicFormInstance> hasInstances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
            //2.list 转 map
            Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(hasInstances, "fieldCode", DynamicFormInstance.class);
            //3.查询列数据，已列为主
            List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
            //4.已列为主 填充动态表单数据
            List<DynamicFormInstance> entrys = new ArrayList<>();
            for (DynamicFormColumn column : columns) {
                DynamicFormInstance formInstance = instanceMap.get(column.getFieldCode());
                if (!ObjectUtils.isEmpty(formInstance)) {
                    //有的更新
                    formInstance.setFieldValue(map.get(column.getFieldCode()) != null ? map.get(column.getFieldCode()).toString() : "");
                } else {
                    //没有的新增
                    formInstance = new DynamicFormInstance();
                    buildFormInstanceData(instanceId, map, column, formInstance);
                }
                entrys.add(formInstance);
            }
            if(!entrys.isEmpty()){
                dynamicFormInstanceService.saveOrUpdateBatch(entrys);
            }

        } else {
            instanceId =  dynamicFormInstanceService.commonSave(groupCode,map);
        }
        // 如果当前保存没有保存调班记录 需要默认保存一个月的空数据

        if(dutyPersonDto.getDutyShift() != null && dutyPersonDto.getDutyShift().size() == 0) {
            Calendar startDate = Calendar.getInstance();
            startDate.setTime(DateUtils.longStr2Date(dutyPersonDto.getStartTime()));
            int dates = startDate.getActualMaximum(Calendar.DAY_OF_MONTH);
            startDate.set(Calendar.DAY_OF_MONTH, 1);
            List<DutyPersonShift> dutyShift = new ArrayList<>(dates);
            for (int i = 0 ; i < dates ; i ++) {
                DutyPersonShift temp = new DutyPersonShift();
                temp.setAppKey(RequestContext.getAppKey());
                temp.setDutyDate(startDate.getTime());
                temp.setIsDelete(false);
                temp.setInstanceId(instanceId);
                dutyShift.add(temp);
                startDate.add(Calendar.DAY_OF_YEAR,1);
            }
            dutyPersonShiftService.saveOrUpdateBatch(dutyShift);
        }
        //2.保存值班信息
        insertPersonShift(instanceId, dutyPersonDto);
        //3.返回保存后的数据
        return dutyPersonDto;



    }
    private Map<String, Object> buildDataMap(Map<String, Object> d, String userId) {
        // 表单存在人员类型，获取用户ID，查询人员类型赋值
        if (!ObjectUtils.isEmpty(userId)) {
            List<DynamicFormInstance> instances = dynamicFormInstanceService
                    .list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getFieldCode, "peopleType")
                            .eq(DynamicFormInstance::getInstanceId, userId)
                            .eq(DynamicFormInstance::getGroupCode, DynamicGroupCodeEnum.JCS_PERSON.getCode()));
            if (!CollectionUtils.isEmpty(instances)) {
                String fieldValue = instances.get(0).getFieldValue();
                List<DataDictionary> dictionaryList = dataDictionaryService.getByType(DataDictionaryTypeEnum.PERSON_TYPE.getCode());
                if (StringUtils.isNotBlank(fieldValue) && !CollectionUtils.isEmpty(dictionaryList)) {
                    Map<String, List<DataDictionary>> map = dictionaryList.stream().collect(Collectors.groupingBy(DataDictionary::getCode));
                    List<DataDictionary> list = map.get(fieldValue);
                    if (!CollectionUtils.isEmpty(list)) {
                        d.put("personType", list.get(0).getName());
                    }
                }
            }
        }
        return d;
    }
    @Override
    public DutyPersonDto update(Long instanceId, DutyPersonDto dutyPersonDto) {
        String groupCode = this.getGroupCode();
        //1.查询已有数据
        List<DynamicFormInstance> instances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
        //2.list 转 map
        Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(instances, "fieldCode", DynamicFormInstance.class);
        //3.查询列数据，已列为主
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        //页面数据转Map
        Map<String, Object> map = Bean.BeantoMap(dutyPersonDto);
        buildDataMap(map, dutyPersonDto.getUserId());
        //4.已列为主 填充动态表单数据
        List<DynamicFormInstance> entrys = new ArrayList<>();
        for (DynamicFormColumn column : columns) {
            DynamicFormInstance formInstance = instanceMap.get(column.getFieldCode());
            if (!ObjectUtils.isEmpty(formInstance)) {
                //有的更新
                formInstance.setFieldValue(map.get(column.getFieldCode()) != null ? map.get(column.getFieldCode()).toString() : "");
            } else {
                //没有的新增
                formInstance = new DynamicFormInstance();
                buildFormInstanceData(instanceId, map, column, formInstance);
            }
            entrys.add(formInstance);
        }
        if(!entrys.isEmpty()){
            dynamicFormInstanceService.saveOrUpdateBatch(entrys);
        }
        //5.更新值班信息人日期数据
        insertPersonShift(instanceId, dutyPersonDto);
        return dutyPersonDto;
    }

    private void insertPersonShift(Long instanceId, DutyPersonDto dutyPersonDto) {
        Set<DutyPersonShift> personShiftList = dutyPersonDto.getDutyShift().stream().map(dto -> {
            DutyPersonShift dutyPersonShift = new DutyPersonShift();
            dto.setInstanceId(instanceId);
            Bean.copyExistPropertis(dto, dutyPersonShift);
            dutyPersonShift.setAppKey(RequestContext.getAppKey());
            return dutyPersonShift;
        }).collect(Collectors.toSet());
        if (!personShiftList.isEmpty()) {
            dutyPersonShiftService.saveOrUpdateBatch(personShiftList);
        }
    }

    private void buildFormInstanceData(Long instanceId, Map<String, Object> map, DynamicFormColumn column, DynamicFormInstance formInstance) {
        fillFormInstanceData(instanceId, map, column, formInstance, sequence.nextId());
    }


    @Override
    public List<DutyPersonDto> findByDutyAreaId(Long dutyAreaId) {
        Date now = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY,0);
        c.set(Calendar.MINUTE,0);
        c.set(Calendar.SECOND,0);
        String beginDate = DateUtils.date2LongStr(c.getTime());
        c.setTime(now);
        c.add(Calendar.MONTH, 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.add(Calendar.DATE, -1);
        c.set(Calendar.HOUR_OF_DAY,23);
        c.set(Calendar.MINUTE,59);
        c.set(Calendar.SECOND,59);
        String endDate = DateUtils.date2LongStr(c.getTime());
        List<DutyPersonDto> temp = new ArrayList<>();
        dutyPersonShiftService.list(new LambdaQueryWrapper<DutyPersonShift>()
                        .ge(beginDate != null, DutyPersonShift::getDutyDate, beginDate)
                        .le(endDate != null, DutyPersonShift::getDutyDate, endDate).groupBy(DutyPersonShift::getInstanceId))
                .stream().forEach(e -> {
                    //1.查询已有数据
                    List<DynamicFormInstance> instances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, e.getInstanceId()).eq(DynamicFormInstance::getGroupCode,this.getGroupCode()));
                    if(instances.size() > 0) {
                        DutyPersonDto dto = new DutyPersonDto();
                        boolean add = false;
                        for(DynamicFormInstance t : instances) {
                            if("userId".equals(t.getFieldCode())) {
                                dto.setUserId(t.getFieldValue());
                            } else if(USERNAME.equals(t.getFieldCode())) {
                                dto.setUserName(t.getFieldValue());
                            } else if(DEPTID.equals(t.getFieldCode())) {
                                dto.setDeptId(t.getFieldValue());
                            } else if(DEPTNAME.equals(t.getFieldCode())) {
                                dto.setDeptName(t.getFieldValue());
                            } else if("postType".equals(t.getFieldCode())) {
                                dto.setPostType(t.getFieldValue());
                            } else if(POSTTYPENAME.equals(t.getFieldCode())) {
                                dto.setPostTypeName(t.getFieldValue());
                            } else if("dutyArea".equals(t.getFieldCode())) {
                                dto.setDutyArea(t.getFieldValue());
                            } else if("dutyAreaId".equals(t.getFieldCode())) {
                                if(dutyAreaId.toString().equals(t.getFieldValue())) {
                                    add = true;
                                }
                                dto.setDutyAreaId(t.getFieldValue());
                            }
                        }
                        if(add) {
                            temp.add(dto);
                        }
                    }
                });
        return temp;
    }
    
    
    
    
public Object BuildScheduleDetails(String dutyDay, Long shiftId, String postType) {
		
		List<Map<String, Object>> list = dayDutyPersonList(dutyDay, shiftId, postType);
		list.stream().forEach(i->{
			List<Object> fieldsList= new ArrayList<Object>();
			List<Object>infoList= new ArrayList<Object>();
			LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
			map.put("name", WXXFZ);
			map.put(VALUE,i.get(DEPTNAME).toString());
			map.put("id","1");
			fieldsList.add(map);
			map.clear();
			map.put("name", WXXFZ);
			map.put(VALUE,i.get(DEPTNAME).toString());
			
		});
		
	
		
		return postType;
	}
    


	@Override
    public   List<Map<String, Object>> queryByCompanyId(List<String> bizNames){
        return   dutyPersonShiftMapper.queryByCompanyId(bizNames);
    }

    @Override
    public   List<Map<String, Object>> queryByCompanyNew(String bizOrgName){
        return   dutyPersonShiftMapper.queryByCompanyNew(bizOrgName);
    }

    @Override
    public List<Map<String, Object>> dayDutyStatistics(String date, String groupCode, String fieldCode, String dictType) {
        return dutyPersonShiftMapper.dayDutyStatistics(date, groupCode, fieldCode, dictType);
    }

    @Override
    public List<Map<String, Object>> dayDutyList(String date, String dictCodes) {
        return dutyPersonShiftMapper.dayDutyList(date, dictCodes);
    }

    public Object getSchedulingDutyForSpecifyDate(String dutyDay, Long shiftId, String postType, String fieldCode) {
		List<Map<String, Object>> equipmentList = dutyPersonShiftMapper.getNewEquipmentForSpecifyDate(dutyDay,
				this.getGroupCode(), DEPTID, DEPTNAME, "result.deptId");
		if (equipmentList == null || equipmentList.size() < 1 || equipmentList.get(0) == null) {
			return null;
		}
		List<Object> detailList = new ArrayList<Object>();
		for (Map<String, Object> map : equipmentList) {
			List<Object> resultList = new ArrayList<Object>();
			LinkedHashMap<String, Object> titleMap_2 = new LinkedHashMap<String, Object>();
			if(map.containsKey(DEPTNAME) && map.get(DEPTNAME) != null){
				resultList.add( map.get(DEPTNAME).toString());
			}
			String carId = map.get(DEPTID).toString();
			Map<String, Object> instanceMap = dutyPersonShiftMapper.getInstanceIdForSpecifyDateAndEquipment(dutyDay,
					this.getGroupCode(), carId);
			if (instanceMap == null) {
				continue;
			}
			String instanceId = instanceMap.get("instanceIds").toString();
			if (StringUtils.isNotBlank(instanceId)) {
				String[] instanceIds = instanceId.split(",");

						// 获取当前装备ID下的排版数据
						List<Map<String, Object>> specifyDateList = dutyPersonShiftMapper
								.getPositionStaffDutyForSpecifyDate(dutyDay, this.getGroupCode(), instanceIds,
										null, fieldCode);
						if (specifyDateList == null || specifyDateList.size() < 1 || specifyDateList.get(0) == null) {
							continue;
						}
						for (Map<String, Object> specify : specifyDateList) {
							LinkedHashMap<String, Object> infoMap_2 = new LinkedHashMap<String, Object>();
							if( specify.containsKey(POSTTYPENAME)&& specify.get(POSTTYPENAME)!=null && specify.containsKey(USERNAME)&& specify.get(USERNAME)!=null ) {
								infoMap_2.put(specify.get(POSTTYPENAME).toString(),specify.get(USERNAME).toString());
								resultList.add(infoMap_2);
						}
				}
			}
			detailList.add(resultList);
		}
		return detailList;
	}
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
}
