package org.wfc.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.wfc.common.core.constant.CacheConstants;
import org.wfc.common.core.constant.HttpStatus;
import org.wfc.common.core.constant.WifiConstants;
import org.wfc.common.core.domain.LoginUser;
import org.wfc.common.core.exception.OmadaException;
import org.wfc.common.core.web.page.TableDataInfo;
import org.wfc.common.redis.service.RedisService;
import org.wfc.omada.api.monitor.OmadaDashboardApi;
import org.wfc.omada.api.monitor.model.GetDashboardOverview;
import org.wfc.omada.api.monitor.model.OperationResponseGetDashboardOverview;
import org.wfc.omada.api.organization.OmadaSiteApi;
import org.wfc.omada.api.organization.model.OperationResponseGridVoSiteSummaryInfo;
import org.wfc.omada.api.organization.model.SiteSummaryInfo;
import org.wfc.system.domain.convert.SysDashboardConvert;
import org.wfc.system.domain.vo.SysDashboardSiteVo;
import org.wfc.system.domain.vo.SysDashboardVo;
import org.wfc.system.mapper.UUserMapper;
import org.wfc.system.service.ISysDashboardService;
import org.wfc.user.api.domain.UUser;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @description:
 * @author: cyc
 * @since: 2025-01-07
 */
@Slf4j
@Service
public class SysDashboardServiceImpl implements ISysDashboardService {
    @Autowired
    private OmadaSiteApi omadaSiteApi;

    @Autowired
    private OmadaDashboardApi omadaDashboardApi;

    @Autowired
    private RedisService redisService;

    @Autowired
    private UUserMapper userMapper;

    @Override
    public TableDataInfo getSiteList(String searchKey, Integer pageNum, Integer pageSize) {
        ResponseEntity<OperationResponseGridVoSiteSummaryInfo> siteList = omadaSiteApi.getSiteList(pageNum, pageSize, searchKey);
        if (siteList.getBody() == null || siteList.getBody().getErrorCode() != WifiConstants.ERROR_CODE_SUCCESS) {
            log.error("Omada error msg: {}",siteList.getBody().getMsg());
            throw new OmadaException();
        }

        List<SiteSummaryInfo> sites = siteList.getBody().getResult().getData();
        List<SysDashboardSiteVo> siteVos = new ArrayList<>();
        for (SiteSummaryInfo site : sites) {
            SysDashboardSiteVo siteVo = SysDashboardConvert.INSTANCE.toSysDashboardSiteVo(site);
            ResponseEntity<OperationResponseGetDashboardOverview> overview = omadaDashboardApi.getOverview(site.getSiteId());
            if (overview.getBody() == null) {
                continue;
            }
            GetDashboardOverview dashboardOverview = overview.getBody().getResult();
            BeanUtils.copyProperties(dashboardOverview, siteVo);
            siteVos.add(siteVo);
        }
        return getDataTable(siteVos, siteList.getBody().getResult().getTotalRows());
    }

    @Override
    public SysDashboardVo overview() {
        ResponseEntity<OperationResponseGridVoSiteSummaryInfo> siteList = omadaSiteApi.getSiteList(1, 1000);
        SysDashboardVo sysDashboardVo = new SysDashboardVo();
        if (siteList.getBody() == null || siteList.getBody().getErrorCode() != WifiConstants.ERROR_CODE_SUCCESS) {
            log.error("Omada error msg: {}",siteList.getBody().getMsg());
            throw new OmadaException();
        }

        List<SiteSummaryInfo> sites = siteList.getBody().getResult().getData();

        List<GetDashboardOverview> dashboardOverviews = new ArrayList<>();
        for (SiteSummaryInfo site : sites) {
            ResponseEntity<OperationResponseGetDashboardOverview> overview = omadaDashboardApi.getOverview(site.getSiteId());
            if (overview.getBody() == null) {
                continue;
            }
            GetDashboardOverview dashboardOverview = overview.getBody().getResult();
            dashboardOverviews.add(dashboardOverview);
        }
        sysDashboardVo.setAvailablePorts(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getAvailablePorts())).mapToInt(GetDashboardOverview::getAvailablePorts).sum());
        sysDashboardVo.setConnectedGatewayNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getConnectedGatewayNum())).mapToInt(GetDashboardOverview::getConnectedGatewayNum).sum());
        sysDashboardVo.setConnectedApNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getConnectedApNum())).mapToInt(GetDashboardOverview::getConnectedApNum).sum());
        sysDashboardVo.setConnectedSwitchNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getConnectedSwitchNum())).mapToInt(GetDashboardOverview::getConnectedSwitchNum).sum());
        sysDashboardVo.setGuestNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getGuestNum())).mapToInt(GetDashboardOverview::getGuestNum).sum());
        sysDashboardVo.setDisconnectedApNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getDisconnectedApNum())).mapToInt(GetDashboardOverview::getDisconnectedApNum).sum());
        sysDashboardVo.setNetCapacity(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getNetCapacity())).mapToInt(GetDashboardOverview::getNetCapacity).sum());
        sysDashboardVo.setIsolatedApNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getIsolatedApNum())).mapToInt(GetDashboardOverview::getIsolatedApNum).sum());
        sysDashboardVo.setNetUsage(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getNetUsage())).mapToDouble(GetDashboardOverview::getNetUsage).sum());
        sysDashboardVo.setDisconnectedGatewayNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getDisconnectedGatewayNum())).mapToInt(GetDashboardOverview::getDisconnectedGatewayNum).sum());
        sysDashboardVo.setTotalApNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getTotalApNum())).mapToInt(GetDashboardOverview::getTotalApNum).sum());
        sysDashboardVo.setTotalPorts(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getTotalPorts())).mapToInt(GetDashboardOverview::getTotalPorts).sum());
        sysDashboardVo.setTotalClientNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getTotalClientNum())).mapToInt(GetDashboardOverview::getTotalClientNum).sum());
        sysDashboardVo.setTotalSwitchNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getTotalSwitchNum())).mapToInt(GetDashboardOverview::getTotalSwitchNum).sum());
        sysDashboardVo.setPowerConsumption(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getPowerConsumption())).mapToDouble(GetDashboardOverview::getPowerConsumption).sum());
        sysDashboardVo.setWirelessClientNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getWirelessClientNum())).mapToInt(GetDashboardOverview::getWirelessClientNum).sum());
        sysDashboardVo.setWiredClientNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getWiredClientNum())).mapToInt(GetDashboardOverview::getWiredClientNum).sum());
        sysDashboardVo.setDisconnectedApNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getDisconnectedApNum())).mapToInt(GetDashboardOverview::getDisconnectedApNum).sum());
        sysDashboardVo.setTotalGatewayNum(dashboardOverviews.stream().filter(c -> ObjectUtil.isNotNull(c.getTotalGatewayNum())).mapToInt(GetDashboardOverview::getTotalGatewayNum).sum());
        sysDashboardVo.setSiteNum(sites.size());

        // 注册用户数和在线用户数
        Long registerUserNum = userMapper.selectCount(Wrappers.lambdaQuery());
        Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        Set<String> sets = new HashSet<>();
        for (String key : keys) {
            LoginUser user = redisService.getCacheObject(key);
            Object userObj = user.getUser();
            if (userObj instanceof UUser) {
                UUser uUser = (UUser) userObj;
                sets.add(uUser.getUserName());
            }
        }
        sysDashboardVo.setRegisterUserNum(registerUserNum);
        sysDashboardVo.setOnlineUserNum(sets.size());

        return sysDashboardVo;
    }

    /**
     * 响应请求分页数据
     */
    protected TableDataInfo getDataTable(List<?> list, Long total) {
        TableDataInfo rspData = new TableDataInfo(list, total);
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("Query successful");

        return rspData;
    }
}
