package com.inspect.mqtt.services.Warn;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.inspect.analysis.domain.ResultAnalysis;
import com.inspect.analysis.domain.Pos;
import com.inspect.analysis.domain.resultList;
import com.inspect.analysis.domain.results;
import com.inspect.analysis.mapper.ResultAnalysisMapper;
import com.inspect.base.core.sftp.SftpClient;
import com.inspect.base.core.utils.DateUtils;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.mqtt.IMQTTUtil;
import com.inspect.partrolresult.domain.AlgInfo;
import com.inspect.partrolresult.domain.PatrolResult;
import com.inspect.partrolresult.mapper.PatrolResultMapper;
import com.inspect.task.service.IPatrolTaskService;
import com.inspect.taskftp.domain.PatrolTaskFtp;
import com.inspect.taskftp.mapper.PatrolTaskFtpMapper;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.poi.util.IOUtils;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Service;

@Service
public class UploadServerImpl implements IUploadServer, MqttCallback {
    private final PatrolResultMapper patrolResultMapper;
    private final ResultAnalysisMapper resultAnalysisMapper;
    private final IMQTTUtil mqttUtil;
    private final IPatrolTaskService patrolTaskService;
    private final PatrolTaskFtpMapper patrolTaskFtpMapper;
    private final SftpClient sftpClient;

    public UploadServerImpl(PatrolResultMapper patrolResultMapper, ResultAnalysisMapper resultAnalysisMapper, IMQTTUtil mqttUtil, IPatrolTaskService patrolTaskService, PatrolTaskFtpMapper patrolTaskFtpMapper, SftpClient sftpClient) {
        this.patrolResultMapper = patrolResultMapper;
        this.resultAnalysisMapper = resultAnalysisMapper;
        this.mqttUtil = mqttUtil;
        this.patrolTaskService = patrolTaskService;
        this.patrolTaskFtpMapper = patrolTaskFtpMapper;
        this.sftpClient = sftpClient;
    }

    public void uploadData(ResultAnalysis fault) {
        String objectId = fault.getObjectId();
        System.out.println("=======================objectId================" + objectId);
        PatrolResult patrolResult = this.patrolResultMapper.selectPatrolResultByLineId(Long.valueOf(fault.getBusinessId()));
        System.out.println("=======================patrolResult================" + patrolResult);
        Map<String, String> stringMap = this.patrolResultMapper.selectAlgorithmType(objectId);
        List<String> splitList = new ArrayList<>();
        if (stringMap != null) {
            String algSubtypeIds = stringMap.get("alg_subtype_ids");
            if (algSubtypeIds.contains(StringUtils.COMMA)) {
                String[] splits = algSubtypeIds.split(StringUtils.COMMA);
                for (String split : splits) {
                    if (StringUtils.isNotEmpty(split)) {
                        splitList.add(split);
                    }
                }
            } else {
                splitList.add(algSubtypeIds);
            }
        }

        PatrolResult result = new PatrolResult();
        if (!splitList.isEmpty()) {
            result.setAlgId(splitList);
        }

        List<AlgInfo> algInfoList = this.patrolResultMapper.selectAlgInfo(result);
        String algName = algInfoList.size() == 1 ?
                algInfoList.get(0).getAlgName() :
                algInfoList.get(algInfoList.size() - 1).getAlgName();
        Map<String, Object> baseInfoMap = this.patrolResultMapper.selectBaseInfoByPointId(objectId);
        Map<String, String> stationMap = this.patrolResultMapper.selectBasedataStation();
        String spaceUnit = stationMap.get("station_name");
        String voltLevel = stationMap.get("volt_level") == null ? "500" : stationMap.get("volt_level");
        JSONObject parseObject = JSONObject.parseObject(fault.getResultContent());
        Object jsonArray = parseObject.get("resultList");
        List<resultList> resContentList = JSONArray.parseArray(jsonArray.toString(), resultList.class);
        List<results> results = resContentList.get(0).getResults();
        String desc = results.get(0).getDesc();
        String conf = results.get(0).getConf();
        String type = results.get(0).getType();
        String imageUrl = results.get(0).getResImageUrl();
        Map<Object, Object> algNamemap = new HashMap<>();
        List list;
        if (StringUtils.isNotEmpty(type)) {
            list = this.patrolResultMapper.selectAlgTypeByAlaName(type);
            if (!list.isEmpty()) {
                algNamemap = (Map) list.get(0);
            }
        }

        List<Pos> posList = results.get(0).getPosList();
        StringBuilder stringBuilder = new StringBuilder();
        int index = 1;
        Iterator<Pos> iterator = posList.iterator();
        while (true) {
            String[] areas;
            String deviceName;
            String provinceName;
            do {
                if (!iterator.hasNext()) {
                    System.out.println(stringBuilder);
                    if (StringUtils.isEmpty(stringBuilder.toString())) {
                        stringBuilder = new StringBuilder("   \"x1\":0,\n  \"y1\":0,\n   \"x2\":0,\n     \"y2\":0,\n");
                    }

                    String stationIp = this.patrolTaskService.selectConfigByKey("MAJOR_URL");
                    String node_id = "";
                    if (stationMap.get("node_id") != null) {
                        node_id = stationMap.get("node_id");
                    }

                    String fileName = DateUtils.format(DateUtils.yyyyMMdd, new Date())
                            + StringUtils.UNDERLINE
                            + DateUtils.format(DateUtils.HHmmss, new Date())
                            + StringUtils.UNDERLINE;
                    String bay_name = "";
                    if (baseInfoMap != null && baseInfoMap.get("jg_name") != null) {
                        bay_name = baseInfoMap.get("jg_name").toString();
                        fileName = fileName + bay_name + StringUtils.UNDERLINE;
                    }

                    deviceName = "";
                    if (baseInfoMap != null && baseInfoMap.get("main_name") != null) {
                        deviceName = baseInfoMap.get("main_name").toString();
                        if (StringUtils.isNotEmpty(fileName)) {
                            fileName = fileName + deviceName + StringUtils.UNDERLINE;
                        }
                    }

                    provinceName = stationMap.get("province_name");
                    String city_name = stationMap.get("city_name");
                    String point_name = baseInfoMap.get("patrol_point_name").toString();
                    if (StringUtils.isNotEmpty(point_name) && StringUtils.isNotEmpty(fileName)) {
                        fileName = fileName + point_name + StringUtils.UNDERLINE;
                    }

                    String stringSub = stringBuilder.charAt(stringBuilder.length() - 2) == ',' ?
                            stringBuilder.substring(0, stringBuilder.length() - 2) :
                            stringBuilder.toString();

                    String newPicDir = "";
                    if (StringUtils.isNotEmpty(patrolResult.getFilePath())) {
                        String picDefect = fileName + "原图.jpg";
                        newPicDir = this.ftpFilePath(patrolResult.getFilePath(), algName, patrolResult.getDeviceId(), picDefect);
                    }

                    String pictureDefect = "";
                    String pictureDifferent = "";
                    String pictureDiffBase = "";
                    String json;
                    if (algNamemap != null && ((Map<?, ?>) algNamemap).get("alg_name") != null) {
                        String asf;
                        if (((String) ((Map<?, ?>) algNamemap).get("alg_name")).contains("识别")) {
                            if (StringUtils.isNotEmpty(imageUrl)) {
                                asf = fileName + "缺陷告警.jpg";
                                json = this.ftpFilePath(imageUrl, algName, patrolResult.getDeviceId(), asf);
                                pictureDefect = "      \"pic_defect\": \"" + json + "\"\n";
                            }
                        } else if (((String) ((Map<?, ?>) algNamemap).get("alg_name")).contains("判别") && StringUtils.isNotEmpty(imageUrl)) {
                            asf = fileName;
                            fileName = fileName + "判别告警.jpg";
                            json = this.ftpFilePath(imageUrl, algName, patrolResult.getDeviceId(), fileName);
                            pictureDifferent = "      \"pic_different\": \"" + json + "\"\n";
                            Map<String, String> pointInfoMap = this.resultAnalysisMapper.selectPointInfoById(objectId);
                            String filePanpath = "";
                            if (pointInfoMap != null && StringUtils.isNotEmpty(pointInfoMap.get("dis_ref_picture_path"))) {
                                filePanpath = pointInfoMap.get("dis_ref_picture_path");
                                if (StringUtils.isNotEmpty(filePanpath)) {
                                    asf = asf + "判别基准.jpg";
                                    filePanpath = this.ftpFilePath(filePanpath, algName, patrolResult.getDeviceId(), asf);
                                }
                            }

                            pictureDiffBase = "\"pic_diff_base\": \"" + filePanpath + "\"\n";
                        }
                    }

                    if (StringUtils.isNotEmpty(pictureDefect)) {
                        pictureDefect = StringUtils.COMMA + pictureDefect;
                    }

                    if (StringUtils.isNotEmpty(pictureDifferent)) {
                        pictureDifferent = StringUtils.COMMA + pictureDifferent + StringUtils.COMMA;
                    }

                    String date = DateUtils.format(DateUtils.yyyyMMddHHmmss2, new Date());
                    json = "{\n   \"province_name\":\"" + provinceName
                            + "\",\n   \"city_name\":\"" + city_name
                            + "\",\n   \"volt_level\":" + voltLevel
                            + ",\n   \"station_name\":\"" + spaceUnit
                            + "\",\n   \"station_ip\":\"" + stationIp
                            + "\",\n   \"node_id\":\"" + node_id
                            + "\",\n   \"msg_type\":\"alarm\",\n   \"alarm\":[\n   {\n      \"bay_name\":\"" + bay_name
                            + "\",\n      \"device_name\":\"" + deviceName
                            + "\",\n      \"point_name\":\"" + point_name
                            + "\",\n      \"time\":\"" + date
                            + "\",\n      \"defect\":[\n      {\n         \"type\":\"" + type
                            + "\",\n" + stringSub
                            + "   \"confidence\":" + conf
                            + ",\n         \"desc\":\"" + desc
                            + "\"\n      }],\n      \"different\":[{" + stringSub
                            + "}],\n      \"pic_width\":1920,\n      \"pic_height\":1080,\n      \"pic_raw\": \"" + newPicDir
                            + "\"\n" + pictureDefect + pictureDifferent + pictureDiffBase
                            + "   }]\n}\n";
                    this.mqttUtil.publish(1, "nodes/java/user/alert/2", json);
                    System.out.println("Alarm json: " + json);
                    return;
                }

                Pos pos = iterator.next();
                areas = pos.getAreas();
            } while (areas.length == 0);

            for (String area : areas) {
                JSONObject xObject = JSONObject.parseObject(area);
                String textX = xObject.get("x").toString();
                String textY = xObject.get("y").toString();
                stringBuilder
                        .append("         \"x")
                        .append(index)
                        .append("\":")
                        .append(textX)
                        .append(",\n         \"y")
                        .append(index)
                        .append("\":")
                        .append(textY)
                        .append(",\n");
                ++index;
            }
        }
    }

    public void messageArrived(String topic, MqttMessage message) throws Exception {
        System.out.println("message Topic: " + topic);
        System.out.println("message Qos:" + message.getQos());
        System.out.println("message Content:" + new String(message.getPayload()));
    }

    public void connectionLost(Throwable throwable) {
        System.out.println("CONNECTION LOST, PLEASE RECONNECT!");
    }

    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
    }

    public static InputStream readFile(String url) {
        URLConnection urlConnection;
        try {
            if (!url.startsWith("http")) {
                return null;
            }

            URL urlObj = new URL(url);
            urlConnection = urlObj.openConnection();
            urlConnection.setConnectTimeout(30000);
            urlConnection.setReadTimeout('\uea60');
            urlConnection.setDoInput(true);
            return urlConnection.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("获取文件流异常！");
            return null;
        } finally {
            IOUtils.closeQuietly(null);
        }
    }

    public String ftpFilePath(String str, String typeName, String pointId, String fileName) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        this.patrolResultMapper.selectBaseInfoByPointId(pointId);
        Map<String, String> station = this.patrolResultMapper.selectBasedataStation();
        String stpathfile = "";
        String filepp = "";
        PatrolTaskFtp xzzjFtp = this.patrolTaskFtpMapper.selectPatrolTaskFtpByLineId(2L);
        PatrolTaskFtp znfxFtp = this.patrolTaskFtpMapper.selectPatrolTaskFtpByLineId(1L);
        List<String> path = new ArrayList<>();
        filepp = station.get("province_name") + "/";
        path.add(filepp);
        filepp = filepp + station.get("city_name") + "/";
        path.add(filepp);
        filepp = filepp + station.get("station_no") + "/";
        path.add(filepp);
        switch (typeName) {
            case "缺陷识别":
                filepp = filepp + "缺陷识别/";
                path.add(filepp);
                break;
            case "缺陷判别":
                filepp = filepp + "缺陷判别/";
                path.add(filepp);
                break;
            case "状态识别":
                filepp = filepp + "状态识别/";
                path.add(filepp);
                break;
        }

        filepp = filepp + sdf.format(new Date()) + "/";
        path.add(filepp);
        String[] sta = str.split(StringUtils.COMMA);
        for (String ignored : sta) {
            stpathfile = filepp + fileName;
        }

        return stpathfile;
    }

    public static String getPinyin(String china) {
        HanyuPinyinOutputFormat hanyuPinyinOutputFormat = new HanyuPinyinOutputFormat();
        hanyuPinyinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        hanyuPinyinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        hanyuPinyinOutputFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
        char[] arrays = china.trim().toCharArray();
        StringBuilder result = new StringBuilder();

        try {
            for (char ti : arrays) {
                if (Character.toString(ti).matches("[\\u4e00-\\u9fa5]")) {
                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(ti, hanyuPinyinOutputFormat);
                    result.append(temp[0]);
                } else {
                    result.append(ti);
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination combination) {
            combination.printStackTrace();
        }

        return result.toString();
    }
}
