package net.vtstar.zhongtong.avi.equipment.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import net.vtstar.scada.base.gather.domain.EquipmentData;
import net.vtstar.user.mybatis.provider.Operation;
import net.vtstar.user.mybatis.provider.OrderBy;
import net.vtstar.user.mybatis.provider.WhereFilter;
import net.vtstar.user.search.service.SearchService;
import net.vtstar.zhongtong.avi.equipment.domain.EquipInfo;
import net.vtstar.zhongtong.avi.equipment.domain.FaultRecord;
import net.vtstar.zhongtong.avi.equipment.domain.RuntimeRecord;
import net.vtstar.zhongtong.avi.equipment.mapper.BasicInfoMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.EquipmentDataMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.FaultRecordMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.RuntimeRecordMapper;
import net.vtstar.zhongtong.avi.monitoring.domain.Warning;
import net.vtstar.zhongtong.avi.stamping.domain.LaserCutting3DMachine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: xiadongwei
 * @Date: 2019/9/20 17:23
 */
@Slf4j
@Service
public class RunRecordService {

    @Autowired
    private RuntimeRecordMapper runtimeRecordMapper;

    @Autowired
    private FaultRecordMapper faultRecordMapper;

    @Autowired
    private SearchService searchService;

    @Autowired
    private BasicInfoMapper basicInfoMapper;

    @Autowired
    private EquipmentDataMapper equipmentData;

    /**
     * 分页查询运行时间
     */
    public List<RuntimeRecord> findPageRunTime(JSONObject pageFilter) {
        PageHelper.startPage(pageFilter.getIntValue("pageNum"), pageFilter.getIntValue("pageSize"));
        List<RuntimeRecord> list = runtimeRecordMapper.findList(searchService.pageFilter2Filter(pageFilter, new WhereFilter() {{
            addJoin(RuntimeRecord.class, "machine_id", EquipInfo.class, "id");
            addFilter(RuntimeRecord.class,"group_code", Operation.IS, "null");
        }}), RuntimeRecord.class);
        list.stream().forEach(runtimeRecord -> {
            switch (runtimeRecord.getWorkshopCode()){
                case "PARTS":
                    runtimeRecord.setWorkshopCode("制件车间");
                    break;
                case "WELDING":
                    runtimeRecord.setWorkshopCode("焊装车间");
                    break;
                case "PAINTING":
                    runtimeRecord.setWorkshopCode("喷涂车间");
                    break;
                case "CHASSIS":
                    runtimeRecord.setWorkshopCode("底盘车间");
                    break;
                case "ASSEMBLY":
                    runtimeRecord.setWorkshopCode("总装车间");
                    break;
                case "TRIAL":
                    runtimeRecord.setWorkshopCode("试交车间");
                    break;
            }
        });
        return list;
    }

    /**
     * 分页查询报警记录
     */
    public List<FaultRecord> findPageFault(JSONObject pageFilter) {
        PageHelper.startPage(pageFilter.getIntValue("pageNum"), pageFilter.getIntValue("pageSize"));
        return faultRecordMapper.findList(searchService.pageFilter2Filter(pageFilter, new WhereFilter() {{
            /*addJoin(PaintshopStation.class, "area_id", PaintshopArea.class, "id");
            addJoin(PaintshopStation.class, "lane_id", PaintshopLane.class, "id");*/
        }}), FaultRecord.class);
    }


    /**
     * 根据设备编码查询上一条运行时间记录
     */
    public RuntimeRecord getLastByCode(String eqpCode) {
        List<RuntimeRecord> list = runtimeRecordMapper.findList(new WhereFilter() {{
            addJoin(RuntimeRecord.class, "machine_id", EquipInfo.class, "id");
            addFilter(EquipInfo.class, "equip_code", Operation.EQUAL, eqpCode);
            addOrderBy(RuntimeRecord.class, "create_time", OrderBy.DESC);
            setRows(0);
            setOffset(1);
        }}, RuntimeRecord.class);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        } else {
            return list.get(0);
        }
    }

    public void test() {
        EquipmentData laser = new LaserCutting3DMachine();
        ((LaserCutting3DMachine) laser).setCuttingSpeed(new BigDecimal(500));

        RuntimeRecord runtimeRecord = new RuntimeRecord();
        runtimeRecord.setWorkshopCode("23232");

        equipmentData.insert(runtimeRecord);
    }

    /**
     * 刷新Redis中的warning信息到数据库中
     *
     * @param list
     */
    public void refreshWarning(List<Warning> list) {
        List<FaultRecord> faultRecords = faultRecordMapper.findList(new WhereFilter() {{
            addFilter("end_time", Operation.IS, "null");
        }}, FaultRecord.class);
        List<FaultRecord> records = new ArrayList<>();
        //告警记录为空, 则保存当前报警
        if (CollectionUtils.isEmpty(faultRecords)) {
            for (Warning w : list) {
                FaultRecord faultRecord = new FaultRecord();
                faultRecord.setEquipCode(w.getName().split(" ")[0]);
                faultRecord.setWarningInfo(w.getInfo());
                faultRecord.setWorkshopCode("涂装车间");
                faultRecord.setBeginTime(new Date());
                records.add(faultRecord);
            }
            if (!CollectionUtils.isEmpty(records)) {
                faultRecordMapper.insertList(records);
            }
            return;
        }
        Map<String, Warning> warningMap = list.stream().collect(Collectors.toMap(Warning :: getInfo, w -> w, (key1, key2) -> key1));
        Map<String, FaultRecord> faultRecordMap = faultRecords.stream().collect(Collectors.toMap(FaultRecord::getWarningInfo, f ->f, (key1, key2) -> key1));
        //遍历现有异常, 看是否存在新的报警
        for (String warningKey : warningMap.keySet()){
            Warning warning = warningMap.get(warningKey);
            if (null == faultRecordMap.get(warningKey)){
                FaultRecord faultRecord = new FaultRecord();
                faultRecord.setEquipCode(warning.getName().split(" ")[0]);
                faultRecord.setWarningInfo(warning.getInfo());
                faultRecord.setWorkshopCode("涂装车间");
                faultRecord.setBeginTime(new Date());
                faultRecord.setCreateTime(new Date());
                records.add(faultRecord);
            }
        }
        if (!CollectionUtils.isEmpty(records)){
            faultRecordMapper.insertList(records);
        }
        //遍历异常记录, 若现有异常里面不包含, 则说明此异常已经结束
        for (String faultString : faultRecordMap.keySet()){
            FaultRecord faultRecord = faultRecordMap.get(faultString);
            if (null == warningMap.get(faultString)){
                faultRecord.setEndTime(new Date());
                faultRecordMapper.update(faultRecord);
            }else{
                faultRecord.setBeginTime(new Date());
                faultRecordMapper.update(faultRecord);
            }
        }
    }
}
