package com.zehong.system.service.impl.shelf;

import com.alibaba.fastjson.JSONObject;
import com.zehong.common.exception.CustomException;
import com.zehong.common.utils.SecurityUtils;
import com.zehong.common.utils.StringUtils;
import com.zehong.common.utils.http.HttpClientUtils;
import com.zehong.system.domain.material.TRackMaterialRelation;
import com.zehong.system.domain.shelf.TShelfInfo;
import com.zehong.system.domain.shelf.TShelfStorageLocation;
import com.zehong.system.mapper.material.TRackMaterialRelationMapper;
import com.zehong.system.mapper.shelf.TShelfInfoMapper;
import com.zehong.system.mapper.shelf.TShelfStorageLocationMapper;
import com.zehong.system.service.impl.shelf.annotation.DockingTaskType;
import com.zehong.system.service.impl.shelf.annotation.PlatformDockingTaskLog;
import com.zehong.system.service.impl.shelf.annotation.SendNotification;
import com.zehong.system.service.shelf.ITShelfApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 货架第三方接口
 */
@Service
public class ITShelfApiServiceImpl implements ITShelfApiService{

    private static final Logger log = LoggerFactory.getLogger(ITShelfApiServiceImpl.class);

    @Resource
    private TShelfStorageLocationMapper shelfStorageLocationMapper;

    @Resource
    private TShelfInfoMapper shelfInfoMapper;

    @Resource
    private TRackMaterialRelationMapper rackMaterialRelationMapper;

    /**
     * 获取料架状态接口
     */
    private final static String RACK_STATUS_URL = "/api/TyChargingData/RackStatus";

    /**
     * 料架出入库接口
     */
    private final static String RACK_IN_OUT_PUT_URL = "/api/TyChargingData/RackInOutput";

    /**
     * 获取料架所有储位信息
     */
    private final static String LOOK_ALL_LOCATION_URL = "/api/TyChargingData/LookAllLocation";

    @Value("${shelf.apiUrl}")
    private String shelfApiUrl;

    /**
     * 获取料架状态
     * @param param 请求参数
     */
    @Override
    public JSONObject getRackStatus(String param) {
        log.info("getRackStatus...params==========" + param);
        String result = HttpClientUtils.doPost(shelfApiUrl + RACK_STATUS_URL,param,null);
        if(StringUtils.isEmpty(result)) throw new CustomException("获取料架状态信息失败");
        return JSONObject.parseObject(result);
    }


    /**
     * 料架出库入库接口
     * @param param 入参
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @PlatformDockingTaskLog(type = DockingTaskType.CALL_RACK_SYSTEM)
    public void rackInOutput(String param){
        log.info("rackInOutput...param==========" + param);
        JSONObject paramJson = JSONObject.parseObject(param);
        if(paramJson.containsKey("relationParam")){
            // 入库
            addRelationInfo(paramJson.getJSONObject("relationParam"));
            String result = HttpClientUtils.doPost(shelfApiUrl + RACK_IN_OUT_PUT_URL,paramJson.getString("inStoreParam"),null);
            if(StringUtils.isEmpty(result)) throw new CustomException("料架出入库接口错误");
            JSONObject resultJson = JSONObject.parseObject(result);
            if("1".equals(resultJson.getString("FLAG"))) throw new CustomException("料架入库失败" + resultJson.getString("MESSAGE"));
        }else{
            //出库
            delRelationInfo(JSONObject.parseObject(param));
            String result = HttpClientUtils.doPost(shelfApiUrl + RACK_IN_OUT_PUT_URL,param,null);
            if(StringUtils.isEmpty(result)) throw new CustomException("料架出入库接口错误");
            JSONObject resultJson = JSONObject.parseObject(result);
            if("1".equals(resultJson.getString("FLAG"))) throw new CustomException("料架出库失败" + resultJson.getString("MESSAGE"));
        }
    }

    /**
     * 新增关联入库信息
     * @param param 关联信息
     */
    private void addRelationInfo(JSONObject param){
        List<TRackMaterialRelation> tRackMaterialRelations = rackMaterialRelationMapper.selectByRockCode(param.getString("rackCode"));
        if(tRackMaterialRelations.size() > 0){
            TRackMaterialRelation tRackMaterialRelation = tRackMaterialRelations.get(0);
            tRackMaterialRelation.setUpdateTime(new Date());
            tRackMaterialRelation.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
            tRackMaterialRelation.setMaterialId(param.getLong("materialId"));
            tRackMaterialRelation.setRackCode(param.getString("rackCode"));
            tRackMaterialRelation.setShelf(param.getString("shelf"));
            rackMaterialRelationMapper.updateTRackMaterialRelation(tRackMaterialRelation);
        } else {
            TRackMaterialRelation tRackMaterialRelation = new TRackMaterialRelation();
            tRackMaterialRelation.setMaterialId(param.getLong("materialId"));
            tRackMaterialRelation.setRackCode(param.getString("rackCode"));
            tRackMaterialRelation.setCreateTime(new Date());
            tRackMaterialRelation.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
            tRackMaterialRelation.setShelf(param.getString("shelf"));
            int result = rackMaterialRelationMapper.insertTRackMaterialRelation(tRackMaterialRelation);
            if(result == 0) throw new CustomException("入库料盘物料信息关联失败");
        }
    }

    /**
     * 解除入库关联信息
     * @param param 位置信息
     */
    private void delRelationInfo(JSONObject param){
        List<JSONObject> locationInfo =  param.getJSONArray("TOTALINFO").toJavaList(JSONObject.class);
        String[] rockCodes = locationInfo.stream()
                .map(json -> json.getString("RID"))
                .filter(Objects::nonNull)
                .toArray(String[]::new);

        int result = rackMaterialRelationMapper.deleteTRackMaterialRelationByRackCodes(rockCodes);
        if(result == 0) throw new CustomException("入库料盘物料信息解除失败");
    }
    /**
     * 获取料架所有储位信息
     * @param param 请求参数
     */
    @Override
    public JSONObject lookAllLocation(String param){
        log.info("lookAllLocation...param==========" + param);
        String result = HttpClientUtils.doPost(shelfApiUrl + LOOK_ALL_LOCATION_URL,param,null);
        if(StringUtils.isEmpty(result)) throw new CustomException("获取料架所有储位信息错误");
        return JSONObject.parseObject(result);
    }


    /**
     * 获取储出储成功后反馈
     * @param request 入参
     */
    @Override
    @SendNotification
    @PlatformDockingTaskLog(type = DockingTaskType.RECEIVE_RACK_SYSTEM_INFO)
    @Transactional(rollbackFor = Exception.class)
    public JSONObject receiveFeedBackInfo(JSONObject request) {
        log.info("receiveFeedBackInfo...param==========" + request.toJSONString());
        try {
            JSONObject result = new JSONObject();
            TShelfInfo shelfInfo = shelfInfoMapper.selectTShelfInfoByShelf(request.getString("shelf"));
            request.put("shelfId",shelfInfo.getfShelfId());
            //更新位置状态
            TShelfStorageLocation tShelfStorageLocation = new TShelfStorageLocation();
            tShelfStorageLocation.setLocation(request.getString("location"));
            tShelfStorageLocation.setShelfId(shelfInfo.getfShelfId());
            if("I".equals(request.getString("optype"))){
                tShelfStorageLocation.setInboundTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(request.getString("operateDate")));
                tShelfStorageLocation.setRid(request.getString("rid"));
                //查询物料信息
                TRackMaterialRelation materialInfo = rackMaterialRelationMapper.selectTRackMaterialRelationByRackCode(request.getString("rid"));
                request.put("materialCode",materialInfo.getMaterialCode());
                request.put("materialName",materialInfo.getMaterialName());
                request.put("materialSpecifications",materialInfo.getMaterialSpecifications());
            }
            if("O".equals(request.getString("optype"))){
                tShelfStorageLocation.setOutboundTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(request.getString("operateDate")));
            }
            shelfStorageLocationMapper.updateTShelfStorageLocationByLocationAndShelfId(tShelfStorageLocation);
            result.put("FLAG","0");
            result.put("MESSAGE","");
            result.put("ERRORCODE","");
            return result;
        } catch (ParseException e) {
            throw new CustomException("储出储成功后反馈接口错误",e);
        }
    }
}
