package com.pqs9200.serviceimpl.advanced;

import cn.hutool.core.collection.CollectionUtil;
import com.njcn.enums.ResultStatusEnum;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.AppConfig;
import com.njcn.utils.PubUtils;
import com.njcn.utils.sagDomain.Complex;
import com.njcn.utils.sagDomain.DipZoneModel;
import com.njcn.utils.sagDomain.SagDomainUtils;
import com.pqs9200.mapper.advanced.SvgMapper;
import com.pqs9200.pojo.data.*;
import com.pqs9200.service.advanced.SvgService;
import com.pqs9200.utils.SagDomain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author hongawen
 * @version 1.0.0
 * @date 2021年12月07日 10:19
 */
@Service
public class SvgServiceImpl implements SvgService {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private SvgMapper svgMapper;

    @Override
    public String saveSvg(String fileName, String xml, String svg) throws IOException {
        String svgDirPath = appConfig.getTmppath() + File.separator + "svg" + File.separator + fileName ;
        File dirFile = new File(svgDirPath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
//        String xmlPath = svgDirPath + File.separator  + "svgDomain.xml";
//        String svgPath = svgDirPath + File.separator + "svgDomain.svg";
        String xmlPath = svgDirPath + File.separator  + fileName + ".xml";
        String svgPath = svgDirPath + File.separator + fileName + ".svg";
        File xmlFile = new File(xmlPath);
        if (!xmlFile.exists()) {
            xmlFile.createNewFile();
        }
        FileWriter xmlWriter = new FileWriter(xmlPath);
        xmlWriter.write(xml);
        xmlWriter.flush();
        xmlWriter.close();
        File svgFile = new File(svgPath);
        if (!svgFile.exists()) {
            svgFile.createNewFile();
        }
        FileWriter svgWriter = new FileWriter(svgPath);
        svgWriter.write(svg);
        svgWriter.flush();
        svgWriter.close();
        return ResultStatusEnum.SUCCESS.getMessage();
    }

    @Override
    public String loadSvg(String index,String type) throws IOException {
        String xml;
        String svgDirPath = appConfig.getTmppath() + File.separator + "svg"  + File.separator + index;
        File dirFile = new File(svgDirPath);
        if (!dirFile.exists()) {
            return ResultStatusEnum.NO_SVG_FILE.getMessage();
        }
        File[] files = dirFile.listFiles();
        if (null == files) {
            return ResultStatusEnum.NO_SVG_FILE.getMessage();
        }
        List<File> fileList = Stream.of(files).filter(file -> file.getName().endsWith(type)).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(fileList)) {
            return ResultStatusEnum.NO_SVG_FILE.getMessage();
        } else {
            //默认读取第一xml文件的内容，除非指定文件名
            File xmlFile = fileList.get(0);
            List<String> lines = Files.readAllLines(Paths.get(xmlFile.getPath()),
                    StandardCharsets.UTF_8);
            xml = String.join("", lines);
        }
        return xml;
    }


    @Override
    public void saveCell(SvgCells svgCells) {
        Date time = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strUserGuid = TokenManager.getToken().getUserIndex();
        SvgCells cell = svgMapper.getSvgCells(svgCells.getCellIndex());
        if (Objects.isNull(cell)){
            svgCells.setCreateBy(strUserGuid);
            svgCells.setCreateTime(sbf.format(time));
            svgMapper.saveCell(svgCells);
        } else {
            svgCells.setCreateBy(cell.getCreateBy());
            svgCells.setCreateTime(cell.getCreateTime());
            svgCells.setUpdateBy(strUserGuid);
            svgCells.setUpdateTime(sbf.format(time));
            svgMapper.updateCell(svgCells);
        }
    }

    @Override
    public SvgCells getCell(Integer cellIndex) {
        return svgMapper.getSvgCells(cellIndex);
    }

    @Override
    public void saveAllCells(SvgAllCells svgAllCells) {
        Date time = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strUserGuid = TokenManager.getToken().getUserIndex();
        List<Integer> lineArr = svgAllCells.getLineArr();
        if (!CollectionUtils.isEmpty(lineArr)){
            for (Integer id : lineArr) {
                SvgCells cell = svgMapper.getSvgCells(id);
                if (Objects.isNull(cell)){
                    SvgCells svgCells = new SvgCells();
                    svgCells.setCellIndex(id);
                    svgCells.setCellName("电缆");
                    svgCells.setCableLength(1f);
                    svgCells.setCellLevel(110f);
                    svgCells.setPositiveSequenceResistance(0.132f);
                    svgCells.setPositiveSequenceReactance(0.388f);
                    svgCells.setZeroSequenceResistance(0.33f);
                    svgCells.setZeroSequenceReactance(0.97f);
                    svgCells.setCoefficient(2.5f);
                    svgCells.setCellType(1);
                    svgCells.setWiringDiagram("/");
                    svgCells.setCreateBy(strUserGuid);
                    svgCells.setCreateTime(sbf.format(time));
                    svgCells.setRunLevel(0f);
                    svgCells.setState(1);
                    svgMapper.saveCell(svgCells);
                }
            }
        }

        List<Integer> sensitiveArr = svgAllCells.getSensitiveArr();
        if (!CollectionUtils.isEmpty(sensitiveArr)){
            for (Integer id : sensitiveArr) {
                SvgCells cell = svgMapper.getSvgCells(id);
                if (Objects.isNull(cell)){
                    SvgCells svgCells = new SvgCells();
                    svgCells.setCellIndex(id);
                    svgCells.setCellName(id.toString());
                    svgCells.setCableLength(0f);
                    svgCells.setCellLevel(110f);
                    svgCells.setPositiveSequenceResistance(0f);
                    svgCells.setPositiveSequenceReactance(0f);
                    svgCells.setZeroSequenceResistance(0f);
                    svgCells.setZeroSequenceReactance(0f);
                    svgCells.setCoefficient(0f);
                    svgCells.setCellType(2);
                    svgCells.setWiringDiagram("/");
                    svgCells.setCreateBy(strUserGuid);
                    svgCells.setCreateTime(sbf.format(time));
                    svgCells.setRunLevel(0f);
                    svgCells.setState(1);
                    svgMapper.saveCell(svgCells);
                }
            }
        }

        List<Integer> substationArr = svgAllCells.getSubstationArr();
        if (!CollectionUtils.isEmpty(substationArr)){
            for (Integer id : substationArr) {
                SvgCells cell = svgMapper.getSvgCells(id);
                if (Objects.isNull(cell)){
                    SvgCells svgCells = new SvgCells();
                    svgCells.setCellIndex(id);
                    svgCells.setCellName(id.toString());
                    svgCells.setCableLength(0f);
                    svgCells.setCellLevel(110f);
                    svgCells.setPositiveSequenceResistance(0f);
                    svgCells.setPositiveSequenceReactance(0f);
                    svgCells.setZeroSequenceResistance(0f);
                    svgCells.setZeroSequenceReactance(0f);
                    svgCells.setCoefficient(0f);
                    svgCells.setCellType(3);
                    svgCells.setWiringDiagram("/");
                    svgCells.setCreateBy(strUserGuid);
                    svgCells.setCreateTime(sbf.format(time));
                    svgCells.setRunLevel(110f);
                    svgCells.setState(1);
                    svgMapper.saveCell(svgCells);
                }
            }
        }

        List<Integer> powerArr = svgAllCells.getPowerArr();
        if (!CollectionUtils.isEmpty(powerArr)){
            for (Integer id : powerArr) {
                SvgCells cell = svgMapper.getSvgCells(id);
                if (Objects.isNull(cell)){
                    SvgCells svgCells = new SvgCells();
                    svgCells.setCellIndex(id);
                    svgCells.setCellName(id.toString());
                    svgCells.setCableLength(0f);
                    svgCells.setCellLevel(0f);
                    svgCells.setPositiveSequenceResistance(0.132f);
                    svgCells.setPositiveSequenceReactance(0.388f);
                    svgCells.setZeroSequenceResistance(0.33f);
                    svgCells.setZeroSequenceReactance(0.97f);
                    svgCells.setCoefficient(2.5f);
                    svgCells.setCellType(4);
                    svgCells.setWiringDiagram("/");
                    svgCells.setCreateBy(strUserGuid);
                    svgCells.setCreateTime(sbf.format(time));
                    svgCells.setRunLevel(0f);
                    svgCells.setState(1);
                    svgMapper.saveCell(svgCells);
                }
            }
        }

        List<Integer> transformerArr = svgAllCells.getTransformerArr();
        if (!CollectionUtils.isEmpty(transformerArr)){
            for (Integer id : transformerArr) {
                SvgCells cell = svgMapper.getSvgCells(id);
                if (Objects.isNull(cell)){
                    SvgCells svgCells = new SvgCells();
                    svgCells.setCellIndex(id);
                    svgCells.setCellName(id.toString());
                    svgCells.setCableLength(0f);
                    svgCells.setCellLevel(110f);
                    svgCells.setPositiveSequenceResistance(0.132f);
                    svgCells.setPositiveSequenceReactance(0.388f);
                    svgCells.setZeroSequenceResistance(0.33f);
                    svgCells.setZeroSequenceReactance(0.97f);
                    svgCells.setCoefficient(2.5f);
                    svgCells.setCellType(5);
                    svgCells.setWiringDiagram("/");
                    svgCells.setCreateBy(strUserGuid);
                    svgCells.setCreateTime(sbf.format(time));
                    svgCells.setRunLevel(0f);
                    svgCells.setState(1);
                    svgMapper.saveCell(svgCells);
                }
            }
        }
        //清理多余的图元信息
        List<Integer> list = new ArrayList<>();
        list.addAll(lineArr);
        list.addAll(sensitiveArr);
        list.addAll(substationArr);
        list.addAll(powerArr);
        list.addAll(transformerArr);
        List<Integer> cellsList = svgMapper.getAllCellsId();
        cellsList.removeAll(list);
        if (!CollectionUtils.isEmpty(cellsList)){
            svgMapper.deleteCell(cellsList);
        }
    }

    @Override
    public List<SvgCells> getAllCells() {
        return  svgMapper.getAllCells();
    }

    @Override
    public DipZoneModel[] getSagDomain(SvgSagDomain svgSagDomain) {

        Map nodesMap = svgSagDomain.getNodesMap();
        List<String> lines_substation = svgSagDomain.getLines_substation();
        List<String> lines_transformer = svgSagDomain.getLines_transformer();
        /// <summary>
        /// 正序阻抗矩阵
        /// 首段节点号 末端节点号  支路电阻  支路电抗 对地导纳
        /// </summary>
        int iNodeCount = nodesMap.size();//节点数量
        int iLineCount = lines_substation.size();
        int iAllCount = iLineCount + lines_transformer.size();//线路数量（线路+变压器）
        double [][] Z1=new double[iAllCount][6];
        // 零序阻抗矩阵
        double [][] Z0=new double[iAllCount][5];

        String[] splitNodes;//元素分割线
        Integer nodesId = 0;//元素Id
        Integer startId = 0;//起始Id
        Integer endId = 0;//结束Id
        double resistance = 0.0,reactance = 0.0,admittance = 0.0;//电阻，电抗，导纳
        String tmpLineValue;//前端求得的string值
        for(int i = 0;i < iAllCount; i++){
            //主线线路
            if (i < iLineCount){
                tmpLineValue = lines_substation.get(i);
                splitNodes =tmpLineValue.split("&");
                //长度为2
                if (splitNodes.length == 2){
                    String[] tmpSplitNodes = splitNodes[0].split("->");//元素分割线
                    if (tmpSplitNodes.length == 2){
                        nodesId = Integer.parseInt(splitNodes[1]);
                        startId = (Integer) nodesMap.get(tmpSplitNodes[0]);//通过Map做映射
                        endId = (Integer) nodesMap.get(tmpSplitNodes[1]);//通过Map做映射
                    }
                }
                //通过元素Id获取实体类
                SvgCells tmpSvgCells =getCell(nodesId);

                //电阻 =线路长度×单位电阻
                resistance = tmpSvgCells.getCableLength() * tmpSvgCells.getPositiveSequenceResistance();
                //电抗 =线路长度×单位电抗
                reactance = tmpSvgCells.getCableLength() * tmpSvgCells.getPositiveSequenceReactance();
                //对地导纳 = 2.8×10-6×线路长度
                admittance = tmpSvgCells.getCableLength() * 2.8 * 1e-6;
                //10Kv
                if(tmpSvgCells.getCellLevel() == 10){
                    //电阻 =线路长度×单位电阻
                    resistance = resistance * Math.pow(10.0/110.0,2);
                    //电抗 =线路长度×单位电抗
                    reactance = reactance * Math.pow(10.0/110.0,2);
                    //对地导纳 = 2.8×10-6×线路长度
                    admittance = admittance * Math.pow(110.0/10.0,2);
                }
                Z1[i][0] = startId;
                Z1[i][1] = endId;
                Z1[i][2] = PubUtils.doubleRound(6,resistance);
                Z1[i][3] = PubUtils.doubleRound(6,reactance);
                Z1[i][4] = PubUtils.doubleRound(6,admittance);
                Z1[i][5] = tmpSvgCells.getCableLength();//长度

                //Z0为Z1的2.5倍
                Z0[i][0] = startId;
                Z0[i][1] = endId;
                Z0[i][2] = PubUtils.doubleRound(6,resistance* tmpSvgCells.getCoefficient());
                Z0[i][3] = PubUtils.doubleRound(6,reactance* tmpSvgCells.getCoefficient());
                Z0[i][4] = PubUtils.doubleRound(6,admittance* tmpSvgCells.getCoefficient());
            }
            //变压器支线线路
            else{
                tmpLineValue = lines_transformer.get(i - iLineCount);
                splitNodes =tmpLineValue.split("&");
                //长度为2
                if (splitNodes.length == 2){
                    String[] tmpSplitNodes = splitNodes[0].split("->");//元素分割线
                    if (tmpSplitNodes.length == 2){
                        nodesId = Integer.parseInt(splitNodes[1]);
                        startId = (Integer) nodesMap.get(tmpSplitNodes[0]);//通过Map做映射
                        endId = (Integer) nodesMap.get(tmpSplitNodes[1]);//通过Map做映射
                    }
                }
                //通过元素Id获取实体类
                SvgCells tmpSvgCells =getCell(nodesId);

                //电阻 = 电阻
                resistance = tmpSvgCells.getPositiveSequenceResistance();
                //电抗 = 电抗
                reactance = tmpSvgCells.getPositiveSequenceReactance();
                //对地导纳 = 直接取正序导纳
                admittance = tmpSvgCells.getPositiveAdmittance();

                Z1[i][0] = startId;
                Z1[i][1] = endId;
                Z1[i][2] = PubUtils.doubleRound(6,resistance);
                Z1[i][3] = PubUtils.doubleRound(6,reactance);
                Z1[i][4] = PubUtils.doubleRound(6,admittance);

                //Z0为Z1的2.5倍
                Z0[i][0] = startId;
                Z0[i][1] = endId;
                Z0[i][2] = PubUtils.doubleRound(6,resistance * tmpSvgCells.getCoefficient());
                Z0[i][3] = PubUtils.doubleRound(6,reactance * tmpSvgCells.getCoefficient());
                Z0[i][4] = PubUtils.doubleRound(6,tmpSvgCells.getZeroAdmittance());
            }
        }

        Complex[] Vpre =new  Complex[nodesMap.size()];
        //赋值
        for(int i =0; i < nodesMap.size();i++){
            Complex complex =new Complex(0,0);
            Vpre[i] = complex;
        }
        //计算故障前故障点电压
        for (Object key : nodesMap.keySet()) {
            int iKey = Integer.parseInt(key.toString());
            int iValue = Integer.parseInt(nodesMap.get(key.toString()).toString());
            //通过元素Id获取实体类
            SvgCells tmpSvgCells =getCell(iKey);
            double runVoltage = (double)tmpSvgCells.getRunLevel();//运行电压
            double nominalVoltage = (double)tmpSvgCells.getCellLevel();//额定电压
            //赋值
            Vpre[iValue - 1] = SagDomainUtils.getVpre(runVoltage,nominalVoltage);
        }
        //开始进行暂降域计算
        SagDomain sagDomain =new SagDomain();
        int eventPoint = Integer.parseInt(nodesMap.get(svgSagDomain.getEventPoint().toString()).toString());
        DipZoneModel[] Usag_area = sagDomain.analysisSagDomain(svgSagDomain.getDip()/100.0,svgSagDomain.getEventType(),eventPoint,iNodeCount,iLineCount,Z1,Z0,Vpre);
        DipZoneModel[] Usag_Result =new DipZoneModel[Usag_area.length];
        //暂降域映射处理
        for (int i = 0;i < Usag_area.length; i++){
            DipZoneModel dipZoneModel = Usag_area[i];
            //计算故障前故障点电压
            for (Object key : nodesMap.keySet()) {
                int iKey = Integer.parseInt(key.toString());
                int iValue = Integer.parseInt(nodesMap.get(key.toString()).toString());
                if(iValue == dipZoneModel.head){
                    dipZoneModel.setHead(iKey);
                }
                if(iValue == dipZoneModel.tail){
                    dipZoneModel.setTail(iKey);
                }
             }
            Usag_Result[i] = dipZoneModel;
        }

        return Usag_Result;
    }
    @Override
    public void saveSensitivePoint(SvgSensitivePoint svgSensitivePoint) {
        int row = svgMapper.saveSensitivePoint(svgSensitivePoint);

    }

    @Override
    public List<SvgCalucateInfo> getAllCalucateInfo() {
        return svgMapper.getAllCalucateInfo();
    }

    @Override
    public int deleteCalucateInfo(String index) {
        return svgMapper.deleteCalucateInfo(index);
    }

}
