package org.nl.acs.task.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.nl.acs.ext.wms.service.AcsToWmsService;
import org.nl.acs.task.domain.TaskFeedback;
import org.nl.acs.task.service.TaskFeedbackService;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.dto.TaskDto;
import org.nl.acs.task.service.dto.TaskFeedbackDto;
import org.nl.acs.task.service.dto.TaskFeedbackQueryParam;
import org.nl.acs.task.service.mapper.TaskFeedbackMapper;
import org.nl.acs.common.base.PageInfo;
import org.nl.acs.common.base.QueryHelpMybatisPlus;
import org.nl.acs.common.base.impl.CommonServiceImpl;
import org.nl.common.exception.BadRequestException;
import org.nl.acs.utils.ConvertUtil;
import org.nl.common.utils.FileUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
* @author jiaolm
* @date 2023-05-09
*/
@Service
// @CacheConfig(cacheNames = TaskFeedbackService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TaskFeedbackServiceImpl extends CommonServiceImpl<TaskFeedbackMapper, TaskFeedback> implements TaskFeedbackService {

    // private final RedisUtils redisUtils;
    @Autowired
    TaskFeedbackMapper taskFeedbackMapper;
    @Autowired
    AcsToWmsService acstowmsService;
    @Autowired
    TaskService taskService;

    @Override
    public PageInfo<TaskFeedbackDto> queryAll(TaskFeedbackQueryParam query, Pageable pageable) {
        IPage<TaskFeedback> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<TaskFeedback> page = taskFeedbackMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, TaskFeedbackDto.class);
    }

    @Override
    public List<TaskFeedbackDto> queryAll(TaskFeedbackQueryParam query){
        return ConvertUtil.convertList(taskFeedbackMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), TaskFeedbackDto.class);
    }

    @Override
    public TaskFeedback getById(String id) {
        return taskFeedbackMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public TaskFeedbackDto findById(String id) {
        return ConvertUtil.convert(getById(id), TaskFeedbackDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(TaskFeedbackDto resources) {
        TaskFeedback entity = ConvertUtil.convert(resources, TaskFeedback.class);
        return taskFeedbackMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(TaskFeedbackDto resources){
        TaskFeedback entity = ConvertUtil.convert(resources, TaskFeedback.class);
        int ret = taskFeedbackMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids){
        // delCaches(ids);
        return taskFeedbackMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id){
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(String id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<String> ids) {
        for (String id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<TaskFeedbackDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (TaskFeedbackDto taskFeedback : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("任务标识", taskFeedback.getTaskId());
              map.put("任务号", taskFeedback.getTaskCode());
              map.put("载具号", taskFeedback.getVehicleCode());
              map.put("载具类型", taskFeedback.getVehicleType());
              map.put("任务类型", taskFeedback.getTaskType());
              map.put("任务状态", taskFeedback.getTaskStatus());
              map.put("是否完成", taskFeedback.getIsFinished());
              map.put("错误编码", taskFeedback.getErrorCode());
              map.put("开始时间", taskFeedback.getStartTime());
              map.put("完成时间", taskFeedback.getFinishTime());
              map.put("创建类型", taskFeedback.getCreateType());
              map.put("完成类型", taskFeedback.getFinishType());
              map.put("重试次数", taskFeedback.getRetryTimes());
              map.put("起始点位编码", taskFeedback.getStartPointCode());
              map.put("起始设备编码", taskFeedback.getStartDeviceCode());
              map.put("目标点位编码", taskFeedback.getNextPointCode());
              map.put("目标设备编码", taskFeedback.getNextDeviceCode());
              map.put("备注", taskFeedback.getRemark());
              map.put("是否启用", taskFeedback.getIsActive());
              map.put("是否删除", taskFeedback.getIsDelete());
              map.put("创建者", taskFeedback.getCreateBy());
              map.put("创建时间", taskFeedback.getCreateTime());
              map.put("修改者", taskFeedback.getUpdateBy());
              map.put("修改时间", taskFeedback.getUpdateTime());
              map.put("1-诺宝agv
2-叉车agv", taskFeedback.getAgvSystemType());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/

    @Override
    public Map<String, Object> queryAll(Map whereJson, Pageable page) {
        IPage<TaskFeedback> queryPage = PageUtil.toMybatisPage(page);
        LambdaQueryWrapper<TaskFeedback> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskFeedback::getIs_finished,"0");
        IPage<TaskFeedback> tfPage = taskFeedbackMapper.selectPage(queryPage,wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(tfPage, TaskFeedbackDto.class));
        return json;
    }

    @Override
    public List<TaskFeedbackDto> queryAll(Map whereJson) {
        List<TaskFeedback> insList= new LambdaQueryChainWrapper<>(taskFeedbackMapper)
                .list();
        return ConvertUtil.convertList(insList,TaskFeedbackDto.class);
    }

//    @Override
//    public TaskFeedbackDto findById(String taskback_id) {
//        WQLObject wo = WQLObject.getWQLObject("acs_task_feedback");
//        JSONObject json = wo.query("taskback_id ='" + taskback_id + "'").uniqueResult(0);
//        final TaskFeedbackDto obj =  json.toJavaObject(TaskFeedbackDto.class);
//        return obj;
//    }

    @Override
    public TaskFeedbackDto findByCode(String code) {
//        WQLObject wo = WQLObject.getWQLObject("acs_task_feedback");
//        JSONObject json = wo.query("task_code ='" + code + "' and is_finished='0' ").uniqueResult(0);
        TaskFeedback taskFeedback = new LambdaQueryChainWrapper<>(taskFeedbackMapper)
                .eq(TaskFeedback::getTask_code,code)
                .eq(TaskFeedback::getIs_finished,"0")
                .one();
        if (ObjectUtil.isEmpty(taskFeedback)){
            return null;
        }
        final TaskFeedbackDto obj = ConvertUtil.convert (taskFeedback,TaskFeedbackDto.class);
        return obj;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(TaskFeedbackDto dto) {
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();

        dto.setTaskback_id(IdUtil.simpleUUID());
        dto.setCreate_by(currentUsername);
        dto.setUpdate_by(currentUsername);
        dto.setUpdate_time(now);
        dto.setCreate_time(now);

//        WQLObject wo = WQLObject.getWQLObject("acs_task_feedback");
//        JSONObject json = (JSONObject) JSONObject.toJSON(dto);
//
//        wo.insert(json);

        TaskFeedback entity = ConvertUtil.convert(dto, TaskFeedback.class);
        taskFeedbackMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TaskFeedbackDto dto) {
        TaskFeedbackDto entity = this.findById(dto.getTaskback_id());
        if (entity == null) throw new BadRequestException("被删除或无权限，操作失败!");

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        dto.setUpdate_time(now);
        dto.setUpdate_by(currentUsername);

        TaskFeedback tf = ConvertUtil.convert(dto, TaskFeedback.class);
        taskFeedbackMapper.updateById(tf);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String[] ids) {
//        WQLObject wo = WQLObject.getWQLObject("acs_task_feedback");
        for (String taskback_id : ids) {
//            wo.delete("taskback_id = '" + taskback_id + "'");
            taskFeedbackMapper.deleteById(taskback_id);
        }
    }

    @Override
    public void download(List<TaskFeedbackDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TaskFeedbackDto taskFeedback : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("任务标识", taskFeedback.getTask_id());
            map.put("任务号", taskFeedback.getTask_code());
            map.put("载具号", taskFeedback.getVehicle_code());
            map.put("载具类型", taskFeedback.getVehicle_type());
            map.put("任务类型", taskFeedback.getTask_type());
            map.put("任务状态", taskFeedback.getTask_status());
            map.put("是否完成", taskFeedback.getIs_finished());
            map.put("错误编码", taskFeedback.getError_code());
            map.put("开始时间", taskFeedback.getStart_time());
            map.put("完成时间", taskFeedback.getFinish_time());
            map.put("创建类型", taskFeedback.getCreate_type());
            map.put("完成类型", taskFeedback.getFinish_type());
            map.put("重试次数", taskFeedback.getRetry_times());
            map.put("起始点位编码", taskFeedback.getStart_point_code());
            map.put("起始设备编码", taskFeedback.getStart_device_code());
            map.put("目标点位编码", taskFeedback.getNext_point_code());
            map.put("目标设备编码", taskFeedback.getNext_device_code());
            map.put("备注", taskFeedback.getRemark());
            map.put("是否启用", taskFeedback.getIs_active());
            map.put("是否删除", taskFeedback.getIs_delete());
            map.put("创建者", taskFeedback.getCreate_by());
            map.put("创建时间", taskFeedback.getCreate_time());
            map.put("修改者", taskFeedback.getUpdate_by());
            map.put("修改时间", taskFeedback.getUpdate_time());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void retry(String id) {
        TaskFeedbackDto dto = this.findById(id);
        TaskDto entity = taskService.findById(dto.getTask_id());
        JSONObject feed_jo = new JSONObject();
        feed_jo.put("task_id", entity.getTask_id());
        feed_jo.put("task_code", entity.getTask_code());
        feed_jo.put("task_status", entity.getTask_status());
        JSONArray ja = new JSONArray();
        ja.add(feed_jo);
        HttpResponse body = null;
        String error_message = null;
        try {
            body = acstowmsService.feedbackTaskStatusToWms(ja);
        } catch (Exception e) {
            error_message = e.getMessage();
            e.printStackTrace();
        }
        int status = body.getStatus();

        dto.setTask_status(entity.getTask_status());
        if (status == 200) {
            dto.setIs_finished("1");
            dto.setError_code("200");
            dto.setRemark("");
        } else {
            dto.setRemark(error_message);
            dto.setRetry_times(Integer.parseInt(dto.getRetry_times()) + 1 + "");
        }
        this.update(dto);

    }

    @Override
    public void invalid(String id) {
        TaskFeedbackDto entity = this.findById(id);
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        entity.setUpdate_time(now);
        entity.setUpdate_by(currentUsername);
        entity.setIs_finished("1");
        TaskFeedback tf = ConvertUtil.convert(entity, TaskFeedback.class);
        taskFeedbackMapper.updateById(tf);
    }
}
