package com.njcn;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.njcn.csdevice.api.CsDeviceUserFeignClient;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.pojo.dto.CsLineDTO;
import com.njcn.csdevice.pojo.param.UserDevParam;
import com.njcn.csdevice.pojo.po.CsDeviceUserPO;
import com.njcn.csharmonic.api.RStatLimitRateDFeignClient;
import com.njcn.csharmonic.pojo.param.RStatLimitQueryParam;
import com.njcn.csharmonic.pojo.po.CsEventUserPO;
import com.njcn.csharmonic.pojo.po.CsHarmonic;
import com.njcn.csharmonic.pojo.po.RStatLimitRateDPO;
import com.njcn.cssystem.CsSystemBootApplication;
import com.njcn.harmonic.pojo.param.StatSubstationBizBaseParam;
import com.njcn.user.api.AppUserFeignClient;
import com.njcn.user.pojo.po.User;
import lombok.SneakyThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = CsSystemBootApplication.class)
public class ZipTest {

    private static final int BUFFER_SIZE = 4096;

    @Resource
    private CsLineFeignClient csLineFeignClient;
    @Resource
    private RStatLimitRateDFeignClient rStatLimitRateDClient;
    @Resource
    private CsDeviceUserFeignClient csDeviceUserFeignClient;
    @Resource
    private AppUserFeignClient appUserFeignClient;

    @SneakyThrows
    @Test
    public void test11() {

        List<CsHarmonic> list1 = new ArrayList<>();
        List<CsEventUserPO> list2 = new ArrayList<>();
        //获取所有监测点
        List<CsLineDTO> allLine = csLineFeignClient.getAllLineDetail().getData();
        if (CollUtil.isNotEmpty(allLine)) {
            //监测点id集合
            List<String> lineList = allLine.stream().map(CsLineDTO::getDeviceId).distinct().collect(Collectors.toList());
            //设备id集合
            List<String> devList = allLine.stream().map(CsLineDTO::getDeviceId).distinct().collect(Collectors.toList());
            //获取监测点和设备关系
            Map<String,String> lineDevMap = allLine.stream().collect(Collectors.toMap(CsLineDTO::getLineId,CsLineDTO::getDeviceId));

            //获取设备和用户关系
            UserDevParam param = new UserDevParam();
            param.setList(devList);
            List<CsDeviceUserPO> userList = csDeviceUserFeignClient.getList(param).getData();
            //根据设备id分组 组是subUserId的集合
            Map<String, List<String>> userDevMap = userList.stream().collect(Collectors.groupingBy(
                    CsDeviceUserPO::getDeviceId,
                    Collectors.mapping(
                            CsDeviceUserPO::getSubUserId,
                            Collectors.toList()
                    )
            ));
            //获取管理员信息
            List<User> adminList = appUserFeignClient.getAdminInfo().getData();
            //获取用户id集合
            List<String> userIdList = adminList.stream().map(User::getId).collect(Collectors.toList());

            //获取越限数据
            StatSubstationBizBaseParam rateLine = new StatSubstationBizBaseParam();
            rateLine.setIds(lineList);
            String date = DateUtil.yesterday().toString(DatePattern.NORM_DATE_PATTERN);
            rateLine.setStartTime(date);
            rateLine.setEndTime(date);

            RStatLimitQueryParam rStatLimitQueryParam = RStatLimitQueryParam.builder().ids(lineList).date(date).endDate(date).build();
            List<RStatLimitRateDPO> limitRates =  rStatLimitRateDClient.monitorIdsGetLimitRateInfo(rStatLimitQueryParam).getData();

            if (CollUtil.isNotEmpty(limitRates)) {
                limitRates.forEach(item->{
                    //新增cs_harmonic数据
                    String id = IdUtil.fastSimpleUUID();
                    CsHarmonic csharmonic = new CsHarmonic();
                    csharmonic.setId(id);
                    csharmonic.setLineId(item.getLineId());
                    csharmonic.setTime(LocalDate.parse(date));
                    csharmonic.setTag(buildOverlimitTag(item));
                    list1.add(csharmonic);

                    //根据监测点id获取设备
                    String deviceId = lineDevMap.get(item.getLineId());
                    //根据设备获取用户
                    List<String> userIds = userDevMap.get(deviceId);
                    //添加管理员用户
                    List<String> result = Stream.concat(userIdList.stream(), userIds.stream())
                            .distinct()
                            .collect(Collectors.toList());
                    result.forEach(userId->{
                        //新增cs_event_user数据
                        CsEventUserPO po = new CsEventUserPO();
                        po.setUserId(userId);
                        po.setEventId(id);
                        po.setStatus(0);
                        list2.add(po);
                    });
                });
            }
        }
        if (CollUtil.isNotEmpty(list1)) {
            System.out.println("list1==:" + list1);
            System.out.println("list2==:" + list2);
        }
    }

    @SneakyThrows
    @Test
    public void test() {
        String ZipFilePath = "C:\\Users\\徐扬\\Desktop\\test.zip";


        File zipFile = new File(ZipFilePath);
        ZipFile zip = new ZipFile(zipFile);

        //遍历zip文件中的所有条目
        Enumeration<? extends ZipEntry> entries = zip.entries();
        while (entries.hasMoreElements()) {
            //在这里执行后续操作
            ZipEntry entry = entries.nextElement();
            System.out.println(entry.getName());
            InputStream inputStream = zip.getInputStream(entry);
//            OutputStream outputStream = new FileOutputStream("path/to/output/file");
//            byte[] buffer = new byte[1024];int length;
//            while ((length = inputStream.read(buffer)) > 0) {
//                outputStream.write(buffer, 0, length);
//            }
//            outputStream.close();
            inputStream.close();
        }
    }

    public void unzip(String ZipFilePath, String DestFilePath) throws IOException {
        File Destination_Directory = new File(DestFilePath);
        if (!Destination_Directory.exists()) {
            Destination_Directory.mkdir();
        }
        ZipInputStream Zip_Input_Stream = new ZipInputStream(new FileInputStream(ZipFilePath));
        ZipEntry Zip_Entry = Zip_Input_Stream.getNextEntry();

        while (Zip_Entry != null) {
            String File_Path = DestFilePath + File.separator + Zip_Entry.getName();
            if (!Zip_Entry.isDirectory()) {
                extractFile(Zip_Input_Stream, File_Path);
            } else {
                File directory = new File(File_Path);
                directory.mkdirs();
            }
            Zip_Input_Stream.closeEntry();
            Zip_Entry = Zip_Input_Stream.getNextEntry();
        }
        Zip_Input_Stream.close();
    }

    private static void extractFile(ZipInputStream Zip_Input_Stream, String File_Path)
            throws IOException {
        BufferedOutputStream Buffered_Output_Stream =
                new BufferedOutputStream(new FileOutputStream(File_Path));
        byte[] Bytes = new byte[BUFFER_SIZE];
        int Read_Byte = 0;
        while ((Read_Byte = Zip_Input_Stream.read(Bytes)) != -1) {
            Buffered_Output_Stream.write(Bytes, 0, Read_Byte);
        }
        Buffered_Output_Stream.close();
    }


    /**
     * 构建越限标签字符串
     *
     * @param item 越限统计数据
     * @return 越限标签
     */
    private String buildOverlimitTag(RStatLimitRateDPO item) {
        String tag = "";

        // 基础越限项
        Integer freqDevOvertime = item.getFreqDevOvertime();
        if (freqDevOvertime > 0) {
            tag = tag + "频率偏差越限" + freqDevOvertime + "次,";
        }

        Integer voltageDevOvertime = item.getVoltageDevOvertime();
        if (voltageDevOvertime > 0) {
            tag = tag + "电压偏差越限" + voltageDevOvertime + "次,";
        }

        Integer ubalanceOvertime = item.getUbalanceOvertime();
        if (ubalanceOvertime > 0) {
            tag = tag + "三相电压不平衡度越限" + ubalanceOvertime + "次,";
        }

        Integer flickerOvertime = item.getFlickerOvertime();
        if (flickerOvertime > 0) {
            tag = tag + "闪变越限" + flickerOvertime + "次,";
        }

        Integer uaberranceOvertime = item.getUaberranceOvertime();
        if (uaberranceOvertime > 0) {
            tag = tag + "电压总谐波畸变率越限" + uaberranceOvertime + "次,";
        }

        Integer iNegOvertime = item.getINegOvertime();
        if (iNegOvertime > 0) {
            tag = tag + "负序电流越限" + iNegOvertime + "次,";
        }

        // 谐波电压含有率（2-25 次）
        tag = buildHarmonicVoltageTags(item, tag);

        // 谐波电流有效值（2-25 次）
        tag = buildHarmonicCurrentTags(item, tag);

        // 间谐波电压含有率（0.5-15.5 次）
        tag = buildInterharmonicVoltageTags(item, tag);

        // 去除末尾逗号
        return trimTrailingComma(tag);
    }

    /**
     * 批量构建谐波电压含有率 tag（2-25 次）
     *
     * @param item        数据对象
     * @param originalTag 原始 tag
     * @return 组装后的 tag
     */
    public static String buildHarmonicVoltageTags(Object item, String originalTag) {
        String tag = originalTag;
        for (int i = 2; i <= 25; i++) {
            String fieldName = "uharm" + i + "Overtime";
            Integer value = (Integer) ReflectUtil.getFieldValue(item, fieldName);
            if (value != null && value > 0) {
                tag = tag + i + "次谐波电压含有率越限" + value + "次,";
            }
        }
        return tag;
    }

    /**
     * 批量构建谐波电流有效值 tag（2-25 次）
     *
     * @param item        数据对象
     * @param originalTag 原始 tag
     * @return 组装后的 tag
     */
    public static String buildHarmonicCurrentTags(Object item, String originalTag) {
        String tag = originalTag;
        for (int i = 2; i <= 25; i++) {
            String fieldName = "iharm" + i + "Overtime";
            Integer value = (Integer) ReflectUtil.getFieldValue(item, fieldName);
            if (value != null && value > 0) {
                tag = tag + i + "次谐波电流有效值越限" + value + "次,";
            }
        }
        return tag;
    }

    /**
     * 批量构建间谐波电压含有率 tag（0.5-15.5 次）
     *
     * @param item        数据对象
     * @param originalTag 原始 tag
     * @return 组装后的 tag
     */
    public static String buildInterharmonicVoltageTags(Object item, String originalTag) {
        String tag = originalTag;
        for (int i = 1; i <= 16; i++) {
            String fieldName = "inuharm" + i + "Overtime";
            Integer value = (Integer) ReflectUtil.getFieldValue(item, fieldName);
            if (value != null && value > 0) {
                double harmonicOrder = i * 1.0 - 0.5;
                tag = tag + harmonicOrder + "次间谐波电压含有率越限" + value + "次,";
            }
        }
        return tag;
    }

    /**
     * 去除字符串末尾的逗号
     *
     * @param str 原字符串
     * @return 处理后的字符串
     */
    public static String trimTrailingComma(String str) {
        return StrUtil.endWith(str, ",") ? StrUtil.subPre(str, str.length() - 1) : str;
    }


}
