package com.xzzn.ems.service.impl;

import com.xzzn.common.constant.RedisKeyConstants;
import com.xzzn.common.core.redis.RedisCache;
import com.xzzn.common.exception.ServiceException;
import com.xzzn.common.enums.DeviceCategory;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsBatteryData;
import com.xzzn.ems.domain.EmsSiteSetting;
import com.xzzn.ems.domain.vo.SiteDeviceListVo;
import com.xzzn.ems.domain.vo.SiteTotalInfoVo;
import com.xzzn.ems.mapper.EmsDevicesSettingMapper;
import com.xzzn.ems.mapper.EmsSiteSettingMapper;
import com.xzzn.ems.service.IEmsSiteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 站点信息 服务层实现
 *
 */
@Service
public class EmsSiteServiceImpl implements IEmsSiteService
{
    private static final Pattern SITE_ID_PATTERN = Pattern.compile("^[A-Za-z0-9_]+$");

    @Autowired
    private EmsSiteSettingMapper emsSiteMapper;
    @Autowired
    private EmsDevicesSettingMapper emsDevicesMapper;
    @Autowired
    private RedisCache redisCache;

    @Override
    public List<EmsSiteSetting> getAllSites() {
        return emsSiteMapper.selectEmsSiteSettingList(null);
    }

    @Override
    public SiteTotalInfoVo getSiteTotalInfo() {
        return emsSiteMapper.getSiteTotalInfo();
    }

    /**
     * 根据site_id获取所有电池堆
     * @param siteId
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllStackInfo(String siteId) {
        return emsDevicesMapper.getDeviceInfosBySiteIdAndCategory(siteId, DeviceCategory.STACK.getCode());
    }

    /**
     * 根据父类设备id获取子设备id
     * @param parentId
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllClusterInfo(String siteId, String parentId) {
        return emsDevicesMapper.getDeviceInfoByParentId(siteId,parentId);
    }

    /**
     * 获取站点列表
     * @param siteName
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<EmsSiteSetting> getAllSiteInfoList(String siteName, String startTime, String endTime) {
        List<EmsSiteSetting> list = emsSiteMapper.getSiteInfoList(siteName,startTime,endTime);
        if (list == null || list.isEmpty()) {
            return list;
        }
        for (EmsSiteSetting site : list) {
            site.setAuthorized(Boolean.TRUE);
        }
        return list;
    }

    /**
     * 获取设备列表
     *
     * @param siteId
     * @return
     */
    @Override
    public List<SiteDeviceListVo> getAllDeviceList(String siteId, String deviceCategory) {
        List<SiteDeviceListVo> resultData = emsSiteMapper.getAllSiteDeviceList(siteId, deviceCategory);
        if(resultData == null || resultData.size() == 0){
            return resultData;
        }
        for (SiteDeviceListVo siteDeviceListVo : resultData) {
            String clusterId = siteDeviceListVo.getDeviceId();
            String category = siteDeviceListVo.getDeviceCategory();
            if(DeviceCategory.CLUSTER.getCode().equals(category)){
                // 获取该stack下面有多少单体电池
                List<EmsBatteryData> batteryDataList = redisCache.getCacheList(RedisKeyConstants.BATTERY + siteId + "_" + clusterId);
                siteDeviceListVo.setBatteryNum(batteryDataList == null ? 0 : batteryDataList.size());
            }
            String categoryName = DeviceCategory.getInfoByCode(category);
            siteDeviceListVo.setCategoryName(categoryName);
        }
        return resultData;
    }

    /**
     * 获取设备列表
     *
     * @param siteId
     * @return
     */
    @Override
    public List<SiteDeviceListVo> getAllDeviceListNoDisp(String siteId, String deviceCategory) {
        List<SiteDeviceListVo> resultData = emsSiteMapper.getAllSiteDeviceListNoDisp(siteId, deviceCategory);
        if(resultData == null || resultData.size() == 0){
            return resultData;
        }
        for (SiteDeviceListVo siteDeviceListVo : resultData) {
            String clusterId = siteDeviceListVo.getDeviceId();
            String category = siteDeviceListVo.getDeviceCategory();
            if(DeviceCategory.CLUSTER.getCode().equals(category)){
                // 获取该stack下面有多少单体电池
                List<EmsBatteryData> batteryDataList = redisCache.getCacheList(RedisKeyConstants.BATTERY + siteId + "_" + clusterId);
                siteDeviceListVo.setBatteryNum(batteryDataList == null ? 0 : batteryDataList.size());
            }
            String categoryName = DeviceCategory.getInfoByCode(category);
            siteDeviceListVo.setCategoryName(categoryName);
        }
        return resultData;
    }
    /**
     * 根据site_id获取所有pcs
     * @param siteId
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllPcsInfo(String siteId) {
        return emsDevicesMapper.getDeviceInfosBySiteIdAndCategory(siteId, DeviceCategory.PCS.getCode());
    }

    // 根据设备类别获取父类的设备id
    @Override
    public List<Map<String,Object>> getParentCategoryDeviceId(String siteId, String deviceCategory) {
        DeviceCategory category = DeviceCategory.fromCode(deviceCategory);
        if(category == null || category.getParentCategory() == null){
            return null;
        }
        String parentCategory = category.getParentCategory().getCode();
        List<Map<String,Object>> deviceIdList = emsDevicesMapper.getDeviceInfosBySiteIdAndCategory(siteId, parentCategory);
        return deviceIdList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addSite(EmsSiteSetting emsSiteSetting) {
        validateSiteSetting(emsSiteSetting, true);
        String siteId = emsSiteSetting.getSiteId();
        EmsSiteSetting existing = emsSiteMapper.selectEmsSiteSettingBySiteId(siteId);
        if (existing != null) {
            throw new ServiceException("站点ID已存在，请更换后重试");
        }
        emsSiteSetting.setCreateTime(DateUtils.getNowDate());
        return emsSiteMapper.insertEmsSiteSetting(emsSiteSetting);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSite(EmsSiteSetting emsSiteSetting) {
        if (emsSiteSetting == null || emsSiteSetting.getId() == null) {
            throw new ServiceException("站点主键不能为空");
        }
        validateSiteSetting(emsSiteSetting, false);
        EmsSiteSetting dbData = emsSiteMapper.selectEmsSiteSettingById(emsSiteSetting.getId());
        if (dbData == null) {
            throw new ServiceException("站点不存在");
        }
        if (StringUtils.isNotEmpty(emsSiteSetting.getSiteId())
                && !StringUtils.equals(emsSiteSetting.getSiteId(), dbData.getSiteId())) {
            throw new ServiceException("不支持修改站点ID");
        }
        emsSiteSetting.setSiteId(dbData.getSiteId());
        emsSiteSetting.setUpdateTime(DateUtils.getNowDate());
        return emsSiteMapper.updateEmsSiteSetting(emsSiteSetting);
    }

    private void validateSiteSetting(EmsSiteSetting emsSiteSetting, boolean requireSiteId) {
        if (emsSiteSetting == null) {
            throw new ServiceException("参数不能为空");
        }
        if (StringUtils.isBlank(emsSiteSetting.getSiteName())) {
            throw new ServiceException("站点名称不能为空");
        }
        if (requireSiteId && StringUtils.isBlank(emsSiteSetting.getSiteId())) {
            throw new ServiceException("站点ID不能为空");
        }
        if (StringUtils.isNotBlank(emsSiteSetting.getSiteId()) && !SITE_ID_PATTERN.matcher(emsSiteSetting.getSiteId()).matches()) {
            throw new ServiceException("站点ID仅支持字母、数字、下划线");
        }
    }

}
