package com.ssj.service.es;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ssj.bean.es.domain.EsDataRecode;
import com.ssj.dao.es.dao.IEsDataRecodeDao;
import com.ssj.es.service.base.BaseElasticService;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.util.ResponseConstant;
import com.ssj.framework.core.util.ResponseEntity;
import com.ssj.mapper.load.data.LoadDataMapper;
import com.ssj.service.es.service.IEsDataRecodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.*;

/**
 * @author sh
 * @className EsDataRecodeServiceImpl
 * @description TODO
 * @date 2020/4/29
 */
@Service(version = "1.0")
@Transactional
public class EsDataRecodeServiceImpl  extends BaseServiceImpl<EsDataRecode,String> implements IEsDataRecodeService{

    @Autowired
    private IEsDataRecodeDao dao;
    @Autowired
    private BaseElasticService baseElasticService;

    @Autowired
    private LoadDataMapper loadDataMapper;

    @Override
    public PagingAndSortingRepository<EsDataRecode, String> getDao() {
        return dao;
    }

    @Override
    public  <T> ResponseEntity findIsLoadEs(String beginDate,String loadDate, String indexName, String apiName, List<T> list) {

        ResponseEntity responseEntity = new ResponseEntity();
        try{
            //判断时间字符串格式是否正确
            Date date = DateHelper.parseDate(loadDate,"yyyy-MM-dd");
            Date date2 = DateHelper.parseDate(beginDate,"yyyy-MM-dd");
            loadDate= DateHelper.format(date,"yyyy-MM-dd");
            beginDate= DateHelper.format(date2,"yyyy-MM-dd");
        }catch (Exception e){
            responseEntity.failure("000","传入日期格式错误，格式要求yyyy-MM-dd");
            return  responseEntity;
        }

        String thisMonth = DateHelper.format(new Date(),"yyyy-MM-dd");
        //判断时间是否合法
        if(loadDate.compareTo(thisMonth)>=0 && beginDate.compareTo(thisMonth) >=0){
            responseEntity.failure("000","传入时间错误，应小于本月！");
            return  responseEntity;
        }

        //判断索引名称是否符合要求
        String pattern = "^[a-z0-9_-]+$";
        if(!indexName.matches(pattern)){
            responseEntity.failure("000","传入索引名称不合法，小写字母和字母组合");
            return  responseEntity;
        }

        EsDataRecode recode = dao.getLastDataByIndex(indexName);
        boolean b = false;
        if(recode == null ){
            b = true;
        }else{
            if(beginDate.compareTo(recode.getLoadDate())==0 && loadDate.compareTo(recode.getLoadDate())>0){
                b = true;
            }
        }
        if(b){
            try{
                baseElasticService.insertBatchES(indexName,list);
                recode = new EsDataRecode();
                recode.setApiName(apiName);
                recode.setCreateTime(new Date());
                recode.setEsIndexName(indexName);
                recode.setLoadDate(loadDate);
                recode.setState(1);
                this.save(recode);
                responseEntity.success("数据加载成功！");
            }catch (Exception e){
                responseEntity.failure("000","保存es数据出现异常，请重试！");
                return  responseEntity;
            }

        }else{
            Map<String,Object> data = new HashMap<>(2);
            data.put("lastLoadDate",recode.getLoadDate());
            responseEntity.failure(ResponseConstant.CODE_004,"时间区间不正确",data);
        }
        return  responseEntity;
    }

    @Override
    public <T> ResponseEntity loadDataToEs(String beginDate, String loadDate, String indexName, String apiName, Class<T> clazz, String methodName,int count) {
        ResponseEntity responseEntity = new ResponseEntity();
        try{
            //判断时间字符串格式是否正确
            Date date = DateHelper.parseDate(loadDate,"yyyy-MM-dd");
            Date date2 = DateHelper.parseDate(beginDate,"yyyy-MM-dd");
            loadDate= DateHelper.format(date,"yyyy-MM-dd");
            beginDate= DateHelper.format(date2,"yyyy-MM-dd");
        }catch (Exception e){
            responseEntity.failure("000","传入日期格式错误，格式要求yyyy-MM-dd");
            return  responseEntity;
        }

        String thisMonth = DateHelper.format(new Date(),"yyyy-MM-dd");
        //判断时间是否合法
        if(loadDate.compareTo(thisMonth)>=0 && beginDate.compareTo(thisMonth) >=0){
            responseEntity.failure("000","传入时间错误，应小于本月！");
            return  responseEntity;
        }

        //判断索引名称是否符合要求
        String pattern = "^[a-z0-9_-]+$";
        if(!indexName.matches(pattern)){
            responseEntity.failure("000","传入索引名称不合法，小写字母和字母组合");
            return  responseEntity;
        }

        EsDataRecode recode = dao.getLastDataByIndex(indexName);
        if(recode != null ){
            if(loadDate.compareTo(beginDate)<=0){
                responseEntity.failure("000","结束时间要大于开始时间");
                return  responseEntity;
            }
            if(recode.getLoadDate().compareTo(loadDate)>=0){
                responseEntity.success("请求数据已经之前已经预加载完成！");
                return  responseEntity;
            }
            //将开始时间赋值为上次加载成功时间
            beginDate = recode.getLoadDate();
        }

        try{
            Method method = loadDataMapper.getClass().getMethod(methodName,Class.forName("com.baomidou.mybatisplus.extension.plugins.pagination.Page"),Class.forName("java.lang.String"),Class.forName("java.lang.String"));
            Page page = new Page<>(1, count);
            Object object =  method.invoke(loadDataMapper,page,beginDate,loadDate);
            List<T> list = castList(object,clazz);
            baseElasticService.insertBatchES(indexName,list);
            recode = new EsDataRecode();
            recode.setApiName(apiName);
            recode.setCreateTime(new Date());
            recode.setEsIndexName(indexName);
            recode.setLoadDate(loadDate);
            recode.setState(1);
            this.save(recode);
            responseEntity.success("数据加载成功！");
        }catch (Exception e){
            e.printStackTrace();
            responseEntity.failure("000","保存es数据出现异常，请重试！");
            return  responseEntity;
        }
        return  responseEntity;
    }


    public static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<T>();
        if (obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }
}
