package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.shkj.common.core.domain.Result;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.common.utils.StringUtils;
import com.shkj.wms.bo.BusinTaskThirdQueryBo;
import com.shkj.wms.domain.BusinTask;
import com.shkj.wms.enums.NumberPreEnum;
import com.shkj.wms.enums.TaskStatusEnum;
import com.shkj.wms.mapper.BusinTaskMapper;
import com.shkj.wms.service.IBusinTaskService;
import com.shkj.wms.service.ISysThirdExceptionRequestService;
import com.shkj.wms.utils.SnowflakeIdWorker;
import com.shkj.wms.vo.BusinTaskVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 作业任务Service业务层处理
 *
 * @author lch
 * @date 2023-02-27
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class BusinTaskServiceImpl extends ServiceImpl<BusinTaskMapper, BusinTask> implements IBusinTaskService {

    @Autowired
    private ISysThirdExceptionRequestService thirdExceptionRequestService;


    @Override
    public List<BusinTaskVo> queryList(BusinTaskThirdQueryBo bo) {
        LambdaQueryWrapper<BusinTask> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getTaskCode()), BusinTask::getTaskCode, bo.getTaskCode());
        lqw.eq(StrUtil.isNotBlank(bo.getOrderNo()), BusinTask::getOrderNo, bo.getOrderNo());
        lqw.eq(StrUtil.isNotBlank(bo.getStatus()), BusinTask::getStatus, bo.getStatus());
        lqw.eq(StrUtil.isNotBlank(bo.getType()), BusinTask::getType, bo.getType());
        lqw.eq(StrUtil.isNotBlank(bo.getWay()), BusinTask::getWay, bo.getWay());
        lqw.eq(BusinTask::getBranchId, SecurityUtils.getCurrentBranchId());
        lqw.ge(bo.getBeginDate() != null, BusinTask::getCreateTime, bo.getBeginDate());
        lqw.orderByDesc(BusinTask::getCreateTime);
        List<BusinTaskVo> voList = entity2Vo(this.list(lqw));
        return voList;

    }


    /**
     String code = taskService.addTask(pickD.getId(),
     pickD.getOrderNo(),
     BusinTaskTypeEnum.out.getValue(),
     Result.isOk(result) ? TaskStatusEnum.wait_callback.getValue() : TaskStatusEnum.err.getValue(),
     TaskWayEnum.CTU.getValue(),
     taskPath,
     pickD.getConsignorId(),
     pickD.getBranchId(),
     result.getMsg(),
     ThirdApiTypeEnum.essTaskDistribution);
     thirdExceptionRequestService.addException(code, ThirdApiTypeEnum.essTaskDistribution, JSONObject.toJSONString(dto), JSONObject.toJSONString(result), Result.isOk(result));
     *
     * */


    /**
     * 添加
     *
     * @param orderId
     * @param orderNo
     * @param type
     * @param status
     * @param way
     * @param taskPath
     * @param consignorId
     * @param branchId
     * @param taskType
     */

    @Override
    public String addTask(Long orderId, String orderNo, String type, String status, String way, String taskPath, Long consignorId, Long branchId, String msg, String taskType) {
        BusinTask businTask = new BusinTask();
        businTask.setTaskCode(NumberPreEnum.RW.getValue() + SnowflakeIdWorker.generateId().toString());
        businTask.setOrderId(orderId);
        businTask.setOrderNo(orderNo);
        businTask.setStatus(status);
        businTask.setType(type);
        businTask.setWay(way);
        businTask.setTaskPath(taskPath);
        businTask.setErrMsg(msg);
        businTask.setTaskType(taskType);
        businTask.setConsignorId(consignorId);
        businTask.setBranchId(branchId);
        this.save(businTask);
        return businTask.getTaskCode();
    }


    @Override
    public Result<Boolean> redistribution(String taskCode) throws Exception {
        LambdaQueryWrapper<BusinTask> eq = new LambdaQueryWrapper<BusinTask>()
                .eq(BusinTask::getTaskCode, taskCode);
        BusinTask one = getOne(eq);
        if (one == null) {
            return Result.err().msg("不存在任务信息");
        }
        if (!one.getStatus().equals(TaskStatusEnum.err.getValue())) {
            return Result.err().msg("该异常不能重复下发");
        }
        Result result;

        //重新着
        result = thirdExceptionRequestService.executeException(taskCode);
        if (!Result.isOk(result)) {
            return result;
        }
        // 注意这里是异常之后重新下发 如果是回调失败 那么这里需要另外处理
        one.setStatus(TaskStatusEnum.wait_callback.getValue());
        this.updateById(one);
        return Result.ok().msg("已重新下发");
    }


    @Override
    @Async
    public String updateStatus(Long orderId, String orderNo, String taskPath, String status, String msg, String taskType) {
        LambdaQueryWrapper<BusinTask> eq = new LambdaQueryWrapper<BusinTask>().eq(BusinTask::getOrderNo, orderNo)
                .eq(BusinTask::getOrderId, orderId)
                .ne(BusinTask::getStatus, status)
                .orderByDesc(BusinTask::getId)
                .last("limit 1");
        BusinTask one = getOne(eq);
        if (one == null) {
            log.error("不存在任务信息");
            return "";
        }
        one.setStatus(status);
        if (StringUtils.isNoneBlank(taskPath)) {
            one.setTaskPath(taskPath);
        }
        one.setErrMsg(msg);
        if (StringUtils.isNoneBlank(taskPath)) {
            one.setTaskPath(taskPath);
        }

        this.updateById(one);
        return one.getTaskCode();
    }


    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<BusinTaskVo> entity2Vo(Collection<BusinTask> collection) {
        List<BusinTaskVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, BusinTaskVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<BusinTask> page = (Page<BusinTask>) collection;
            Page<BusinTaskVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }


}
