/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.youchain.businessdata.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.youchain.businessdata.domain.AgvTask;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import com.youchain.businessdata.repository.AgvTaskRepository;
import com.youchain.businessdata.service.AgvTaskService;
import com.youchain.businessdata.service.dto.AgvTaskDto;
import com.youchain.businessdata.service.dto.AgvTaskQueryCriteria;
import com.youchain.businessdata.service.mapstruct.AgvTaskMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
 * @author baobinglin
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-08-18
 **/
@Service
@RequiredArgsConstructor
public class AgvTaskServiceImpl implements AgvTaskService {

    private final AgvTaskRepository agvTaskRepository;
    private final AgvTaskMapper agvTaskMapper;

    @Override
    public Map<String, Object> queryAll(AgvTaskQueryCriteria criteria, Pageable pageable) {
        Page<AgvTask> page = agvTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(agvTaskMapper::toDto));
    }

    @Override
    public List<AgvTaskDto> queryAll(AgvTaskQueryCriteria criteria) {
        return agvTaskMapper.toDto(agvTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public AgvTaskDto findById(Integer id) {
        AgvTask agvTask = agvTaskRepository.findById(id).orElseGet(AgvTask::new);
        ValidationUtil.isNull(agvTask.getId(), "AgvTask", "id", id);
        return agvTaskMapper.toDto(agvTask);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AgvTaskDto create(AgvTask resources) {
        return agvTaskMapper.toDto(agvTaskRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(AgvTask resources) {
        AgvTask agvTask = agvTaskRepository.findById(resources.getId()).orElseGet(AgvTask::new);
        ValidationUtil.isNull(agvTask.getId(), "AgvTask", "id", resources.getId());
        agvTask.copy(resources);
        agvTaskRepository.save(agvTask);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            agvTaskRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<AgvTaskDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AgvTaskDto agvTask : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("容器码", agvTask.getStockCode());
            map.put("容器类型", agvTask.getStockTypeCode());
            map.put("起点位置", agvTask.getStartSlotCode());
            map.put("终点位置", agvTask.getEndSlotCode());
            map.put("容器当前位置", agvTask.getSlotCode());
            map.put("任务状态", agvTask.getStatus());
            map.put("任务类型", agvTask.getType());
            map.put("下游任务号", agvTask.getJobId());
            map.put("工作类型", agvTask.getJobType());
            map.put("优先级", agvTask.getJobPriority());
            map.put("强制优先级", agvTask.getJobPriorityType());
            map.put("任务组", agvTask.getJobForce());
            map.put("任务组执行顺序", agvTask.getJobForceAsc());
            map.put("返回报文", agvTask.getJobMessage());
            map.put("变动时间", agvTask.getJobMessageTime());
            map.put("创建时间", agvTask.getCreateTime());
            map.put("开始时间", agvTask.getStartTime());
            map.put("完成时间", agvTask.getEndTime());
            map.put("创建人", agvTask.getCreateBy());
            map.put("修改人", agvTask.getUpdateBy());
            map.put("修改时间", agvTask.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * @param agvTasks
     * @return
     */
    @Override
    public String sendAgvTaskImpl(List<AgvTask> agvTasks) {

        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());

        Map<String, Object> objMap = new LinkedHashMap<>();
        objMap.put("orgId", "127");//库存组织 ID(或工厂代码，供应商代码)
        objMap.put("reqCode", agvTasks.get(0).getId());//请求 id
        objMap.put("taskCode", agvTasks.get(0).getId());//任务编号
        objMap.put("missionType", "01");//任务类型 01：料箱

        JSONArray missionDataArray = new JSONArray();
        for (int i = 0; i < agvTasks.size(); i++) {
            AgvTask agvTask = agvTasks.get(i);
            JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
            Map<String, Object> missionDataMap = new LinkedHashMap<>();
            missionDataMap.put("podCode", agvTask.getStockCode());//容器编码
            missionDataMap.put("priority", "1");//1~99(数值越小，优先级 越高)
            missionDataMap.put("startNode", agvTask.getStartSlotCode());//取料箱点位
            missionDataMap.put("startSlotCode", agvTask.getSlotCode());//料箱当前放置的货位码
            missionDataMap.put("takeActionConfirm", false);//取料箱时之前是否需要确认
            missionDataMap.put("endNode", agvTask.getEndSlotCode());//放料箱点位
            missionDataMap.put("endSlotCode", "1-001");//料箱放置的目标货位码
            missionDataMap.put("putActionConfirm", false);//放料箱时之前是否需要确认
            missionDataObj.putAll(missionDataMap);
            missionDataArray.add(missionDataObj);
        }

        objMap.put("missionData", missionDataArray);
        jsonObject.putAll(objMap);
        System.out.println(jsonObject.toString());

        /*  String resultJson= HttpPostUtil.sendPostReq(UrlApi.agv_url, jsonObject.toString());//返回ResponseJson*/
        String resultJson = "{\n" +
                "\"code\":\"0\",\n" +
                "\"message\":\"\",\n" +
                "\"success\":true,\n" +
                "\"data\":\"\"\n" +
                "}";
        JSONObject resulObject = JSON.parseObject(resultJson);
        String code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
        if (code.equals("0")) {
            for (int i = 0; i < agvTasks.size(); i++) {
                AgvTask agvTask = agvTasks.get(i);
                agvTask.setJobForce(agvTasks.get(0).getId().toString());//任务组
                agvTask.setJobForceAsc((i + 1));
                agvTask.setStatus(BizStatus.ATWORK);
                agvTask.setJobMessage(resultJson);
                update(agvTask);
            }
        } else {
            for (int i = 0; i < agvTasks.size(); i++) {
                AgvTask agvTask = agvTasks.get(i);
                agvTask.setJobMessage(resultJson);
                update(agvTask);
            }
        }
        return resultJson;
    }

    @Override
    public void getConveyorState(String conveyorId) {
        /*  String resultJson= HttpPostUtil.sendPostReq(UrlApi.agv_url, jsonObject.toString());//返回ResponseJson*/
        String resultJson = "{\n" +
                "\"success\":true,\n" +
                "\"code\":200,\n" +
                "\"message\":\"\",\n" +
                "\"conveyorId\":\"1\",\n" +
                "\"state\":\"1\"\n" +
                "}";
        JSONObject resulObject = JSON.parseObject(resultJson);
        String code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
        if (code.equals("200")) {
            /**
             * state
             * 1：允许取货
             * 2：允许放货
             * 3、不允许取货
             * 4、不允许放货
             */
            String state = resulObject.getString("state") == null ? "" : resulObject.getString("state");
            if (state.equals("1")) {

            } else if (state.equals("2")) {

            } else if (state.equals("3")) {

            } else if (state.equals("4")) {

            }
        }

    }

    public AgvTask toEntity(AgvTaskDto agvTaskDto) {
        return agvTaskMapper.toEntity(agvTaskDto);
    }

    @Override
    public void agvTaskCallback(AgvTask agvTask, String status) {
        if (status.equals("PICKER_RECEIVE")) {
            //取料箱
        } else if (status.equals("PICKER_SEND")) {
            //取料箱
        } else if (status.equals("COMPLETED")) {
            agvTask.setStatus(BizStatus.FINISH);
            update(agvTask);
            //任务完成
        } else if (status.equals("CANCELED")) {
            //任务取消完成
        }
    }
}