package com.njcn.device.pq.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.njcn.device.pq.mapper.PqsProtectvalueMapper;
import com.njcn.device.pq.pojo.param.ConstantValueParam;
import com.njcn.device.pq.pojo.po.PqsProtectcontrolword;
import com.njcn.device.pq.pojo.po.PqsProtectvalue;
import com.njcn.device.pq.service.IPqsProtectcontrolwordService;
import com.njcn.device.pq.service.IPqsProtectvalueService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wr
 * @since 2023-08-10
 */
@Service
@RequiredArgsConstructor
public class PqsProtectvalueServiceImpl extends ServiceImpl<PqsProtectvalueMapper, PqsProtectvalue> implements IPqsProtectvalueService {

    private final IPqsProtectcontrolwordService iPqsProtectcontrolwordService;

    @Override
    public List<Object> quarryOutValueBase(String isOutIn, String lineIndex) {
        List<Object> quarryValue = new ArrayList<>();
        List<PqsProtectvalue> quarryOutValue = new ArrayList<>();//简谐波
        List<PqsProtectvalue> quarryOutValue1 = new ArrayList<>();//谐波电压
        List<PqsProtectvalue> quarryOutValue2 = new ArrayList<>();//谐波电流
        List<PqsProtectvalue> quarryOutValue3 = new ArrayList<>();//基本定值
        if (isOutIn.equals("out")) {  //外部定值
            List<PqsProtectvalue> constantValues = this.list(new LambdaQueryWrapper<PqsProtectvalue>()
                    .eq(PqsProtectvalue::getCpu_no, lineIndex));

            if (CollUtil.isNotEmpty(constantValues)) {
                //区分定值类型
                Map<Integer, List<PqsProtectvalue>> protectMap =
                        constantValues.stream().collect(Collectors.groupingBy(PqsProtectvalue::getDz_type));

                if (protectMap.containsKey(1)) {
                    quarryOutValue3.addAll(protectMap.get(1));
                }
                if (protectMap.containsKey(2)) {
                    quarryOutValue2.addAll(protectMap.get(2));
                }
                if (protectMap.containsKey(3)) {
                    quarryOutValue1.addAll(protectMap.get(3));
                }
                if (protectMap.containsKey(4)) {
                    quarryOutValue.addAll(protectMap.get(4));
                }

                quarryValue.add(quarryOutValue3);
                quarryValue.add(quarryOutValue2);
                quarryValue.add(quarryOutValue1);
                quarryValue.add(quarryOutValue);
            }
        } else if (isOutIn.equals("in")) { //内部定值
            List<PqsProtectvalue> constantValues = this.list(new LambdaQueryWrapper<PqsProtectvalue>()
                    .eq(PqsProtectvalue::getCpu_no, lineIndex));
            if (CollUtil.isNotEmpty(constantValues)) {
                quarryValue.add(constantValues);
            }
        }
        return quarryValue;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDatabaseValue(String json) {
        Map map = JSON.parseObject(json, Map.class);
        //区分内/外定值
        String type = map.get("type").toString();
        if (type.equals("80")) {//外部定值
            String cpuNo = map.get("cpu_no").toString();
            List<Float> inoutValue = JSONArray.parseArray(map.get("data").toString(), Float.class);
            for (int i = 0; i < inoutValue.size(); i++) {
                //进行外部定值的更正
                this.update(new LambdaUpdateWrapper<PqsProtectvalue>()
                        .set(PqsProtectvalue::getValue, inoutValue.get(i))
                        .eq(PqsProtectvalue::getCpu_no, cpuNo)
                        .like(PqsProtectvalue::getType, type)
                        .eq(PqsProtectvalue::getSort, i + 1)
                );
            }
            return true;
        } else if (type.equals("90")) {
            //内部定值
            String devIndex = map.get("devindex").toString();
            List<Integer> inoutValue = JSONArray.parseArray(map.get("data").toString(), Integer.class);
            for (int i = 0; i < inoutValue.size(); i++) {
                int value = inoutValue.get(i);
                if (i == inoutValue.size() - 1 || i == inoutValue.size() - 2) {
                    value = value / 100;
                    //进行内部定值的更正
                    this.update(new LambdaUpdateWrapper<PqsProtectvalue>()
                            .set(PqsProtectvalue::getValue, value)
                            .eq(PqsProtectvalue::getCpu_no, devIndex)
                            .like(PqsProtectvalue::getType, type)
                            .eq(PqsProtectvalue::getSort, i + 1)
                    );
                } else {
                    //进行内部定值的更正
                    this.update(new LambdaUpdateWrapper<PqsProtectvalue>()
                            .set(PqsProtectvalue::getValue, value)
                            .eq(PqsProtectvalue::getCpu_no, devIndex)
                            .like(PqsProtectvalue::getType, type)
                            .eq(PqsProtectvalue::getSort, i + 1)
                    );
                    //查询指定内部定级
                    PqsProtectvalue one = this.getOne(new LambdaQueryWrapper<PqsProtectvalue>()
                            .eq(PqsProtectvalue::getCpu_no, devIndex)
                            .eq(PqsProtectvalue::getType, type)
                            .eq(PqsProtectvalue::getSort, i + 1)
                    );
                    //根据装置类型和sort进行查询
                    String pvIndex = one.getPvIndex();
                    String property = Integer.toBinaryString(value);
                    int strLen = property.length();
                    if (strLen < 16) {
                        while (strLen < 16) {
                            StringBuffer sb = new StringBuffer();
                            sb.append("0").append(property);//左补0
                            property = sb.toString();
                            strLen = property.length();
                        }
                    }
                    char[] ar = property.toCharArray();
                    for (int j = 0; j < ar.length; j++) {
                        int flag = ar[j] - 48;
                        iPqsProtectcontrolwordService.update(new LambdaUpdateWrapper<PqsProtectcontrolword>()
                                .set(PqsProtectcontrolword::getPvIndex, pvIndex)
                                .eq(PqsProtectcontrolword::getTypeNum, (ar.length - 1) - j)
                                .like(PqsProtectcontrolword::getFlag, flag));
                    }
                }
            }
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDatabase(ConstantValueParam param) {
        Integer type = param.getType();
        ConstantValueParam.ConstantValue json = param.getJson();

        //获取方法类型methodname
        String methodName = json.getMethodname();
        List<PqsProtectvalue> inoutValue;
        //hander 用于匹配 0 定值 1 定值描述
        Integer hander = json.getHander();
        //用于判断内外定值 80外部定值 90内部定值
        if (hander == param.getHander()) {
            //终端id
            String devIndex = json.getDevindex();
            inoutValue = json.getData();

            PqsProtectvalue pqsProtectvalue = inoutValue.get(0);

            int isint = 0;//用于判断时候删除子表数据
            String devType2 = pqsProtectvalue.getDev_type();
            Integer type2 = pqsProtectvalue.getType();
            if (type == 90) {
                this.remove(new LambdaUpdateWrapper<PqsProtectvalue>()
                        .eq(PqsProtectvalue::getCpu_no, devIndex)
                        .like(PqsProtectvalue::getType, type2)

                );
                isint = 1;
            } else if (type == 80) {
                String lineIndex = json.getLineindex();
                isint = 0;
                this.remove(new LambdaUpdateWrapper<PqsProtectvalue>()
                        .eq(PqsProtectvalue::getCpu_no, lineIndex)
                        .like(PqsProtectvalue::getType, type2)

                );
            }
            List<PqsProtectvalue> addProtect = new ArrayList<>();
            List<PqsProtectcontrolword> addWord = new ArrayList<>();
            for (int i = 0; i < inoutValue.size(); i++) {
                //获取监测点序号、终端类型、定值类型、单位、最大值、最小值、默认值、设定值、描述
                String pvIndex = IdUtil.fastSimpleUUID();
                PqsProtectvalue protect = inoutValue.get(i);
                protect.setPvIndex(pvIndex);
                protect.setDz_type(protect.getType() == 80 ? protect.getDz_type() : 0);
                addProtect.add(protect);

                //获取内部定值控制字
                if (isint == 1) {
                    if (protect.getWord().size() > 1) {
                        protect.getWord().stream().peek(x->x.setPvIndex(pvIndex));
                        addWord.addAll(protect.getWord());
                    }
                }
            }
            if (CollUtil.isNotEmpty(addProtect)) {
                this.saveBatch(addProtect);
            }
            if (CollUtil.isNotEmpty(addWord)) {
                iPqsProtectcontrolwordService.saveBatch(addWord);
            }
            return true;
        }
        return false;
    }
}
