package com.project.zcustom.service.service.basics.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.zcustom.controller.core.PageParamVo;
import com.project.zcustom.controller.core.StringUtils;
import com.project.zcustom.domain.basics.PlatBasics;
import com.project.zcustom.domain.basics.PlatBasicsCompany;
import com.project.zcustom.domain.basics.PlatBasicsServer;
import com.project.zcustom.domain.basics.PlatBasicsSystem;
import com.project.zcustom.mapper.basics.PlatBasicsMapper;
import com.project.zcustom.service.service.basics.IPlatBasicsCompanyService;
import com.project.zcustom.service.service.basics.IPlatBasicsServerService;
import com.project.zcustom.service.service.basics.IPlatBasicsService;
import com.project.zcustom.service.service.basics.IPlatBasicsSystemService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 基础运行数据Service业务层处理
 *
 * @author change
 * @date 2024-10-21
 */
@Service
public class PlatBasicsServiceImpl extends ServiceImpl<PlatBasicsMapper, PlatBasics> implements IPlatBasicsService {
    @Resource
    IPlatBasicsCompanyService platBasicsCompanyService;
    @Resource
    IPlatBasicsServerService platBasicsServerService;
    @Resource
    IPlatBasicsSystemService platBasicsSystemService;


    /**
     * 组装查询条件
     */
    private LambdaQueryWrapper<PlatBasics> getLambdaQueryWrapper(PlatBasics platBasics) {
        LambdaQueryWrapper<PlatBasics> lqw = new LambdaQueryWrapper<PlatBasics>();
        if (StringUtils.isNotBlank(platBasics.getAppOrg())) {
            lqw.eq(PlatBasics::getAppOrg, platBasics.getAppOrg());
        }
        return lqw;
    }

    /**
     * 分页查询基础运行数据列表
     *
     * @param platBasics 基础运行数据
     * @return 基础运行数据集合
     */
    @Override
    public IPage<PlatBasics> pagingPlatBasicsList(PlatBasics platBasics) {
        IPage<PlatBasics> page = new Page<>(platBasics.getPageNum(), platBasics.getPageSize());
        LambdaQueryWrapper<PlatBasics> lqw = getLambdaQueryWrapper(platBasics);
        // 排序 默认时间倒序
        lqw.orderByDesc(PlatBasics::getCreateTime);
        return baseMapper.selectPage(page, lqw);
    }

    /**
     * 分页查询基础运行数据列表
     *
     * @param lqw
     * @return 基础运行数据集合
     */
    @Override
    public IPage<PlatBasics> pagingPlatBasicsList(PageParamVo pageParamVo, LambdaQueryWrapper<PlatBasics> lqw) {
        IPage<PlatBasics> page = new Page<>(pageParamVo.getPageNum(), pageParamVo.getPageSize());
        // 排序 默认时间倒序
        lqw.orderByDesc(PlatBasics::getCreateTime);
        return baseMapper.selectPage(page, lqw);
    }

    /**
     * 查询基础运行数据列表
     *
     * @param platBasics 基础运行数据
     * @return 基础运行数据
     */
    @Override
    public List<PlatBasics> selectPlatBasicsList(PlatBasics platBasics) {
        LambdaQueryWrapper<PlatBasics> lqw = getLambdaQueryWrapper(platBasics);
        // 排序 默认时间倒序
        lqw.orderByDesc(PlatBasics::getCreateTime);
        return baseMapper.selectList(lqw);
    }

    /**
     * 查询基础运行数据列表
     *
     * @param platBasics 基础运行数据
     * @return 基础运行数据
     */
    @Override
    public List<PlatBasics> selectPlatBasicsList(PlatBasics platBasics, Long limitNum) {
        LambdaQueryWrapper<PlatBasics> lqw = getLambdaQueryWrapper(platBasics);
        // 排序 默认时间倒序
        lqw.orderByDesc(PlatBasics::getCreateTime);
        lqw.last("limit " + limitNum);
        return baseMapper.selectList(lqw);
    }

    /**
     * 根据指定字段查询信息
     *
     * @param field      字段名称
     * @param filedValue 字段值
     * @return 基础运行数据
     */
    @Override
    public PlatBasics getPlatBasicsByField(String field, String filedValue) {
        QueryWrapper<PlatBasics> lqw = new QueryWrapper<PlatBasics>();
        lqw.eq(field, filedValue);
        lqw.last("limit 1");
        return this.getOne(lqw, false);
    }

    /**
     * 根据指定字段查询信息
     *
     * @param field      字段名称
     * @param filedValue 字段值
     * @return 基础运行数据
     */
    @Override
    public PlatBasics getPlatBasicsByField(String field, String filedValue, String fieldString) {
        QueryWrapper<PlatBasics> lqw = new QueryWrapper<PlatBasics>();
        if(!(Objects.equals(field,"app_org") && Objects.equals(filedValue,"0000"))){
            lqw.eq(field, filedValue);
        }
        lqw.select(fieldString);
        lqw.last("limit 1");
        return this.getOne(lqw, false);
    }


    /**
     * 根据指定字段查询信息列表
     *
     * @param field      字段名称
     * @param filedValue 字段值
     * @return 基础运行数据
     */
    @Override
    public List<PlatBasics> selectPlatBasicsListByField(String field, String filedValue, Long limitNum) {
        QueryWrapper<PlatBasics> lqw = new QueryWrapper<PlatBasics>();
        lqw.eq(field, filedValue);
        lqw.last("limit " + limitNum);
        return this.list(lqw);
    }

    /**
     * 根据指定字段查询信息列表
     *
     * @param field      字段名称
     * @param filedValue 字段值
     * @return 基础运行数据
     */
    @Override
    public List<PlatBasics> selectPlatBasicsListByField(String field, String filedValue) {
        QueryWrapper<PlatBasics> lqw = new QueryWrapper<PlatBasics>();
        lqw.eq(field, filedValue);
        return this.list(lqw);
    }

    /**
     * 判断指定字段值是否存在
     *
     * @param field      字段名称
     * @param filedValue 字段值
     */
    @Override
    public void checkFieldExist(String field, String filedValue, String tips, Long id) {
        QueryWrapper<PlatBasics> lqw = new QueryWrapper<PlatBasics>();
        lqw.eq(field, filedValue);
        lqw.ne("id", id);
        if (this.getOne(lqw, false) != null) {
            throw new RuntimeException(tips + "已存在");
        }
    }

    /**
     * 添加基础服务
     */
    @Override
    public void addPlatBasics(String appOrg,String appName,Map<String, Object> mapField){
        PlatBasics platBasics = this.getPlatBasicsByField("app_org", appOrg);
        try {
            if(StringUtils.isNotNull(platBasics)){
                this.setPlatBasics(mapField,platBasics);
                this.updateById(platBasics);
            }else{
                platBasics = new PlatBasics();
                this.setPlatBasics(mapField,platBasics);
                platBasics.setAppOrg(appOrg);
                this.save(platBasics);
            }
            this.operatorServer(appOrg,mapField);
            this.operatorCompany(appOrg,appName,mapField);
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 设置数据
     */
    private void setPlatBasics(Map<String, Object> mapField, PlatBasics platBasics){
        List<String> keyList = Arrays.asList("register","activeUsers");
        StringUtils.setFieldValue(platBasics,mapField,keyList,0, PlatBasics::setRegisterNum,Long.class);
        StringUtils.setFieldValue(platBasics,mapField,keyList,1, PlatBasics::setOrderNum,Long.class);
//
//
//        platBasics.setRegisterNum((Long) mapField.get("register"));
//        platBasics.setOnlineNum((Long) mapField.get("onLine"));
//        platBasics.setOrderNum((Long) mapField.get("activeUsers"));
//        platBasics.setOnlineRate((BigDecimal) mapField.get("rate"));
//        platBasics.setCpuOverloadNum((Long) mapField.get("cpuOverload"));
//        platBasics.setDiskOverloadNum((Long) mapField.get("diskOverload"));
//        platBasics.setMemoryOverloadNum((Long) mapField.get("memoryOverload"));
//        platBasics.setInsufficientNum((Long) mapField.get("Insufficient"));
    }

    /**
     * 公司信息处理
     */
    private void operatorCompany(String appOrg,String appName,Map<String, Object> mapField){
         // 处理公司数据
        PlatBasicsCompany platBasicsCompany = platBasicsCompanyService.getPlatBasicsCompanyByField("app_org", appOrg);
        if(StringUtils.isNotNull(platBasicsCompany)){
            StringUtils.setFieldValue(platBasicsCompany, mapField, Collections.singletonList("activeUsers"), 0,PlatBasicsCompany::setActiveUserNum, Long.class);
            platBasicsCompanyService.updateById(platBasicsCompany);
        }else{
            platBasicsCompany = new PlatBasicsCompany();
            platBasicsCompany.setCompanyName(appName);
            platBasicsCompany.setAppOrg(appOrg);
            StringUtils.setFieldValue(platBasicsCompany, mapField, Collections.singletonList("activeUsers"), 0,PlatBasicsCompany::setActiveUserNum, Long.class);
            platBasicsCompanyService.save(platBasicsCompany);
        }

    }

    /**
     * 服务器数据处理
     */
    private void operatorServer(String appOrg,Map<String, Object> mapField){
        try {
            // 先删除服务器数据
            LambdaQueryWrapper<PlatBasicsServer> serverQueryWrapper = new LambdaQueryWrapper<>();
            serverQueryWrapper.eq(PlatBasicsServer::getAppOrg, appOrg);
            platBasicsServerService.reallyDeletePlatBasicsServer(serverQueryWrapper);
            // 在添加
            if(mapField.containsKey("unitList")){
                JSONArray unitList = JSONArray.parseArray(mapField.get("unitList").toString());
                List<PlatBasicsServer> addList = new ArrayList<>();
                for (Object o : unitList) {
                    Map<String, Object> temp = JSONObject.parseObject(o.toString(), Map.class);
                    PlatBasicsServer platBasicsServer = new PlatBasicsServer();
                    platBasicsServer.setAppOrg(appOrg);
                    platBasicsServer.setServerName(temp.get("name").toString());
                    platBasicsServer.setServerNum((Long) temp.get("number"));
                    addList.add(platBasicsServer);
                }
                platBasicsServerService.saveBatch(addList);
            }

//            // cpu
//            List<String> cpuList = Arrays.asList("cpu0","cpu12","cpu18","cpu24");
//            this.operatorSystem(appOrg,0,cpuList,mapField);
//            // 内存
//            List<String> memList = Arrays.asList("mem0","mem12","mem18","mem24");
//            this.operatorSystem(appOrg,1,memList,mapField);
//            // 磁盘
//            List<String> disList = Arrays.asList("dis0","dis12","dis18","dis24");
//            this.operatorSystem(appOrg,2,disList,mapField);
//            // 流量
//            List<String> insList = Arrays.asList("ins0","ins12","ins18","ins24");
//            this.operatorSystem(appOrg,3,insList,mapField);

        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }

    }

    /**
     * 系统数据处理
     */
    private void operatorSystem(String appOrg,int type,List<String> keyList,Map<String, Object> mapField){
        try {
            QueryWrapper<PlatBasicsSystem> systemQueryWrapper = new QueryWrapper<>();
            systemQueryWrapper.eq("app_org", appOrg);
            systemQueryWrapper.eq("sys_type", type);
            systemQueryWrapper.last("limit 1");
            PlatBasicsSystem platBasicsSystem = platBasicsSystemService.getOne(systemQueryWrapper);
            if(StringUtils.isNotNull(platBasicsSystem)){
                platBasicsSystem.setBetween6Num((Long) mapField.get(keyList.get(0)));
                platBasicsSystem.setBetween12Num((Long) mapField.get(keyList.get(1)));
                platBasicsSystem.setBetween18Num((Long) mapField.get(keyList.get(2)));
                platBasicsSystem.setBetween24Num((Long) mapField.get(keyList.get(3)));
                platBasicsSystemService.updateById(platBasicsSystem);
            }else{
                platBasicsSystem = new PlatBasicsSystem();
                platBasicsSystem.setBetween6Num((Long) mapField.get(keyList.get(0)));
                platBasicsSystem.setBetween12Num((Long) mapField.get(keyList.get(1)));
                platBasicsSystem.setBetween18Num((Long) mapField.get(keyList.get(2)));
                platBasicsSystem.setBetween24Num((Long) mapField.get(keyList.get(3)));
                platBasicsSystem.setAppOrg(appOrg);
                platBasicsSystem.setSysType(type);
            }

        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }


    /**
     * 获取数据概况
     */
    @Override
    public Map<String, Object> getOverviewData(String appOrg){
        String fieldString = "register_num,order_num";
        if(Objects.equals(appOrg,"0000")){
            fieldString = "sum(register_num) as register_num,sum(order_num) as order_num";
        }
        PlatBasics platBasics = this.getPlatBasicsByField("app_org", appOrg,fieldString);
        Map<String, Object> tempMap = new HashMap<>();
        if (StringUtils.isNull(platBasics)) {
            StringUtils.getMapData("注册用户数", "registerNum", 0, tempMap);
            StringUtils.getMapData("活跃人数", "orderNum", 0, tempMap);
            tempMap.put("onlineRate", "0");
        }else{
            StringUtils.getMapData("注册用户数", "registerNum", platBasics.getRegisterNum(), tempMap);
            StringUtils.getMapData("活跃人数", "orderNum", platBasics.getOrderNum(), tempMap);
            BigDecimal a = new BigDecimal(platBasics.getOrderNum());
            BigDecimal b = new BigDecimal(platBasics.getRegisterNum());
            BigDecimal result = a.divide(b, 4, RoundingMode.HALF_UP);
            BigDecimal percentage = result.multiply(new BigDecimal("100")).stripTrailingZeros();
            tempMap.put("onlineRate", percentage.toPlainString());
        }
        return tempMap;
    }

    /**
     * 系统运行报警信息
     */
    @Override
    public Map<String, Object> getSystemRunErrData(String appOrg){
        Map<String, Object> tempMap = new HashMap<>();
        PlatBasics platBasics = this.getPlatBasicsByField("app_org", appOrg);
        Long[] numList = new Long[]{0L,0L,0L,0L};
        if (StringUtils.isNotNull(platBasics)) {
            numList = new Long[]{platBasics.getCpuOverloadNum(),platBasics.getDiskOverloadNum(),platBasics.getMemoryOverloadNum(),platBasics.getInsufficientNum()};
        }
        String[] nameList = new String[]{"CPU过载","磁盘过载","内存过载","流量不足"};

        StringUtils.createdTableData(Arrays.asList(nameList), Arrays.asList(numList),"#2EC7C9",tempMap);

        return tempMap;
    }
}
