package com.purui.prims.headless.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.purui.prims.common.pojo.PersistenceConf;
import com.purui.prims.common.util.BeanMapper;
import com.purui.prims.common.util.DatePeriodEnum;
import com.purui.prims.headless.api.pojo.request.MetricPersistenceConfigReq;
import com.purui.prims.headless.api.pojo.response.MetricPersistenceConfigResp;
import com.purui.prims.headless.api.pojo.response.MetricResp;
import com.purui.prims.headless.server.persistence.dataobject.MetricPersistenceConfigDO;
import com.purui.prims.headless.server.persistence.mapper.MetricPersistenceConfigDOMapper;
import com.purui.prims.headless.server.service.MetricPersistenceConfigService;
import com.purui.prims.headless.server.service.MetricService;
import com.purui.prims.headless.server.service.StatisticsPeriodService;
import com.purui.prims.headless.server.utils.CronUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * 指标持久化类
 *
 * @author charlie
 * @date 2024/6/21
 */
@Service
@Slf4j
public class MetricPersistenceConfigServiceImpl
    extends ServiceImpl<MetricPersistenceConfigDOMapper, MetricPersistenceConfigDO> implements
    MetricPersistenceConfigService {

    MetricService metricService;
    StatisticsPeriodService statisticsPeriodService;

    public MetricPersistenceConfigServiceImpl(MetricService metricService, StatisticsPeriodService statisticsPeriodService) {
        this.metricService = metricService;
        this.statisticsPeriodService = statisticsPeriodService;
    }

    @Override
    public boolean save(MetricPersistenceConfigReq configReq) {
        MetricPersistenceConfigDO metricPersistenceConfigDO = new MetricPersistenceConfigDO();
        BeanMapper.mapper(configReq, metricPersistenceConfigDO);
        QueryWrapper<MetricPersistenceConfigDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MetricPersistenceConfigDO::getMetricId, configReq.getMetricId());
        MetricPersistenceConfigDO configDO = getOne(queryWrapper);
        if (configDO != null) {
            metricPersistenceConfigDO.setId(configDO.getId());
        }
        // 统一设置表名
        metricPersistenceConfigDO.setTableName(metricService.getMetricTableName(configReq.getMetricId()));
        return saveOrUpdate(metricPersistenceConfigDO);
    }

    @Override
    public MetricPersistenceConfigResp get(Long id) {
        MetricPersistenceConfigDO metricPersistenceConfigDO = getById(id);
        return converter(metricPersistenceConfigDO);
    }

    @Override
    public MetricPersistenceConfigDO getById(Long id) {
        return this.getById(id);
    }

    @Override
    public MetricPersistenceConfigResp getByMetricId(Long id) {
        QueryWrapper<MetricPersistenceConfigDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MetricPersistenceConfigDO::getMetricId, id);
        return converter(getOne(queryWrapper));
    }

    @Override
    public List<MetricPersistenceConfigResp> getConfigList() {
        return list().stream().map(this::converter).filter(config -> config != null).collect(Collectors.toList());
    }

    @Override
    public boolean delete(Long id) {
        return this.removeById(id);
    }

    private MetricPersistenceConfigResp converter(MetricPersistenceConfigDO metricPersistenceConfigDO) {
        if (metricPersistenceConfigDO == null) {
            return null;
        }
        MetricPersistenceConfigResp metricPersistenceConfigResp = new MetricPersistenceConfigResp();
        BeanMapper.mapper(metricPersistenceConfigDO, metricPersistenceConfigResp);
        MetricResp metricResp = metricService.getMetric(metricPersistenceConfigDO.getMetricId());
        if (metricResp != null) {
            metricPersistenceConfigResp.setModelId(metricResp.getModelId());
        }
        // 解析配置
        if (StringUtils.isNotEmpty(metricPersistenceConfigDO.getDefaultConfig())) {
            PersistenceConf conf = JSON.parseObject(metricPersistenceConfigDO.getDefaultConfig(), PersistenceConf.class);
            if ("AUTO".equalsIgnoreCase(conf.getWay())) {
                return null;
            }
            if (StringUtils.isNotEmpty(conf.getPeriod())) {
                DatePeriodEnum period = DatePeriodEnum.valueOf(conf.getPeriod().toUpperCase(Locale.ROOT));
                String[] dateRange = CronUtils.calculateDateRange(period, conf.getUnit());
                conf.setStartDate(dateRange[0]);
                conf.setEndDate(dateRange[1]);
                conf.setCron(CronUtils.buildCron(period, conf.getStartTime()));
            }
            metricPersistenceConfigResp.setConf(conf);
        }
        return metricPersistenceConfigResp;
    }
}
