package com.sckw.mine.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.page.PageRes;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.utils.TenantUtil;
import com.sckw.core.web.response.HttpResult;
import com.sckw.mine.common.OrderServerCommon;
import com.sckw.mine.entity.*;
import com.sckw.mine.entity.dto.NodeStatusDTO;
import com.sckw.mine.entity.req.CompleteOrderParam;
import com.sckw.mine.entity.req.MineOrderPageListParam;
import com.sckw.mine.entity.req.MineAddParam;
import com.sckw.mine.entity.res.MineOrderDetailRes;
import com.sckw.mine.entity.res.MineOrderPageListRes;
import com.sckw.mine.enums.MineStatusEnum;
import com.sckw.mine.enums.TransportUnderEnum;
import com.sckw.mine.mapper.*;
import com.sckw.redis.utils.RedissonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @desc:
 * @author: Lt
 * @date: 2024-05-27
 */
@Service
public class MineService {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    @Autowired
    MineOrderMapper mineOrderMapper;

    @Autowired
    TransportOrderNoMapper transportOrderNoMapper;

    @Autowired
    MineMapper mineMapper;

    @Autowired
    KwBusinessActionTrackMapper kwBusinessActionTrackMapper;

    @Autowired
    OrderServerCommon orderServerCommon;

    @Autowired
    NodeMapper nodeMapper;

    @Autowired
    WorkFlowNodeMapper workFlowNodeMapper;

    /**
     * @Description: 矿山域订单添加
     * @Author: Lt
     * @Date: 2024/5/27 9:43
     */
    public String mineOrderAdd(MineAddParam mineAddParam) throws Exception {
        try {
            Long orderId = new IdWorker(1L).nextId();
            KwBusinessMineOrder kwBusinessMineOrder = BeanUtil.copyProperties(mineAddParam, KwBusinessMineOrder.class);
            //生成订单编号
            String mineOrderNo = orderServerCommon.generatorNum("M", 13);

            //生成物流订单编号- 空了再来封装了
            String usualTransportOrderNo = orderServerCommon.generatorNum("O", 12);
            kwBusinessMineOrder.setId(orderId);
            kwBusinessMineOrder.setMineOrderNo(mineOrderNo);
            kwBusinessMineOrder.setTenantId(TenantUtil.getTenant());   //租户id
            kwBusinessMineOrder.setMineralAggregateId(mineAddParam.getMineralAggregateId());
            kwBusinessMineOrder.setOrderSource(1);
            int insert = mineOrderMapper.insert(kwBusinessMineOrder);
            if (insert > 0) {
                //生成kw_business_transport_order_no
                //如果是自有物流生成物流订单号
                if (mineAddParam.getIsTransport().equals(TransportUnderEnum.ONE.getCode())) {
                    KwBusinessTransportOrderNo kwBusinessTransportOrderNo = new KwBusinessTransportOrderNo();
                    kwBusinessTransportOrderNo.setId(new IdWorker(1L).nextId());
                    kwBusinessTransportOrderNo.setMineOrderId(orderId);
                    kwBusinessTransportOrderNo.setTransportOrderNo(usualTransportOrderNo);
                    transportOrderNoMapper.insert(kwBusinessTransportOrderNo);
                }
                KwBusinessMine kwBusinessMine = new KwBusinessMine();
                kwBusinessMine.setId(new IdWorker(1L).nextId());
                kwBusinessMine.setMineOrderId(orderId);
                kwBusinessMine.setMineVol(mineAddParam.getMineVol());
                kwBusinessMine.setMineWeight(mineAddParam.getMineWeight());
                kwBusinessMine.setPurchaseNum(mineAddParam.getPurchaseNum());
                mineMapper.insert(kwBusinessMine);
            }
            //添加操作记录
            orderServerCommon.saveActionTrack(orderId, String.valueOf(mineAddParam.getStatus()), null, "T");

            return "添加成功";
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }

    }

    /**
     * @Description: 列表分页查询
     * @Author: Lt
     * @Date: 2024/5/27 14:49
     */
    public HttpResult pageList(MineOrderPageListParam param) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<MineOrderPageListRes> businessTruckPageListRes = mineOrderMapper.mineOrderPageList(param);
        businessTruckPageListRes.forEach(e -> {
            if (ObjectUtils.isNotNull(e.getOrderSource())) {
                e.setOrderSourceStr(e.getOrderSource() == 1 ? "生产自建" : "销售流转");
            }
            if (ObjectUtils.isNotNull(e.getStatus())){
                e.setStatusStr(getStatusStr(e.getStatus()));
            }
        });
        return HttpResult.ok(new PageRes<>(new PageInfo<>(businessTruckPageListRes)));
    }

    /**
     * @Description: 订单详情
     * @Author: Lt
     * @Date: 2024/5/27 15:54
     */
    public MineOrderDetailRes detail(String orderId) {
        MineOrderDetailRes kwBusinessMineOrder = mineOrderMapper.selectOrderById(orderId);
        if (ObjectUtils.isNull(kwBusinessMineOrder)) {
            throw new RuntimeException("当前数据不存在");
        }
        if (ObjectUtils.isNotNull(kwBusinessMineOrder.getStatus())) {

            kwBusinessMineOrder.setStatusStr(getStatusStr(kwBusinessMineOrder.getStatus()));
        }
        if (ObjectUtils.isNotNull(kwBusinessMineOrder.getOrderSource())) {
            kwBusinessMineOrder.setOrderSourceStr(kwBusinessMineOrder.getOrderSource() == 1 ? "生产自建" : "销售流转");
        }

        return kwBusinessMineOrder;

    }

    /**
    * @Description: 获取状态中文
    * @Author: Lt
    * @Date: 2024/6/5 15:49
    */
    private String getStatusStr(String status)
    {
        String tenantId = TenantUtil.getTenant();
        Object node = RedissonUtils.get(tenantId + "node");
        if (Objects.isNull(node)) {
            List<NodeStatusDTO> sortedEnums = nodeMapper.selectListNode(tenantId);

            // 创建要追加在最前面的元素
            NodeStatusDTO firstElement = new NodeStatusDTO();
            firstElement.setMsg(MineStatusEnum.getNameByCode(MineStatusEnum.ZERO.getCode()));
            firstElement.setCode(String.valueOf(MineStatusEnum.ZERO.getCode()));

            // 创建要追加在最后的元素
            NodeStatusDTO lastElement = new NodeStatusDTO();
            lastElement.setMsg(MineStatusEnum.getNameByCode(MineStatusEnum.TWENTY.getCode()));
            lastElement.setCode(String.valueOf(MineStatusEnum.TWENTY.getCode()));

            NodeStatusDTO twoElement = new NodeStatusDTO();
            twoElement.setMsg(MineStatusEnum.getNameByCode(MineStatusEnum.FIFTEEN.getCode()));
            twoElement.setCode(String.valueOf(MineStatusEnum.FIFTEEN.getCode()));

            // 将元素追加到列表的最前面
            sortedEnums.add(0, firstElement);
            sortedEnums.add(1, twoElement);

            // 将元素追加到列表的最后面
            sortedEnums.add(lastElement);
            Gson gson = new Gson();
            RedissonUtils.add(tenantId + "node", gson.toJson(sortedEnums));

            if (Objects.equals(status, "0") || Objects.equals(status, "15") || Objects.equals(status, "20")){
                return MineStatusEnum.getNameByCode(Integer.valueOf(status));
            }else{
                for (NodeStatusDTO sortedEnum : sortedEnums) {
                    if (sortedEnum.getCode().equals(status)) {
                        return sortedEnum.getName();
                    }
                }
            }

        }else {
            Gson gson = new Gson();
            Object o = gson.fromJson((String) node, new TypeToken<List<NodeStatusDTO>>() {}.getType());
            List<NodeStatusDTO> sortedEnums = (List<NodeStatusDTO>) o;
            for (NodeStatusDTO sortedEnum : sortedEnums) {
                if (sortedEnum.getCode().equals(status)) {
                    return sortedEnum.getMsg();
                }
            }
        }
        return "";
    }

    public List<Map<String, Object>> getStatusCountListInSingleQuery() {
        String tenantId = TenantUtil.getTenant();
        // 查询每个状态的计数
        List<Map<String, Object>> statusCounts = mineOrderMapper.countByStatus(tenantId);


        List<NodeStatusDTO> sortedEnums = nodeMapper.selectListNode(tenantId);

        // 创建要追加在最前面的元素
        NodeStatusDTO firstElement = new NodeStatusDTO();
        firstElement.setMsg(MineStatusEnum.getNameByCode(MineStatusEnum.ZERO.getCode()));
        firstElement.setCode(String.valueOf(MineStatusEnum.ZERO.getCode()));

        // 创建要追加在最后的元素
        NodeStatusDTO lastElement = new NodeStatusDTO();
        lastElement.setMsg(MineStatusEnum.getNameByCode(MineStatusEnum.TWENTY.getCode()));
        lastElement.setCode(String.valueOf(MineStatusEnum.TWENTY.getCode()));

        NodeStatusDTO twoElement = new NodeStatusDTO();
        twoElement.setMsg(MineStatusEnum.getNameByCode(MineStatusEnum.FIFTEEN.getCode()));
        twoElement.setCode(String.valueOf(MineStatusEnum.FIFTEEN.getCode()));

        // 将元素追加到列表的最前面
        sortedEnums.add(0, firstElement);
        sortedEnums.add(1, twoElement);

        // 将元素追加到列表的最后面
        sortedEnums.add(lastElement);
        // 将查询结果转换为所需的格式
        //List<MineStatusEnum> sortedEnums = MineStatusEnum.getSortList();
        List<Map<String, Object>> result = new ArrayList<>();
        for (NodeStatusDTO enumItem : sortedEnums) {
            Map<String, Object> statusCount = statusCounts.stream()
                    .filter(c -> enumItem.getCode().equals(c.get("status")))
                    .findFirst()
                    .orElseGet(() -> Map.of("status", enumItem.getCode(), "count", 0));
            result.add(
                    Map.of(
                            "key", enumItem.getMsg(),
                            "value", enumItem.getCode(),
                            "data", statusCount.get("count")
                    )
            );
        }
        return result;
    }


    public List<NodeStatusDTO> getActionTrackByMineOrderId(String orderId) {
        // TODO 根据订单的work_flow字段决定是哪一个订单流
        KwBusinessMineOrder kwBusinessMineOrder = mineOrderMapper.selectById(orderId);
        String flowId = kwBusinessMineOrder.getWorkFlow();

        List<NodeStatusDTO> orderFlowEnums = workFlowNodeMapper.selectListNode(flowId);
        // 获取订单的操作记录
        List<KwBusinessActionTrack> actionTracks = kwBusinessActionTrackMapper.findByMainOrderIdOrderByCreateTime(orderId);

        boolean cancelFound = false; // 添加一个标志，表示是否已遇到取消订单状态
        boolean rejectFound = false; // 添加一个标志，表示是否已遇到取消订单状态
        int cancelIndex = -1; // 用来记录取消订单前的最后一个执行节点索引
        String cancelNameAppend = "(" + MineStatusEnum.getNameByCode(MineStatusEnum.TWENTY.getCode()) + ")";
        String rejectNameAppend = "(" + MineStatusEnum.getNameByCode(MineStatusEnum.FIFTEEN.getCode()) + ")";

        for (int i = 0; i < orderFlowEnums.size(); i++) {
            orderFlowEnums.get(i).setColor("gray");

            for (KwBusinessActionTrack track : actionTracks) {
                if (orderFlowEnums.get(i).getCode().equals(track.getStatus())) {
                    orderFlowEnums.get(i).setColor("green");
                    cancelIndex = i; // 更新取消前最后一个执行节点的索引
                    break;
                }

                if (track.getStatus().equals("20") && !cancelFound) {
                    cancelFound = true;
                    if (cancelIndex != -1) { // 确保有一个被执行的节点在前
                        orderFlowEnums.get(cancelIndex).setColor("orange");
                        orderFlowEnums.get(cancelIndex).setName(orderFlowEnums.get(cancelIndex).getName() + cancelNameAppend); // 添加取消字样
                    }
                }

                if (track.getStatus().equals("15") && !rejectFound) {
                    rejectFound = true;
                    if (cancelIndex != -1) { // 确保有一个被执行的节点在前
                        orderFlowEnums.get(cancelIndex).setColor("orange");
                        orderFlowEnums.get(cancelIndex).setName(orderFlowEnums.get(cancelIndex).getName() + rejectNameAppend); // 添加驳回字样
                    }
                }
            }
        }

        // 如果没有执行任何节点就直接取消了，且只有一个取消记录，需要特殊处理
        if (cancelFound && cancelIndex == Global.MINUS_ONE && actionTracks.size() == Global.ADDRESS_LOAD) {
            orderFlowEnums.get(0).setColor("orange");
            orderFlowEnums.get(0).setName(orderFlowEnums.get(0).getName() + cancelNameAppend);
        }

        // 类似的，如果直接驳回且无其他执行记录，也需要处理
        if (rejectFound && cancelIndex == Global.MINUS_ONE && actionTracks.size() == Global.ADDRESS_LOAD) {
            orderFlowEnums.get(0).setColor("orange");
            orderFlowEnums.get(0).setName(orderFlowEnums.get(0).getName() + rejectNameAppend);
        }
        return orderFlowEnums;
        
    }




    /**
    * @Description: 取消
    * @Author: Lt
    * @Date: 2024/5/28 11:26
    */
    public String cancelOrder(CompleteOrderParam completeOrderParam)
    {
        KwBusinessMineOrder kwBusinessMineorder = mineOrderMapper.selectById(completeOrderParam.getOrderId());
        if (ObjectUtils.isNull(kwBusinessMineorder))
        {
            throw new RuntimeException("未找到当前订单");
        }
        if(kwBusinessMineorder.getIsTransport() != 2){
            throw new RuntimeException("当前订单不是非自有订单");
        }
        if (kwBusinessMineorder.getStatus().equals(String.valueOf(MineStatusEnum.TWENTY.getCode()))) {
            throw new RuntimeException("当前订单已取消,请勿重复操作");
        }
        kwBusinessMineorder.setStatus(String.valueOf(MineStatusEnum.TWENTY.getCode()));
        mineOrderMapper.updateById(kwBusinessMineorder);

        String nameByCode = MineStatusEnum.getNameByCode(MineStatusEnum.TWENTY.getCode());
        orderServerCommon.saveActionTrack(Long.valueOf(completeOrderParam.getOrderId()), String.valueOf(MineStatusEnum.TWENTY.getCode()), nameByCode,nameByCode);

        return "取消成功";


    }


}
