package com.gyee.frame.controller.file;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 升压站服务
 *
 * @author xysn
 */
@Component
public class BoostStationSvc {

    /**
     * 自定义控件路径
     */
    private final String CUSTOMIZE_PATH = "shapes\\customize_shapes.json";
    /**
     * 升压站信息
     */
    private final String BOOST_STATION_PATH = "shapes\\boost_station_infos.json";
    /**
     * 二次图信息
     */
    private final String SUB_STATION_PATH = "shapes\\sub_station_infos.json";
    /**
     * svg文件地址
     */
    private final String SVG_PATH = "shapes\\svg\\";

    /**
     * 自定义控件集合
     */
    private Map<String, ShapeInfo> customizeShapes;

    /**
     * 升压站
     */
    private Map<String, ShapeInfo> boostStationInfos;

    /**
     * 二次图
     */
    private Map<String, ShapeInfo> subShapeInfos;

    /**
     * 最大升压站序号
     */
    private int maxIndex;

    public Map<String, ShapeInfo> getBoostStationInfos() {
        if (boostStationInfos == null) {
            initBoostStation();
        }
        return boostStationInfos;
    }

    public Map<String, ShapeInfo> getCustomizeShapesMap() {
        if (customizeShapes == null) {
            initCustomize();
        }
        return customizeShapes;
    }

    public Map<String, ShapeInfo> getSubShapeInfos() {
        if (subShapeInfos == null) {
            initSubStation();
        }
        return subShapeInfos;
    }

    /**
     * 获取所有用户自定义控件
     *
     * @return 所有用户自定义控件
     */
    public Collection<ShapeInfo> getCustomizeShapes() {
        final Map<String, ShapeInfo> infos = getCustomizeShapesMap();

        return infos.values();
    }

    private void initCustomize() {
        System.out.println("初始化自定义图形信息...");

        ShapeInfo[] ls = getShapeInfosFromFile(CUSTOMIZE_PATH);
        if (ls == null) {
            customizeShapes = new HashMap<>();
            return;
        }
        customizeShapes = Arrays.stream(ls).collect(Collectors.toMap(ShapeInfo::getId, ss -> ss));

        System.out.println("自定义图形信息初始化结束");
    }

    /**
     * 添加自定义图形
     *
     * @param info 图形信息
     * @return
     */
    public boolean addCustomizeShape(ShapeInfo info) {
        final Map<String, ShapeInfo> infos = getCustomizeShapesMap();

        try {
            String str = JSON.toJSONString(infos.values());
            boolean b = writToFile(CUSTOMIZE_PATH + System.currentTimeMillis(), str);
            if (!b) {
                return false;
            }
            infos.put(info.getId(), info);
            String str2 = JSON.toJSONString(infos.values());
            return writToFile(CUSTOMIZE_PATH, str2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 移除自定义控件
     *
     * @param id 控件ID
     * @return
     */
    public String removeCustomizeShape(String id) {
        final Map<String, ShapeInfo> infos = getCustomizeShapesMap();
        if (!infos.containsKey(id)) {
            return "没有id为" + id + "的自定义控件";
        }

        try {
            ShapeInfo osi = infos.get(id);
            String str = JSON.toJSONString(infos.values());
            boolean b = writToFile(CUSTOMIZE_PATH + System.currentTimeMillis(), str);
            if (!b) {
                return "控件移除失败：备份失败";
            }
            infos.remove(id);
            String str2 = JSON.toJSONString(infos.values());
            b = writToFile(CUSTOMIZE_PATH, str2);
            if (!b) {
                infos.put(id, osi);
                return "保存失败";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

    /**
     * 从文件获取图形信息
     *
     * @param path 路径
     * @return 图形信息
     */
    private ShapeInfo[] getShapeInfosFromFile(String path) {
        BufferedReader bufferedReader = null;
        try {
            File file = new File(path);
            bufferedReader = new BufferedReader(new FileReader(file));
            StringBuilder sb = new StringBuilder();
            String s = null;
            while ((s = bufferedReader.readLine()) != null) {
                sb.append(s);
            }
            return JSONArray.parseObject(sb.toString(), ShapeInfo[].class);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 添加或更新升压站信息
     *
     * @param info 升压站信息
     */
    public boolean updateBoostStationInfos(ShapeInfo info) {
        final Map<String, ShapeInfo> infos = getBoostStationInfos();

        try {
            String str = JSON.toJSONString(infos.values());
            boolean b = writToFile(BOOST_STATION_PATH + System.currentTimeMillis(), str);
            if (!b) {
                return false;
            }
            if (infos.containsKey(info.getId())) {
                info.setIndex(infos.get(info.getId()).getIndex());
            } else {
                info.setIndex(++maxIndex);
            }
            infos.put(info.getId(), info);
            String str2 = JSON.toJSONString(infos.values());
            return writToFile(BOOST_STATION_PATH, str2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 删除升压站
     *
     * @param id 升压站ID
     * @return 是否成功
     */
    public boolean removeBoostStationInfos(String id) {
        final Map<String, ShapeInfo> infos = getBoostStationInfos();

        try {
            String str = JSON.toJSONString(infos.values());
            boolean b = writToFile(BOOST_STATION_PATH + System.currentTimeMillis(), str);
            if (!b) {
                return false;
            }
            if (infos.containsKey(id)) {
                infos.remove(id);
            }
            String str2 = JSON.toJSONString(infos.values());
            return writToFile(BOOST_STATION_PATH, str2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 获取升压站信息
     *
     * @return 升压站信息
     */
    public Collection<ShapeInfo> getShapeInfos() {
        final Map<String, ShapeInfo> infos = getBoostStationInfos();
        List<ShapeInfo> ls = new ArrayList<>(infos.values());
        ls.sort(Comparator.comparingInt(ShapeInfo::getIndex));
        return ls;
    }


    /**
     * 根据id获取升压站信息
     *
     * @param id 场站id
     */
    public ShapeInfo getBoostStationInfo(String id) {
        final Map<String, ShapeInfo> infos = getBoostStationInfos();
        if (infos.containsKey(id)) {
            return infos.get(id);
        }
        return null;
    }

    /**
     * 初始化升压站信息
     */
    private void initBoostStation() {

        System.out.println("初始化升压站图形信息...");

        ShapeInfo[] ls = getShapeInfosFromFile(BOOST_STATION_PATH);
        if (ls == null) {
            boostStationInfos = Maps.newLinkedHashMap();
            return;
        }
        final Optional<Integer> index = Arrays.stream(ls).max(Comparator.comparingInt(ShapeInfo::getIndex)).map(ShapeInfo::getIndex);
        index.ifPresent(integer -> maxIndex = integer);
        boostStationInfos = Arrays.stream(ls).collect(Collectors.toMap(ShapeInfo::getId, ss -> ss));

        System.out.println("升压站图形信息初始化结束");
    }

    /**
     * 获取二次图信息
     *
     * @param id 二次图ID
     * @return 二次图信息
     */
    public ShapeInfo getSubShapeInfo(String id) {
        final Map<String, ShapeInfo> infos = getSubShapeInfos();
        if (infos.containsKey((id))) {
            return infos.get(id);
        }
        return null;
    }

    /**
     * 移除二次图
     *
     * @param id 二次图ID
     * @return
     */
    public String removeSubStation(String id) {
        final Map<String, ShapeInfo> infos = getSubShapeInfos();

        if (!infos.containsKey(id)) {
            return "没有名称为" + id + "的二次图";
        }

        try {
            ShapeInfo osi = infos.get(id);
            String str = JSON.toJSONString(infos.values());
            boolean b = writToFile(SUB_STATION_PATH + System.currentTimeMillis(), str);
            if (!b) {
                return "二次图移除失败：备份失败";
            }
            infos.remove(id);
            String str2 = JSON.toJSONString(infos.values());
            b = writToFile(SUB_STATION_PATH, str2);
            if (!b) {
                infos.put(id, osi);
                return "保存失败";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

    /**
     * 初始化二次图
     */
    private void initSubStation() {
        System.out.println("初始化升压站二次图信息...");

        ShapeInfo[] ls = getShapeInfosFromFile(SUB_STATION_PATH);
        if (ls == null) {
            subShapeInfos = new HashMap<>();
            return;
        }
        subShapeInfos = Arrays.stream(ls).collect(Collectors.toMap(ShapeInfo::getId, ss -> ss));

        System.out.println("升压站二次图信息初始化结束");
    }


    /**
     * 添加或更新二次图信息
     *
     * @param info 二次图信息
     */
    public boolean updateSubStationInfos(ShapeInfo info) {
        final Map<String, ShapeInfo> infos = getSubShapeInfos();
        try {
            String str = JSON.toJSONString(infos.values());
            boolean b = writToFile(SUB_STATION_PATH + System.currentTimeMillis(), str);
            if (!b) {
                return false;
            }

            infos.put(info.getId(), info);
            String str2 = JSON.toJSONString(infos.values());
            return writToFile(SUB_STATION_PATH, str2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 写入文件
     */
    private boolean writToFile(String path, String val) {
        BufferedWriter bufferedWriter = null;
        try {
            File file = new File(path);
            File pf = file.getParentFile();
            if (!pf.exists()) {
                boolean b = pf.mkdirs();
            }
            bufferedWriter = new BufferedWriter(new FileWriter(file));
            bufferedWriter.write(val);
            bufferedWriter.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 保存svg文件，如果存在则覆盖
     */
    public String addSvgFile(SvgFileInfo svg) {
        String id = svg.getId();
        if (id == null || "".equals(id)) {
            return "svg文件id不能为空";
        }
        BufferedWriter bufferedWriter = null;
        try {
            File pf = new File(SVG_PATH);
            if (!pf.exists()) {
                boolean b = pf.mkdirs();
            }
            File f = new File(SVG_PATH + svg.getId() + ".svg");
            bufferedWriter = new BufferedWriter(new FileWriter(f));
            bufferedWriter.write(svg.getValue());
            bufferedWriter.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return "保存文件出现错误：" + e.getMessage();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }

    /**
     * 获取svg文件
     */
    public String getSvgFile(String id) {
        BufferedReader bufferedReader = null;
        try {
            File file = new File(SVG_PATH + id + ".svg");
            System.out.println(file.getAbsolutePath());
            if (!file.exists()) {
                return "";
            }
            bufferedReader = new BufferedReader(new FileReader(file));
            StringBuilder sb = new StringBuilder();
            String s = null;
            while ((s = bufferedReader.readLine()) != null) {
                sb.append(s);
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 添加触发器和标签
     */
    public String addSvgInfo(SvgInfo info) {
        String id = info.getId();
        if (id == null || "".equals(id)) {
            return "触发器和标签id不能为空";
        }
        BufferedWriter bufferedWriter = null;
        try {
            File pf = new File(SVG_PATH);
            if (!pf.exists()) {
                boolean b = pf.mkdirs();
            }
            File f = new File(SVG_PATH + info.getId() + ".info");
            String val = JSON.toJSONString(info);
            bufferedWriter = new BufferedWriter(new FileWriter(f));
            bufferedWriter.write(val);
            bufferedWriter.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return "保存文件出现错误：" + e.getMessage();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }

    /**
     * 获取svg测点和触发器
     */
    public SvgInfo getSvgInfo(String id) {
        BufferedReader bufferedReader = null;
        try {
            File file = new File(SVG_PATH + id + ".info");
            if (!file.exists()) {
                return null;
            }
            bufferedReader = new BufferedReader(new FileReader(file));
            StringBuilder sb = new StringBuilder();
            String s = null;
            while ((s = bufferedReader.readLine()) != null) {
                sb.append(s);
            }
            return JSON.parseObject(sb.toString(), SvgInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
