package com.huatek.busi.task.curve.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.huatek.busi.common.CurveSubType.RunStateSubTypeEnum;
import com.huatek.busi.common.SiteConstants.SiteTreeEnum;
import com.huatek.busi.dto.CurveSensorEntityDto;
import com.huatek.busi.dto.curve.IecBydworkParamPointDto;
import com.huatek.busi.entity.CurveSensorEntity;
import com.huatek.busi.service.BusiSiteTreeService;
import com.huatek.busi.service.IecBydworkParamService;
import com.huatek.busi.service.curve.BaseCurveSensorService;
import com.huatek.busi.task.curve.helper.AbstractCurveTask;
import com.huatek.busi.vo.BusiTreeNodeVo;
import com.huatek.busi.vo.curve.IecBydworkParamPointVo;
import com.huatek.busi.vo.curve.PointItemVo;

import lombok.extern.slf4j.Slf4j;

/**
 * 变压器工作状态
 * 
 * @author anker_cheng
 * @date 2019/09/04
 */
@Slf4j
@Component("transformerRunStateCurveTask")
public class TransformerRunStateCurveTask extends AbstractCurveTask {
    /** 一天默认取点的个数 */
    private final long DEFAULT_DAILY_POINT_COUNT = 24;
    /** 默认一页处理的条数 */
    private final int PAGE_SIZE = 100;

    @Autowired
    private BusiSiteTreeService busiSiteTreeService;
    @Autowired
    private IecBydworkParamService iecBydworkParamService;

    @Override
    public void execute(LocalDate day) {
        execute(null, day, RunStateSubTypeEnum.RUN_STATE.getValue());
    }

    @Override
    protected void execute(BaseCurveSensorService service, LocalDate day, String subType) {
        List<BusiTreeNodeVo> transformerList =
            busiSiteTreeService.findMainEquipmentList(new String[] {SiteTreeEnum.BYQ_EQM.getValue()});
        if (CollectionUtils.isEmpty(transformerList)) {
            logger.debug("变压器数据为空");
            return;
        }
        // 循环每个变压器，每个变压器每天采集24个点
        for (BusiTreeNodeVo transformer : transformerList) {
            execute(transformer, service, day, subType);
        }
    }

    private void execute(BusiTreeNodeVo transformer, BaseCurveSensorService service, LocalDate day, String subType) {
        // 保存一天一个点的记录
        CurveSensorEntityDto curveSensorEntityDto = new CurveSensorEntityDto();
        curveSensorEntityDto.setSensorCode(transformer.getId());
        curveSensorEntityDto.setMainTreeId(transformer.getId());
        curveSensorEntityDto.setDay(day);
        curveSensorEntityDto.setSubType(subType);
        CurveSensorEntity curveSensorEntity = curveSensorEntityService.saveCurveSensorEntity(curveSensorEntityDto);
        // 分页查询一天里多有的点
        IecBydworkParamPointDto query =
            new IecBydworkParamPointDto(transformer.getSiteId(), transformer.getId(), day, PAGE_SIZE);
        PageInfo<IecBydworkParamPointVo> pageInfo = null;
        // 当前状态
        Integer currentStype = null;
        // 每组的大小
        long group = -1;
        do {
            pageInfo = iecBydworkParamService.queryIecBydworkParamPointList(query);
            if (!hasData(pageInfo)) {
                log.debug("I am free  (*￣︶￣)");
                break;
            }
            List<PointItemVo> dailyPointList = Lists.newArrayList();
            group = pageInfo.getTotal() / DEFAULT_DAILY_POINT_COUNT;
            if (pageInfo.getTotal() % DEFAULT_DAILY_POINT_COUNT != 0) {
                group += 1;
            }
            List<IecBydworkParamPointVo> allDailyPointList = pageInfo.getList();
            for (int index = 0, len = allDailyPointList.size(); index < len; index++) {
                IecBydworkParamPointVo vo = allDailyPointList.get(index);
                int actualIndex = PAGE_SIZE * (pageInfo.getPageNum() - 1) + index;
                PointItemVo point = null;
                if (currentStype == null) {
                    currentStype = vo.getStype();
                    point = new PointItemVo(vo.getStartTime());
                } else if (!currentStype.equals(vo.getStype())) {
                    currentStype = vo.getStype();
                    point = new PointItemVo(vo.getStopTime());
                } else if (actualIndex % group == 0) {
                    point = new PointItemVo(vo.getStopTime());
                } else if (actualIndex == pageInfo.getTotal() - 1
                    && dailyPointList.size() == DEFAULT_DAILY_POINT_COUNT - 1) {
                    point = new PointItemVo(vo.getStopTime());
                }
                if (point == null) {
                    continue;
                }
                point.setVal(multiply(vo.getHigthCurrent(), vo.getHigthVoltage()));
                point.setExtendVala(format(vo.getHigthVoltage()));
                point.setExtendValb(format(vo.getHigthCurrent()));
                point.setExtendValc(vo.getStype() == null ? null : vo.getStype().toString());
                dailyPointList.add(point);
            }
            // 保存当前页取的点
            curveSensorEntityService.saveCurveSensorPointEntity(curveSensorEntity, dailyPointList);
            // 下一页
            query.setPage(query.getPage() + 1);
        } while (pageInfo.getPages() > pageInfo.getPageNum());
    }

    private static boolean hasData(PageInfo<IecBydworkParamPointVo> pageInfo) {
        return pageInfo != null && !CollectionUtils.isEmpty(pageInfo.getList());
    }

    private static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        if (a != null && b != null) {
            return a.multiply(b);
        }
        if (a != null) {
            return a;
        }
        if (b != null) {
            return b;
        }
        return null;
    }

    private static String format(BigDecimal val) {
        return val == null ? null : val.toEngineeringString();
    }
}