package com.prolog.cs.biz.outbound.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.codingapi.tx.annotation.TxTransaction;
import com.google.common.collect.Sets;
import com.prolog.cs.biz.outbound.dao.MoveTaskMapper;
import com.prolog.cs.biz.outbound.dao.PickTaskDMapper;
import com.prolog.cs.biz.outbound.dao.PickTaskHMapper;
import com.prolog.cs.biz.outbound.enums.PickTaskDFLowStatus;
import com.prolog.cs.biz.outbound.model.PickTaskD;
import com.prolog.cs.biz.outbound.model.PickTaskH;
import com.prolog.cs.biz.outbound.model.entity.MoveTaskDO;
import com.prolog.cs.biz.outbound.service.RFPickTaskService;
import com.prolog.cs.biz.outbound.service.impl.eis.EisOutBoundHandler;
import com.prolog.entity.vo.OutBoundRequestItemVO;
import com.prolog.entity.vo.OutBoundRequestVO;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.authority.user.UserTemplate;
import com.prolog.framework.core.restriction.FieldSelector;
import com.prolog.framework.utils.MapUtils;
import com.prolog.upcloud.base.wh.operate.enums.ReplenishStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.prolog.cs.biz.outbound.model.constant.CacheKeyConstant.OUT_BOUND_REPLENISHMENT_REQUEST_WAVE_ID;

@Slf4j
@Service
public class RFPickTaskServiceImpl implements RFPickTaskService {
    @Resource
    private MoveTaskMapper moveTaskMapper;

    @Resource
    private PickTaskHMapper pickTaskHMapper;

    @Resource
    private UserTemplate userTemplate;

    @Resource
    private PickTaskDMapper pickTaskDMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private EisOutBoundHandler eisOutBoundHandler;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @TxTransaction
    public Object updateTasksUnshelveByReplenish(String[] ids, String status) {
        List<MoveTaskDO> moveTasks = moveTaskMapper.getReplenishTasksByIds(Arrays.asList(ids));
        Assert.notEmpty(moveTasks, "获取补货任务失败");
        UserDTO user = userTemplate.getUserDTO();
        if (null == user){
            user = new UserDTO();
            user.setId("EIS");
            user.setUsername("EIS");
            user.setNickname("EIS");
        }
        DateTime now = DateUtil.date();
        UserDTO finalUser = user;
        moveTasks.forEach(t -> {
            t.setStatus(status);
            t.setGmtModified(now);
            t.setModifier(finalUser.getId());
            t.setModifierName(finalUser.getNickname());
            moveTaskMapper.update(t);
        });
        log.info("当前同步的状态为{},ids = {}", status, ids);
        if (!"2".equals(status)) {
            return null;
        }

        //对于上架的，判断是否存在关联的出库任务，如果关联的出库任务下所有的补货任务均已完成，则更新状态从-1为0
        List<PickTaskH> hList = pickTaskHMapper.getTaskHdrsByReplenish(ids);
        if (hList == null || hList.size() <= 0 || hList.get(0) == null) {
            hList = pickTaskHMapper.getTaskHdrsByReplenishV2(ids);
            if(hList == null || hList.size() <= 0 || hList.get(0) == null){
                return null;
            }
        }
        log.info("关联的pickTaskH条数={}", hList.size());

        updateTaskStatusAndPushEis(ids, hList, user, now);

        return null;
    }

    private void updateTaskStatusAndPushEis(String[] ids, List<PickTaskH> hList, UserDTO user, DateTime now) {

        if (CollUtil.isEmpty(hList)) {
            return;
        }

        FieldSelector fs = FieldSelector.newInstance().include("flowStatus", "pickQty", "pickerId", "pickerName", "pickerNo", "pickTime", "gmtModified", "modifier", "modifierName");
        FieldSelector fs2 = FieldSelector.newInstance().include("status", "gmtModified", "modifier", "modifierName");
        Set<String> waveIds = Sets.newHashSet();
	    Set<String> billNos = Sets.newHashSet();
        for (PickTaskH pickTaskH : hList) {
            //判断是否存在还未上架的补货任务
            Integer unFinishReplenishTaskCnt = pickTaskHMapper.countReplenishUnFinishTask(pickTaskH.getPickTaskId(), Arrays.asList(ids));
            log.info("关联的pickTaskH未确认的补货任务数量为={}", unFinishReplenishTaskCnt);
            if (unFinishReplenishTaskCnt != 0) {
                continue;
            }

            List<PickTaskD> dList = pickTaskDMapper.findByMap(MapUtils.put("pickTaskId", pickTaskH.getPickTaskId()).getMap(), PickTaskD.class);
            if (CollUtil.isEmpty(dList)) {
                continue;
            }

            for (PickTaskD pickTask : dList) {
                pickTask.setFlowStatus(PickTaskDFLowStatus.TASK_CONFIRMED.getCode());
                pickTask.setPickQty(pickTask.getQty());
                pickTask.setPickerId(user.getId());
                pickTask.setPickerName(user.getUsername());
                pickTask.setPickerNo(user.getId());
                pickTask.setPickTime(now);
                pickTask.setGmtModified(now);
                pickTask.setModifier(user.getId());
                pickTask.setModifierName(user.getUsername());
                pickTaskDMapper.updateFields(pickTask, fs);
            }

            pickTaskH.setStatus("5");
            pickTaskH.setGmtModified(now);
            pickTaskH.setModifier(user.getId());
            pickTaskH.setModifierName(user.getUsername());
            pickTaskHMapper.updateFields(pickTaskH, fs2);

            waveIds.add(pickTaskH.getWaveId());
	        billNos.add(pickTaskH.getBillGroupId());
        }

        //完成补货任务后激活出库任务
//	    activatePickTask2Eis(waveIds, billNos);
    }

	public void activatePickTask2Eis(Set<String> waveIds, Set<String> billNos) {
        log.info("start_activatePickTask2Eis:{}", JSONObject.toJSONString(waveIds));
        //推送EIS出库任务
        waveIds.forEach(waveId -> {
            String key = OUT_BOUND_REPLENISHMENT_REQUEST_WAVE_ID + waveId;
            log.info("activatePickTask2Eis_key:{}", key);
            if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))) {
                String json = stringRedisTemplate.opsForValue().get(key);
	            log.info("activatePickTask2Eis_value:{}", json);
                List<OutBoundRequestVO> list = JSONObject.parseArray(json, OutBoundRequestVO.class);
	            if (CollUtil.isNotEmpty(list)) {
		            List<OutBoundRequestVO> current = getCurrentEisParamsByBillNos(billNos, list);
		            if (CollUtil.isNotEmpty(current)) {
			            eisOutBoundHandler.outBoundRequest(current);
		            }
		            updateCache(list, key);
	            }
            } else {
                log.error("activatePickTask2Eis:{}", "推送失败，缓存不存在出库任务");
            }
        });
        log.info("end_activatePickTask2Eis");
    }

	private void updateCache(List<OutBoundRequestVO> list, String key) {
		if (CollUtil.isEmpty(list)) {
			stringRedisTemplate.delete(key);
			log.info("key is empty,updateCache:{}", key);
			return;
		}

		String jsonString = JSONObject.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect);
		stringRedisTemplate.opsForValue().set(key, jsonString);
		log.info("updateCache_key:{},value:{}", key, jsonString);
	}

	private List<OutBoundRequestVO> getCurrentEisParamsByBillNos(Set<String> billNos, List<OutBoundRequestVO> list) {
		List<OutBoundRequestItemVO> allItems = list.stream().flatMap(s -> s.getSubList().stream()).collect(Collectors.toList());
//		List<OutBoundRequestItemVO> currentItem = allItems.stream().filter(t -> billNos.contains(t.getBillNo())).collect(Collectors.toList());
//		if (CollUtil.isEmpty(currentItem)) {
//			return null;
//		}
		OutBoundRequestVO head = list.get(0);
//		List<OutBoundRequestItemVO> remaining = CollUtil.subtractToList(allItems, currentItem);
//		OutBoundRequestVO obrv1 = new OutBoundRequestVO();
//		BeanUtil.copyProperties(head, obrv1);
//		obrv1.setMsgId(IdUtil.fastSimpleUUID());
//		obrv1.setSubList(remaining);
		list.clear();
//		list.add(obrv1);

		OutBoundRequestVO obrv2 = new OutBoundRequestVO();
		BeanUtil.copyProperties(head, obrv2);
		obrv2.setMsgId(IdUtil.fastSimpleUUID());
		obrv2.setSubList(allItems);
		return Collections.singletonList(obrv2);
	}

    @Override
    public List<MoveTaskDO> getReplenishListByPickTaskId(String pickTaskId, String status) {
        if (ReplenishStatus.OUT.getStatus().equals(status)) {
            return moveTaskMapper.getUnShelveReplenishUnshelveListByPickTaskId(pickTaskId, userTemplate.getUserDTO().getUserBizModel().getEmployeeNo());
        } else if (ReplenishStatus.IN.getStatus().equals(status)) {
            return moveTaskMapper.getPutAwayReplenishUnshelveListByPickTaskId(pickTaskId, userTemplate.getUserDTO().getUserBizModel().getEmployeeNo());
        }else {
            return moveTaskMapper.getMoveTaskByPickTaskId(pickTaskId, null);
        }
    }

}
