package cn.ibizlab.api.rest.extensions;

import cn.ibizlab.core.analysis.domain.DAMetric;
import cn.ibizlab.core.analysis.domain.DAReport;
import cn.ibizlab.core.analysis.service.impl.DAReportServiceImpl;
import cn.ibizlab.core.extensions.cql.ExecResult;
import cn.ibizlab.core.extensions.cql.ExecResultRepository;
import cn.ibizlab.core.extensions.domain.FetchMetricDatasParam;
import cn.ibizlab.core.extensions.service.DACoreService;
import cn.ibizlab.core.extensions.service.DAMetricExService;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.DataObject;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Api(tags = {"接口" })
@RestController("api-dacore")
@RequestMapping("")
public class DACoreResource {

    @Autowired
    private DACoreService daCoreService;

    @Autowired
    private DAReportServiceImpl daReportService;

    @Autowired
    @Lazy
    private ExecResultRepository execResultRepository;
    @Autowired
    @Lazy
    private DAMetricExService daMetricExService;
    // 删除cql结果批次大小
    @Value("${ibiz.execresult.deletesize: 20}")
    private int deletesize;

    /**
     * 通过指标获取相应的规则结果数据
     * @param param
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value="/dst/analyse/reportdata/fetchmetricdatas")
    public ResponseEntity<List<HashMap<String,Object>>> fetchMetricDatas(@Validated @RequestBody FetchMetricDatasParam param){
        List<HashMap<String,Object>> execResults = daCoreService.onFetchMetricDatas(param);
        return ResponseEntity.status(HttpStatus.OK).body(execResults);
    }

    /**
     * 呈报报表获取数据
     * @param param
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/dst/analyse/reportdata/fetchreportdatas")
    public ResponseEntity<Map<String,Object>> fetchReportDatas(@Validated @RequestBody FetchMetricDatasParam param) {
        Map<String, Object> resultMap = daCoreService.onFetchReportDatas(param);
        return ResponseEntity.status(HttpStatus.OK).body(resultMap);
    }

    /**
     * 获取反查数据用到的keyvalue
     * @param param
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value="/dst/analyse/reportdata/fetchkeyvaluefield")
    public ResponseEntity<Map<String, String>> fetchKeyValueField(@Validated @RequestBody FetchMetricDatasParam param) {
        Map<String, String> results = daCoreService.onFetchKeyValueField(param);
        return ResponseEntity.status(HttpStatus.OK).body(results);
    }

    /**
     * 清除绩效数据缓存
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value="/dst/analyse/reportdata/resetperformancedata/{resettype}")
    public ResponseEntity<Map<String, Object>> resetPerformanceData(@PathVariable(name="resettype",required = false) String resettype) {
        Map<String, Object> resultMap = new HashMap<>();
        if (StringUtils.isEmpty(resettype)) {
            throw new BadRequestAlertException("请求参数为空", "", "");
        }
        String strType = resettype.toUpperCase();
        switch (strType) {
            case "WORK_ALL":// 消除所有的缓存
                this.daCoreService.resetsnap();
                break;
            case "WORK":// 消除指定指标的缓存
                this.daCoreService.resetsnapSingle();
                break;
            case "JXKH":// 消除绩效报表的缓存
                daCoreService.resetPerformance();
                daCoreService.resetsnap();
                break;
            case "RELOADREPORTDATA":// 消除绩效报表的缓存
                daCoreService.resetsnapReport();
                break;
            default:
                break;
        }
        return ResponseEntity.status(HttpStatus.OK).body(resultMap);
    }

    /**
     * 获取绩效数据
     * @param param
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value="/dst/analyse/reportdata/fetchperformancedata")
    public Map<String, Object> fetchPerformanceData(@Validated @RequestBody FetchMetricDatasParam param) {
        if(param == null){
            return new HashMap<String,Object>();
        }
        String id = param.getReportid();
        if (StringUtils.isEmpty(id)) {
            return new HashMap<String,Object>();
        }
        //获取表头及表单名称
        DAReport daReport = daReportService.getById(id);
        String vmcfg = daReport != null ? daReport.getConfig() : "";
        String reportname = daReport != null ? daReport.getReportName() : "";
        //获取表格数据
//        getData(id);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap = daCoreService.getPerformanceReportData(daReport, param.getDimField(), param.getStarttime(), param.getEndtime());
        resultMap.put("vmcfg",vmcfg);
        resultMap.put("reportname",reportname);
        resultMap.put("dataDict", daReport.getDict());
//        resultMap.put("resportdata",jsonObject);
        return resultMap;
    }

    /**
     * 刷新报表缓存
     * @param param
     * @return
     */
    @PostMapping(value="/dst/analyse/reportdata/reloadreportcache")
    public Map<String, Object> reloadReportCache(@Validated @RequestBody FetchMetricDatasParam param) {
        Map<String, Object> resultMap = new HashMap<>();
        if (param == null) {
            throw new BadRequestAlertException("刷新报表缓存错误，错误原因：请求参数为空", "", "");
        }
        String id = param.getReportid();
        if (StringUtils.isEmpty(id)) {
            return new HashMap<String,Object>();
        }
        DAReport daReport = daReportService.getById(id);
        if (daReport == null) {
            throw new BadRequestAlertException("报表不存在", "", "");
        }
        String strDimval = StringUtils.isEmpty(param.getDimval()) ? "%" : param.getDimval();
        String strDict = StringUtils.isEmpty(param.getDimcodelist()) ? daCoreService.getDict(daReport) : param.getDimcodelist();
        Timestamp startTime = param.getStarttime() == null ? daCoreService.getDefaultStartTimestamp() : param.getStarttime();
        Timestamp endTime = param.getEndtime() == null ? daCoreService.getDefaultEndTimestamp() : param.getEndtime();
        daCoreService.resetsnapReport();
        param.setDimcodelist(strDict);
        param.setDimval(strDimval);
        param.setStarttime(startTime);
        param.setEndtime(endTime);
        this.fetchReportDatas(param);
        return resultMap;
    }

    /**
     * 删除cql库中结果数据
     * @param param
     * @return
     */
    @PostMapping(value="/dst/analyse/reportdata/deleteexecresult")
    public ResponseEntity<JSONObject> deleteRuleResultData(@RequestBody JSONObject param){
        long t1 = DataObject.getNow().getTime();
        JSONObject jsonObject = new JSONObject();
        try{
            String type = param.getString("type");
            if (StringUtils.isEmpty(type)){
                jsonObject.put("success",false);
                jsonObject.put("message","未指定清除类型！");
                return ResponseEntity.ok().body(jsonObject);
            }
            JSONArray list = param.getJSONArray("list");
            if ("datakey".equalsIgnoreCase(type)){
                JSONArray buildArray = param.getJSONArray("build");
                if (StringUtils.isEmpty(list) || list.size() == 0 || StringUtils.isEmpty(buildArray) || buildArray.size() == 0){
                    jsonObject.put("success",false);
                    jsonObject.put("message","业务数据主键集合或者构建主键集合为空！");
                    return ResponseEntity.ok().body(jsonObject);
                }
                // 获取所有构建分析数据对应的指标标识
                List<String> ruleids = new ArrayList<>();
                for (int i = 0; i < buildArray.size(); i++) {
                    List<DAMetric> daMetricList = daMetricExService.list(Wrappers.<DAMetric>lambdaQuery().eq(DAMetric::getBuildId, buildArray.getString(i)));
                    for (DAMetric daMetric : daMetricList) {
                        ruleids.add(daMetric.getMetricId());
                    }
                }
                if (ruleids.size() == 0){
                    jsonObject.put("success",false);
                    jsonObject.put("message","未获取到指定构建对应的指标标识！");
                    return ResponseEntity.ok().body(jsonObject);
                }
                List<String> tempList = new ArrayList<>();
                for (int i = 0; i < list.size(); i++) {
                    for (String rule : ruleids) {
                        tempList.add(rule);
                        if (tempList.size() >= deletesize){
                            long start  = DataObject.getNow().getTime();
                            execResultRepository.deleteData(tempList, list.getString(i));
                            log.info("根据指标标识：" + tempList + "，业务数据主键：" + list.getString(i) +  "，删除cql结果，耗时：" + (DataObject.getNow().getTime()-start) + "毫秒");
                            tempList.clear();
                        }
                    }
                    if (tempList.size() > 0){
                        long start  = DataObject.getNow().getTime();
                        execResultRepository.deleteData(tempList, list.getString(i));
                        log.info("根据指标标识：" + tempList + "，业务数据主键：" + list.getString(i) +  "，删除cql结果，耗时：" + (DataObject.getNow().getTime()-start) + "毫秒");
                        tempList.clear();
                    }
                }
                jsonObject.put("success",true);
                jsonObject.put("message","清除结果数据完成!");
            }else if ("rule".equalsIgnoreCase(type)){
                if (StringUtils.isEmpty(list) || list.size() == 0){
                    jsonObject.put("success",false);
                    jsonObject.put("message","指标标识集合为空！");
                    return ResponseEntity.ok().body(jsonObject);
                }
                List<String> tempList = new ArrayList<>();
                for (int i = 0; i < list.size(); i++) {
                    tempList.add(list.getString(i));
                }
                long start  = DataObject.getNow().getTime();
                execResultRepository.deleteData(tempList);
                log.info("根据指标标识：" + list + "，删除cql结果成功，耗时：" + (DataObject.getNow().getTime()-start) + "毫秒");

                jsonObject.put("success",true);
                jsonObject.put("message","清除结果数据完成!");
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("success",false);
            jsonObject.put("message","清除结果数据失败!原因：" + e.getMessage());
        }
        String cost = (DataObject.getNow().getTime() - t1) + "毫秒";
        jsonObject.put("cost", cost);
        log.info("删除cql结果数据执行完成，耗时：" + cost);
        return ResponseEntity.ok().body(jsonObject);
    }

    /**
     * 刷新指定指标数据并重新加载
     * @param param
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value="/dst/analyse/reportdata/reload/fetchmetricdatas")
    public ResponseEntity<List<HashMap<String,Object>>> reloadFetchMetricDatas(@Validated @RequestBody FetchMetricDatasParam param) {
        if (param == null) {
            return ResponseEntity.status(HttpStatus.OK).body(new ArrayList<HashMap<String,Object>>());
        }
        daCoreService.resetCache(param);
        return this.fetchMetricDatas(param);
    }
}
