package com.prolog.cs.base.gsp.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.prolog.cs.base.gsp.QueryDTO;
import com.prolog.cs.base.gsp.dao.GspUpkeepCheckPlanMapper;
import com.prolog.cs.base.gsp.model.GspUpkeepCheckPlan;
import com.prolog.cs.base.gsp.resource.ChainClient;
import com.prolog.cs.base.gsp.resource.WarehouseClient;
import com.prolog.cs.base.gsp.service.GspUpkeepCheckPlanService;
import com.prolog.cs.base.gsp.utils.RestMsgHelper;
import com.prolog.cs.basic.chain.model.cargo.BaseCargoOwnerMst;
import com.prolog.cs.basic.warehouse.model.BaseWmsWarehouseMst;
import com.prolog.cs.basic.warehouse.model.dto.WmsWhBldgDTO;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.authority.user.UserTemplate;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.framework.utils.ObjectUtils;
import com.prolog.framework.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class GspUpkeepCheckPlanServiceImpl implements GspUpkeepCheckPlanService {

    @Autowired
    private GspUpkeepCheckPlanMapper upkeepCheckPlanMapper;

    @Autowired
    private UserTemplate userTemplate;

    @Autowired
    private WarehouseClient warehouseClient;

    @Autowired
    private ChainClient chainClient;

    @Override
    public List<GspUpkeepCheckPlan> spellGspUpkeepCheckPlans(List<GspUpkeepCheckPlan> list) {
        //转换并组装
        //组合id
        String[] cargoOwnerIds = list.stream().map(GspUpkeepCheckPlan::getCargoOwnerId).distinct().toArray(String[]::new);
        //请求货位信息
        RestMessage<Map<String, BaseCargoOwnerMst>> cargoOwnerResult = chainClient.getCargoOwnerMstByIds(cargoOwnerIds);
        List<GspUpkeepCheckPlan> listRet = new ArrayList<>();
        // 获取所有仓库信息 - by Huanglh 2022-02-10
        Map<String, BaseWmsWarehouseMst> warehouseMstMap = new HashMap<>();
        Set<String> warehouseIds = list.stream().map(GspUpkeepCheckPlan::getWarehouseId).collect(Collectors.toSet());
        RestMessage<Map<String, BaseWmsWarehouseMst>> restMessage = warehouseClient.mapbyids(warehouseIds);
        if (restMessage.isSuccess() && ObjectUtils.isNotNull(restMessage.getData())) {
            warehouseMstMap = restMessage.getData();
        }
        String warehouseName = "";
        for (int i = 0; i < list.size(); i++) {
            GspUpkeepCheckPlan gspUpkeepCheckD = list.get(i);
            if (i == 0) {
                // 将循环调用接口改为循环外一次查所有后 Map 匹配 - by Huanglh 2022-02-10
                if (warehouseMstMap.containsKey(gspUpkeepCheckD.getWarehouseId())) {
                    warehouseName = warehouseMstMap.get(gspUpkeepCheckD.getWarehouseId()).getWarehouseName();
                }
            }
            GspUpkeepCheckPlan gspUpkeepCheckVO = new GspUpkeepCheckPlan();
            BeanUtils.copyProperties(gspUpkeepCheckD, gspUpkeepCheckVO);
            if (cargoOwnerResult != null) {
                Map<String, BaseCargoOwnerMst> data = cargoOwnerResult.getData();
                if (data != null && data.get(gspUpkeepCheckD.getCargoOwnerId()) != null) {
                    gspUpkeepCheckVO.setCargoOwnerName(data.get(gspUpkeepCheckD.getCargoOwnerId()).getCargoOwnerName());
                }
            }
            listRet.add(gspUpkeepCheckVO);

            gspUpkeepCheckVO.setWarehouseName(warehouseName);
            //gspUpkeepCheckVO.setBldgName("曲靖康桥仓");
        }
        return listRet;
    }

    @Override
    public Page<GspUpkeepCheckPlan> findPlan(QueryDTO dto) {

        init4FindPlan(dto);
        dto.setType("1");

        PageUtils.startPage(dto.getPageNum(), dto.getPageSize());
        List<GspUpkeepCheckPlan> list = upkeepCheckPlanMapper.findList(dto);

        if (CollUtil.isEmpty(list)) {
            return PageUtils.getPage(list);
        }

        packResult4FindPlan(list);
        return PageUtils.getPage(list);
    }

    private void packResult4FindPlan(List<GspUpkeepCheckPlan> list) {
        Map<String, WmsWhBldgDTO> bldMaps = Maps.newHashMap();
        String[] bldgIds = list.stream().map(GspUpkeepCheckPlan::getBldgId).filter(StrUtil::isNotBlank).distinct().toArray(String[]::new);
        if (bldgIds.length > 0) {
            List<WmsWhBldgDTO> bldgDTOList = RestMsgHelper.unpack(warehouseClient.getBldgBasicInfoList(bldgIds));
            if (CollUtil.isNotEmpty(bldgDTOList)) {
                bldMaps = bldgDTOList.stream().collect(Collectors.toMap(WmsWhBldgDTO::getBldgId, entity -> entity));
            }
        }
        String[] cargoOwnerIds = list.stream().map(GspUpkeepCheckPlan::getCargoOwnerId).distinct().toArray(String[]::new);
        Map<String, BaseCargoOwnerMst> cargoOwnerMaps = Maps.newHashMap();
        if (cargoOwnerIds.length > 0) {
            cargoOwnerMaps = RestMsgHelper.unpack(chainClient.getCargoOwnerMstByIds(cargoOwnerIds));
        }
        Map<String, BaseWmsWarehouseMst> warehouseMstMap = new HashMap<>();
        Set<String> warehouseIds = list.stream().map(GspUpkeepCheckPlan::getWarehouseId).collect(Collectors.toSet());
        if (warehouseIds.size() > 0) {
            warehouseMstMap = RestMsgHelper.unpack(warehouseClient.mapbyids(warehouseIds));
        }

        DateTime now = DateUtil.date();
        UserDTO user = userTemplate.getUserDTO();
        for (GspUpkeepCheckPlan plan : list) {
            plan.setUpkeepTypeDesc(spellUpkeepType(plan.getUpkeepType()));
            Optional.ofNullable(bldMaps.get(plan.getBldgId())).ifPresent(t -> plan.setBldgName(t.getBldgName()));
            Optional.ofNullable(cargoOwnerMaps.get(plan.getCargoOwnerId())).ifPresent(t -> plan.setCargoOwnerName(t.getCargoOwnerName()));
            Optional.ofNullable(warehouseMstMap.get(plan.getWarehouseId())).ifPresent(t -> plan.setWarehouseName(t.getWarehouseName()));
            plan.setPrintDate(now);
            plan.setOperBy(user.getNickname());
        }
    }

    private void init4FindPlan(QueryDTO dto) {
        UserDTO user = userTemplate.getUserDTO();
        dto.initialPageWhenValueIsNull(user);
        dto.setEnterpriseId(user.getEnterpriseId());
        if (dto.getEndTime() != null) {
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(dto.getEndTime());
            calendar.add(Calendar.DATE, 1);//1表示明天,-1表示昨天
            dto.setEndTime(calendar.getTime());//这个时间就是第二天
        }
    }

    @Override
    public List<GspUpkeepCheckPlan> findUpkeepPlan4MovePick(QueryDTO upkeepCheckDTO) {
        upkeepCheckDTO.setType("2");
        String warehouseName = getWarehouseName(upkeepCheckDTO.getWarehouseId());
        String cargoOwnerName = getCargoOwnerName(upkeepCheckDTO.getCargoOwnerId());
        List<GspUpkeepCheckPlan> planList = upkeepCheckPlanMapper.findList(upkeepCheckDTO);
        String[] cargoOwnerIds = planList.stream().map(GspUpkeepCheckPlan::getCargoOwnerId).distinct().toArray(String[]::new);
        RestMessage<Map<String, BaseCargoOwnerMst>> result = chainClient.getCargoOwnerMstByIds(cargoOwnerIds);

        for (int i = 0; i < planList.size(); i++) {
            GspUpkeepCheckPlan upkeepCheckPlan = planList.get(i);
            upkeepCheckPlan.setWarehouseName(warehouseName);
            if (result.isSuccess() && result.getData() != null) {
                BaseCargoOwnerMst baseCargoOwnerMst = result.getData().get(upkeepCheckPlan.getCargoOwnerId());
                if (baseCargoOwnerMst != null) {
                    upkeepCheckPlan.setCargoOwnerName(baseCargoOwnerMst.getCargoOwnerName());
                }
            }
        }
        return planList;
    }

    @Override
    public String spellUpkeepType(Integer upkeepType) {
        if (upkeepType != null) {
            //类型：0=未分类 1=重点特殊药品，2=重点专管药品，3=重点其他药品，4=重点医疗器械，
            // 5=重点非药品，6=一般药品，7=一般器械，8=一般非药品
            if (upkeepType == 1)
                return "重点特殊药品";
            if (upkeepType == 2)
                return "重点专管药品";
            if (upkeepType == 3)
                return "重点其他药品";
            if (upkeepType == 4)
                return "重点医疗器械";
            if (upkeepType == 5)
                return "重点非药品";
            if (upkeepType == 6)
                return "一般药品";
            if (upkeepType == 7)
                return "一般器械";
            if (upkeepType == 8)
                return "一般非药品";
        }
        return null;
    }

    //请求仓库信息
    private String getWarehouseName(String warehouseId) {
        if (StringUtils.isBlank(warehouseId)) {
            return null;
        }
        RestMessage<BaseWmsWarehouseMst> itemResultWarehouse = warehouseClient.warehouse(warehouseId);
        if (itemResultWarehouse.isSuccess() && itemResultWarehouse.getData() != null) {
            return itemResultWarehouse.getData().getWarehouseName();
        }
        return null;
    }

    //请求货主信息
    private String getCargoOwnerName(String warehouseId) {
        if (StringUtils.isBlank(warehouseId)) {
            return null;
        }
        RestMessage<Map<String, BaseCargoOwnerMst>> result = chainClient.getCargoOwnerMstByIds(new String[]{warehouseId});
        if (result.isSuccess() && result.getData() != null) {
            return result.getData().get(warehouseId).getCargoOwnerName();
        }
        return null;
    }
}
