package com.inspect.metadata.montdatamqhandle.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.metadata.alg.domain.BasedataAlgSubtype;
import com.inspect.metadata.alg.mapper.BasedataAlgSubtypeMapper;
import com.inspect.metadata.area.domain.BaseDataArea;
import com.inspect.metadata.area.service.IBaseDataAreaService;
import com.inspect.metadata.eqpbook.domain.BasedataEqpBook;
import com.inspect.metadata.eqpbook.mapper.BasedataEqpBookMapper;
import com.inspect.metadata.patrolpointmnt.domain.BasedataPatrolPoint;
import com.inspect.metadata.patrolpointmnt.domain.BasedataPatrolPointPreset;
import com.inspect.metadata.patrolpointmnt.domain.vo.DevicePointModelItem;
import com.inspect.metadata.patrolpointmnt.mapper.BasedataPatrolPointPresetMapper;
import com.inspect.metadata.patrolpointmnt.service.IBasedataPatrolPointService;
import com.inspect.metadata.prodevmnt.domain.BasedataDevice;
import com.inspect.metadata.prodevmnt.mapper.BasedataDeviceMapper;
import com.inspect.metadata.prodevmnt.service.IBasedataDeviceService;
import com.inspect.base.core.utils.DateUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

@RestController
@RequestMapping({"/area_data"})
public class XMLParser {
    @Resource
    private IBaseDataAreaService baseDataAreaService;
    @Resource
    private IBasedataDeviceService basedataDeviceService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private IBasedataPatrolPointService basedataPatrolPointService;
    @Resource
    private BasedataDeviceMapper basedataDeviceMapper;
    @Resource
    BasedataAlgSubtypeMapper basedataAlgSubtypeMapper;
    @Resource
    BasedataEqpBookMapper basedataEqpbookMapper;
    @Resource
    BasedataPatrolPointPresetMapper basedataPatrolPointPresetMapper;

    public static void main(String[] argv) {
        try {
            File inputFile = new File("d:/device_model_E100-001.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();
            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
            NodeList nList = doc.getElementsByTagName("Item");
            System.out.println("----------------------------");
            Map<String, String> bayMap = new HashMap<>();
            Map<String, List<String>> areaMap = new HashMap<>();

            int count;
            for (count = 0; count < nList.getLength(); ++count) {
                Node nNode = nList.item(count);
                if (nNode.getNodeType() == 1) {
                    Element eElement = (Element) nNode;
                    bayMap.put(eElement.getAttribute("area_id") + ":" + eElement.getAttribute("bay_id"), eElement.getAttribute("bay_name") + ":" + eElement.getAttribute("area_id") + ":" + eElement.getAttribute("area_name"));
                    String areaKey = eElement.getAttribute("area_id") + ":" + eElement.getAttribute("area_name");
                    String areaData = eElement.getAttribute("area_id") + ":" + eElement.getAttribute("area_name") + "--" + eElement.getAttribute("bay_id") + ":" + eElement.getAttribute("bay_name");
                    List areaDataMap = areaMap.get(areaKey);
                    if (CollectionUtils.isNotEmpty(areaDataMap)) {
                        if (!areaDataMap.contains(areaData)) {
                            areaDataMap.add(areaData);
                            areaMap.put(areaKey, areaDataMap);
                        }
                    } else {
                        areaDataMap = new ArrayList<>();
                        areaDataMap.add(areaData);
                        areaMap.put(areaKey, areaDataMap);
                    }
                }
            }

            System.out.println("bayMap.size=" + bayMap.size());
            System.out.println("areaMap.size=" + areaMap.size());
            count = 0;

            for (String areaKey : areaMap.keySet()) {
                System.out.println("baysize=" + areaMap.get(areaKey).size());
                count += areaMap.get(areaKey).size();
                System.out.println("area--" + areaMap.get(areaKey));
            }

            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @GetMapping({"/areaSave"})
    public void areaSave() {
        try {
            File inputFile = new File("d:/device_model_E100-001.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();
            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
            NodeList nList = doc.getElementsByTagName("Item");
            System.out.println("----------------------------");
            String sendCode = "1";
            Map<String, List<String>> deviceMap = new HashMap<>();
            Map<String, List<String>> areaMap = new HashMap<>();

            String device_id;
            String device_name;
            for (int temp = 0; temp < nList.getLength(); ++temp) {
                Node nNode = nList.item(temp);
                if (nNode.getNodeType() == 1) {
                    Element eElement = (Element) nNode;
                    String areaKey = eElement.getAttribute("area_id") + ":" + eElement.getAttribute("area_name");
                    String areaData = eElement.getAttribute("bay_id") + ":" + eElement.getAttribute("bay_name");
                    List areaDataMap = areaMap.get(areaKey);
                    if (CollectionUtils.isNotEmpty(areaDataMap)) {
                        if (!areaDataMap.contains(areaData)) {
                            areaDataMap.add(areaData);
                            areaMap.put(areaKey, areaDataMap);
                        }
                    } else {
                        areaDataMap = new ArrayList<>();
                        areaDataMap.add(areaData);
                        areaMap.put(areaKey, areaDataMap);
                    }

                    device_id = eElement.getAttribute("main_device_id") + ":" + eElement.getAttribute("main_device_name") + ":" + eElement.getAttribute("area_id") + ":" + eElement.getAttribute("area_name");
                    device_name = eElement.getAttribute("component_id") + ":" + eElement.getAttribute("component_name");
                    List mainDeviceDataMap = deviceMap.get(device_id);
                    if (CollectionUtils.isNotEmpty(mainDeviceDataMap)) {
                        if (!mainDeviceDataMap.contains(device_name)) {
                            mainDeviceDataMap.add(device_name);
                            deviceMap.put(device_id, mainDeviceDataMap);
                        }
                    } else {
                        mainDeviceDataMap = new ArrayList();
                        mainDeviceDataMap.add(device_name);
                        deviceMap.put(device_id, mainDeviceDataMap);
                    }
                }
            }

            System.out.println("deviceMap.size=" + areaMap.size());
            System.out.println("deviceMap.size=" + deviceMap.size());
            this.saveAreaData(areaMap, sendCode);
            this.saveMainDeviceData(deviceMap, sendCode);
            String convertFlag = "0";
            String algConvertFlag = "0";
            System.out.println("nList.size=" + nList.getLength());

            for (int temp = 0; temp < nList.getLength(); ++temp) {
                Node nNode = nList.item(temp);
                if (nNode.getNodeType() == 1) {
                    Element eElement = (Element) nNode;
                    BasedataPatrolPoint patrolpointInsert = new BasedataPatrolPoint();
                    device_id = eElement.getAttribute("device_id");
                    device_name = eElement.getAttribute("device_name");
                    String main_device_id = eElement.getAttribute("main_device_id");
                    String originalDeviceId = eElement.getAttribute("component_id");
                    String originalAlgSubtypeIds = eElement.getAttribute("recognition_type_list");
                    BasedataPatrolPoint basedataPatrolpoint = new BasedataPatrolPoint();
                    basedataPatrolpoint.setPatrolPointCode(sendCode + "_" + device_id);
                    List<BasedataPatrolPoint> patrolpointList = this.basedataPatrolPointService.selectBasedataPatrolPointList(basedataPatrolpoint);
                    if (null == patrolpointList || patrolpointList.isEmpty()) {
                        BasedataDevice basedataDevice = new BasedataDevice();
                        basedataDevice.setOldDeviceId(sendCode + "_component_" + originalDeviceId);
                        List<BasedataDevice> devices = this.basedataDeviceMapper.selectBasedataDeviceList(basedataDevice);
                        if (CollectionUtils.isNotEmpty(devices) && !devices.isEmpty()) {
                            BasedataDevice device = devices.get(0);
                            patrolpointInsert.setPatrolPointCode(sendCode + "_" + device_id);
                            patrolpointInsert.setPatrolPointName(device_name);
                            patrolpointInsert.setOriginalMainDeviceId(main_device_id);
                            patrolpointInsert.setDeviceId(device.getDeviceId());
                            patrolpointInsert.setCreateTime(DateUtils.getNowDate());
                            patrolpointInsert.setCreateBy("sys");
                            patrolpointInsert.setOriginalAlgSubtypeIds(originalAlgSubtypeIds);
                            patrolpointInsert.setOriginalDeviceId(originalDeviceId);
                            patrolpointInsert.setAlgSubtypeIds(originalAlgSubtypeIds);
                            patrolpointInsert.setPointImptLevel("Ⅰ");
                            patrolpointInsert.setMainDeviceId(device.getParentId());
                            patrolpointInsert.setDeviceTypeId(978L);
                            patrolpointInsert.setAreaId(device.getAreaId());
                            this.setAlgIdS(patrolpointInsert, sendCode, originalAlgSubtypeIds, algConvertFlag);
                            BasedataPatrolPoint patrolPointInsertRet = this.basedataPatrolPointService.insertBasedataPatrolPoint(patrolpointInsert);
                            Long patrolPointId = patrolPointInsertRet.getPatrolPointId();
                            DevicePointModelItem item = new DevicePointModelItem();
                            this.handPointPreset(patrolPointId, item, sendCode);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void handPointPreset(Long patrolPointId, DevicePointModelItem item, String sendCode) {
        String video_pos = item.getVideo_pos();
        if (null == video_pos) {
            BasedataEqpBook basedataEqpbook = new BasedataEqpBook();
            basedataEqpbook.setPatrolDeviceCode(sendCode);
            List<BasedataEqpBook> eqpBooks = this.basedataEqpbookMapper.selectBasedataEqpBookList(basedataEqpbook);
            if (null != eqpBooks && !eqpBooks.isEmpty()) {
                BasedataEqpBook eqpBook = eqpBooks.get(0);
                this.insertPatrolPointPreset(patrolPointId, eqpBook.getPatrolDeviceCode(), StringUtils.EMPTY);
            }
        }

    }

    public void insertPatrolPointPreset(Long patrolPointId, String device_code, String device_pos) {
        BasedataEqpBook basedataEqpbook = new BasedataEqpBook();
        basedataEqpbook.setPatrolDeviceCode(device_code);
        List<BasedataEqpBook> eqpBooks = this.basedataEqpbookMapper.selectBasedataEqpBookList(basedataEqpbook);
        if (!eqpBooks.isEmpty()) {
            Long eqpBookId = eqpBooks.get(0).getEqpBookId();
            BasedataPatrolPointPreset basedataPatrolpointPreset = new BasedataPatrolPointPreset();
            basedataPatrolpointPreset.setEqpBookId(eqpBookId);
            basedataPatrolpointPreset.setPresetCode(device_pos);
            basedataPatrolpointPreset.setPatrolPointId(patrolPointId);
            List<BasedataPatrolPointPreset> presets = this.basedataPatrolPointPresetMapper.selectBasedataPatrolPointPresetList(basedataPatrolpointPreset);
            BasedataPatrolPointPreset pointPreset;
            if (null != presets && !presets.isEmpty()) {
                pointPreset = presets.get(0);
                pointPreset.setPresetCode(device_pos);
                pointPreset.setPatrolDeviceCode(device_code);
                pointPreset.setUpdateBy("sys");
                pointPreset.setUpdateTime(DateUtils.getNowDate());
                this.basedataPatrolPointPresetMapper.updateBasedataPatrolPointPreset(pointPreset);
            } else {
                pointPreset = new BasedataPatrolPointPreset();
                pointPreset.setPatrolPointId(patrolPointId);
                pointPreset.setPresetCode(device_pos);
                pointPreset.setEqpBookId(eqpBookId);
                pointPreset.setPatrolDeviceCode(eqpBooks.get(0).getPatrolDeviceCode());
                pointPreset.setCreateBy("sys");
                pointPreset.setCreateTime(DateUtils.getNowDate());
                this.basedataPatrolPointPresetMapper.insertBasedataPatrolPointPreset(pointPreset);
            }
        } else {
            BasedataPatrolPointPreset basedataPatrolpointPreset = new BasedataPatrolPointPreset();
            basedataPatrolpointPreset.setPatrolPointId(patrolPointId);
            basedataPatrolpointPreset.setPatrolDeviceCode(device_code);
            basedataPatrolpointPreset.setPresetCode(device_pos);
            this.basedataPatrolPointPresetMapper.insertBasedataPatrolPointPreset(basedataPatrolpointPreset);
        }

    }

    public void setDeviceId(BasedataPatrolPoint patrolPointInsert, String SendCode, String mainDeviceId, String componentId, String convertFlag) {
        if (convertFlag.equals("0")) {
            BasedataDevice basedataDevice = new BasedataDevice();
            basedataDevice.setDeviceCode(mainDeviceId);
            List<BasedataDevice> devices = this.basedataDeviceMapper.selectBasedataDeviceList(basedataDevice);
            Long componentTypeId;
            if (!devices.isEmpty()) {
                Long main_device_type_id = devices.get(0).getDeviceTypeId();
                componentTypeId = devices.get(0).getDeviceId();
                patrolPointInsert.setMainDeviceId(componentTypeId);
                patrolPointInsert.setDeviceTypeId(main_device_type_id);
                patrolPointInsert.setAreaId(devices.get(0).getAreaId());
            }

            basedataDevice.setDeviceCode(componentId);
            List<BasedataDevice> deviceList = this.basedataDeviceMapper.selectBasedataDeviceList(basedataDevice);
            if (!deviceList.isEmpty()) {
                componentTypeId = deviceList.get(0).getDeviceTypeId();
                Long deviceId = deviceList.get(0).getDeviceId();
                patrolPointInsert.setDeviceId(deviceId);
                patrolPointInsert.setAreaId(deviceList.get(0).getAreaId());
            }
        }

    }

    public void setAlgIdS(BasedataPatrolPoint basedataPatrolPoint, String SendCode, String recognitionTypeList, String algConvertFlag) {
        if (null != recognitionTypeList && !recognitionTypeList.isEmpty()) {
            StringBuilder builder = new StringBuilder();
            StringBuilder nameBuilder = new StringBuilder();
            JSONArray jsonArray = new JSONArray();
            String[] recognitionTypeArray = recognitionTypeList.split(StringUtils.COMMA);

            for (String recognition_type : recognitionTypeArray) {
                if ("0".equals(algConvertFlag)) {
                    BasedataAlgSubtype basedataAlgSubtype = new BasedataAlgSubtype();
                    basedataAlgSubtype.setAlgSubtypeCode(recognition_type);
                    List<BasedataAlgSubtype> algSubtypes = this.basedataAlgSubtypeMapper.selectBasedataAlgSubtypeList(basedataAlgSubtype);
                    if (null != algSubtypes && !algSubtypes.isEmpty()) {
                        BasedataAlgSubtype algSubtype = algSubtypes.get(0);
                        Long algId = algSubtype.getAlgId();
                        builder.append(algId);
                        String name = algSubtype.getAlgSubtypeName();
                        nameBuilder.append(name);
                        JSONObject jsonObject = new JSONObject();
                        String lowerFlag = algSubtype.getLowerFlag();
                        if (null != lowerFlag && lowerFlag.equals("1")) {
                            jsonObject.put("lowerValue", algSubtype.getLowerValue());
                        }

                        String upperFlag = algSubtype.getUpperFlag();
                        if (null != upperFlag && upperFlag.equals("1")) {
                            jsonObject.put("upperValue", algSubtype.getUpperValue());
                        }

                        if (!jsonObject.isEmpty()) {
                            jsonArray.add(jsonObject);
                            jsonObject.put("id", "sub_" + algSubtype.getAlgSubtypeId());
                            jsonObject.put("code", algSubtype.getAlgSubtypeCode());
                        }
                    }
                }
            }

            if (builder.length() > 0) {
                basedataPatrolPoint.setAlgSubtypeIds(builder.toString());
            }

            if (nameBuilder.length() > 0) {
                basedataPatrolPoint.setAlgSubtypeName(nameBuilder.toString());
            }

            String alarmThreshold = jsonArray.toJSONString();
            basedataPatrolPoint.setAlarmThreshold(alarmThreshold);
        }

    }

    private void saveMainDeviceData(Map<String, List<String>> deviceMap, String sendCode) {
        int count = 0;
        int count1 = 0;
        int count2 = 0;

        for (String deviceKey : deviceMap.keySet()) {
            ++count;
            List deviceList = deviceMap.get(deviceKey);
            BasedataDevice device = new BasedataDevice();
            String deviceId = deviceKey.split(StringUtils.COLON)[0];
            String deviceName = deviceKey.split(StringUtils.COLON)[1];
            String oldAreaId = deviceKey.split(StringUtils.COLON)[2];
            String areaName = deviceKey.split(StringUtils.COLON)[3];
            device.setOldDeviceId(sendCode + "_main_" + deviceId);
            List<BasedataDevice> basedataDeviceList = this.basedataDeviceService.selectBasedataDeviceList(device);
            Long pid;
            if (CollectionUtils.isEmpty(basedataDeviceList)) {
                ++count1;
                pid = (Long) this.redisTemplate.opsForValue().get(oldAreaId);
                device.setParentId(0L);
                device.setOldAreaName(areaName);
                device.setOldAreaId(sendCode + "_" + oldAreaId);
                device.setStatus("0");
                device.setCreateBy("sys");
                device.setPowerMainEquFlag("Yes");
                device.setAreaId(pid);
                device.setAreaName(areaName);
                device.setDeviceName(deviceName);
                device.setDeviceCode(device.getOldDeviceId() + "_" + RandomUtil.randomNumbers(4));
                this.basedataDeviceService.insertBasedataDevice(device);
            } else {
                ++count2;
                device = basedataDeviceList.get(0);
                device.setDeviceName(deviceName);
                this.basedataDeviceService.updateBasedataDevice(device);
            }

            pid = device.getDeviceId();
            this.saveComponentData(deviceList, device, basedataDeviceList, pid, sendCode);
        }

        System.out.println("shuliang=" + count);
        System.out.println("shuliang1=" + count1);
        System.out.println("shuliang2=" + count2);
    }

    private void saveAreaData(Map<String, List<String>> areaMap, String sendCode) {
        BaseDataArea baseDataArea = new BaseDataArea();
        baseDataArea.setAreaCode(sendCode);
        List<BaseDataArea> baseAreaList = this.baseDataAreaService.selectAreaList(baseDataArea);
        long areaPid = 1L;
        if (CollectionUtils.isEmpty(baseAreaList)) {
            baseDataArea.setParentId(areaPid);
            baseDataArea.setAreaName(sendCode);
            baseDataArea.setAreaType("station_in");
            baseDataArea.setStatus("0");
            baseDataArea.setCreateBy("sys");
            baseDataArea.setAncestors(",1");
            this.baseDataAreaService.insertArea(baseDataArea);
            areaPid = baseDataArea.getAreaId();
        }

        for (String areaKey : areaMap.keySet()) {
            List bayList = areaMap.get(areaKey);
            BaseDataArea area = new BaseDataArea();
            String areaId = areaKey.split(StringUtils.COLON)[0];
            String areaName = areaKey.split(StringUtils.COLON)[1];
            area.setOldAreaId(sendCode + "_" + areaId);
            List<BaseDataArea> baseDataAreaList = this.baseDataAreaService.selectAreaList(area);
            if (CollectionUtils.isEmpty(baseDataAreaList)) {
                area.setParentId(areaPid);
                area.setAreaName(areaName);
                area.setAreaType("station_in");
                area.setStatus("0");
                area.setCreateBy("sys");
                area.setAncestors("," + areaPid);
                this.baseDataAreaService.insertArea(area);
            } else {
                area = baseDataAreaList.get(0);
                area.setAreaName(areaName);
                this.baseDataAreaService.updateArea(area);
            }

            Long pid = area.getAreaId();
            this.redisTemplate.opsForValue().set(areaId, pid);
            this.saveBayData(bayList, area, baseDataAreaList, pid, sendCode);
        }

    }

    private void saveBayData(List<String> bayList, BaseDataArea area, List<BaseDataArea> baseDataAreaList, Long pid, String sendCode) {
        if (CollectionUtils.isNotEmpty(bayList) && pid != null) {
            String oldPid = area.getOldAreaId();
            bayList.stream().forEach((bay) -> {
                String bayId = bay.split(StringUtils.COLON)[0];
                String bayName = bay.split(StringUtils.COLON)[1];
                BaseDataArea bayData = new BaseDataArea();
                bayData.setOldAreaId(sendCode + "_" + bayId);
                List<BaseDataArea> baseDataBayList = this.baseDataAreaService.selectAreaList(bayData);
                if (CollectionUtils.isEmpty(baseDataBayList)) {
                    bayData.setParentId(1L);
                    bayData.setAreaName(bayName);
                    bayData.setAreaType("bayunit");
                    bayData.setStatus("0");
                    bayData.setCreateBy("sys");
                    bayData.setAncestors(",1," + pid);
                    bayData.setParentId(pid);
                    bayData.setOldParentId(sendCode + "_" + oldPid);
                    this.baseDataAreaService.insertArea(bayData);
                } else {
                    bayData = baseDataAreaList.get(0);
                    bayData.setAreaName(bayName);
                    this.baseDataAreaService.updateArea(bayData);
                }

            });
        }

    }

    private void saveComponentData(List<String> componentList, BasedataDevice device, List<BasedataDevice> basedataDeviceList, Long pid, String sendCode) {
        if (CollectionUtils.isNotEmpty(componentList) && pid != null) {
            String oldPid = device.getOldAreaId();
            componentList.stream().forEach((bay) -> {
                String componentId = bay.split(StringUtils.COLON)[0];
                String componentName = bay.split(StringUtils.COLON)[1];
                BasedataDevice componentData = new BasedataDevice();
                componentData.setOldDeviceId(sendCode + "_component_" + componentId);
                List<BasedataDevice> baseDataComponentList = this.basedataDeviceService.selectBasedataDeviceList(componentData);
                if (CollectionUtils.isEmpty(baseDataComponentList)) {
                    componentData.setParentId(pid);
                    componentData.setOldAreaName(device.getOldAreaName());
                    componentData.setOldAreaId(sendCode + "_" + device.getOldAreaId());
                    componentData.setStatus("0");
                    componentData.setCreateBy("sys");
                    componentData.setPowerMainEquFlag("No");
                    componentData.setAreaId(device.getAreaId());
                    componentData.setAreaName(device.getAreaName());
                    componentData.setDeviceName(componentName);
                    componentData.setDeviceCode(componentData.getOldDeviceId() + "_" + RandomUtil.randomNumbers(4));
                    this.basedataDeviceService.insertBasedataDevice(componentData);
                } else {
                    componentData = baseDataComponentList.get(0);
                    componentData.setDeviceName(componentName);
                    this.basedataDeviceService.updateBasedataDevice(componentData);
                }

            });
        }

    }
}
