package com.fizz.business.constants.enums;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.annotation.IEnum;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fizz.business.form.ChangePlanStatusForm;
import com.fizz.business.form.L1OperateMatForm;
import com.fizz.business.service.CrmPdiPlanService;
import com.fizz.business.comm.OPC.OpcMessageSend;
import com.fizz.business.service.client.RedisCacheManager;
import com.fizz.business.service.impl.BeanFactory;
import com.fizz.business.utils.MatmapUtil;
import com.fizz.business.utils.WebSocketUtil;
import com.fizz.business.vo.CrmPdiPlanVO;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


/**
 * 钢卷操作
 *
 * @author chenhao
 * @date 2023/04/24
 */
@Slf4j
@Getter
@AllArgsConstructor
public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatForm> {
    ONLINE("上线") {
        @Override
        public void operate(L1OperateMatForm form) {
            ONLINE.syncPlanStatus(form.getPlanId(),form.getEntryMatId());
            MatmapUtil.setMatmap(form.getPorIdx(), form.getEntryMatId(), form.getPlanId(), form.getPlanNo());
            // 钢卷上线时, 缓存工艺规程
//            BeanFactory.getBean(RedisCacheManager.class).setCoilSetup(form.getPlanId());
            WebSocketUtil.sendSignalMsg(form);
            WebSocketUtil.sendMatmapMsg();
        }
    },
    UNLOAD("卸卷") {
        @Override
        public void operate(L1OperateMatForm form) {
            // 卷取机卸卷,清除matmap
            MatmapUtil.clearMatmap(form.getTrIdx());
            // 移除mergeHead
            BeanFactory.getBean(RedisCacheManager.class).removeMergeHead();
            WebSocketUtil.sendSignalMsg(form);
            WebSocketUtil.sendMatmapMsg();
        }
    },

    PRODUCING("生产中") {
        @Override
        public void operate(L1OperateMatForm form) {

            PRODUCING.syncPlanStatus(form.getPlanId(),form.getEntryMatId());
            // L1 指令将计划置为 PRODUCING 时，写入钢卷号到 OPC
                if (form.getEntryMatId() != null) {
                    BeanFactory.getBean(OpcMessageSend.class).sendCoilId(form.getEntryMatId());
                }


            WebSocketUtil.sendSignalMsg(form);
        }
    },
    PRODUCT("生产完成") {
        @Override
        public void operate(L1OperateMatForm form) {
            log.error("==================================================================");
            log.error("form.planId={},entryMatId={}", form.getPlanId(), form.getEntryMatId());
            PRODUCT.syncPlanStatus(form.getPlanId(),form.getEntryMatId());
            WebSocketUtil.sendSignalMsg(form);
        }
    },
    PAY_OVER("甩尾") {
        @Override
        public void operate(L1OperateMatForm form) {
            ArrayList<String> status = Lists.newArrayList(PlanStatusEnum.PRODUCING.name(), PlanStatusEnum.PRODUCT.name());
            CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
            CrmPdiPlanVO plan = planClient.getByCoilIdAndOperId(form.getEntryMatId());
            Assert.notNull(plan, "计划[{}]不存在", plan.getId());
            Assert.isTrue(status.contains(plan.getStatus()), "当前状态[{}]不支持甩尾", plan.getStatus());
            MatmapUtil.clearMatmap(form.getPorIdx());
            WebSocketUtil.sendSignalMsg(form);
            WebSocketUtil.sendMatmapMsg();
        }
    },
    ;

    private final String desc;

    private static final Map<String, L1OperateMatEnum> MAP = new HashMap<>(16);

    static {
        for (L1OperateMatEnum e : L1OperateMatEnum.values()) {
            MAP.put(e.getValue(), e);
        }
    }

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static L1OperateMatEnum getByValue(String value) {
        return MAP.get(value);
    }

    @JsonValue
    @Override
    public String getValue() {
        return this.name();
    }


    /**
     * 同步计划状态
     *
     * @param planId 计划id
     */
    private void syncPlanStatus(String planId, String matId) {
        CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);

        planClient.changeStatus(ChangePlanStatusForm.builder()
                .operation(this.name())
                .id(planId)
                .matId(matId)
                .build());
    }
}
