package com.yihu.hos.datacollect.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yihu.hos.common.Services;
import com.yihu.hos.datacollect.dao.DatacollectDao;
import com.yihu.hos.datacollect.model.*;
import com.yihu.hos.resource.model.RsDatasourceDataset;
import com.yihu.hos.resource.service.StdService;
import com.yihu.hos.standard.model.adapter.AdapterDatasetModel;
import com.yihu.hos.standard.model.standard.StdDataSetModel;
import com.yihu.hos.system.service.FlowManager;
import com.yihu.hos.web.framework.model.ActionResult;
import com.yihu.hos.web.framework.model.DataGridResult;
import com.yihu.hos.web.framework.model.DictItem;
import com.yihu.hos.web.framework.model.SimpleChartItem;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service(Services.Datacollect)
public class DatacollectManager{

    public static final String BEAN_ID = Services.Datacollect;

    @Resource(name = DatacollectDao.BEAN_ID)
    private DatacollectDao datacollectDao;

    @Resource(name = StdService.BEAN_ID)
    private StdService stdManager;

    @Resource(name = FlowManager.BEAN_ID)
    private FlowManager flowManage;

    @Autowired
    private ObjectMapper objectMapper;

//    @Autowired
//    private QuartzManager quartzManager;

    /*********************** 任务管理 ****************************************/
    /**
     * 根据JobId获取Cron表达式
     */
    public String getCronByJobId(String jobId) throws Exception {
        return datacollectDao.getCronByJobId(jobId);
    }

    /**
     * 根据ID获取任务详细
     *
     * @return
     */

    public RsJobConfig getJobById(String id) throws Exception {
        return datacollectDao.getEntity(RsJobConfig.class, id);
    }

    /**
     * 获取任务列表
     */

    public DataGridResult getJobList(Map<String, Object> conditionMap, int page, int rows) throws Exception {
        DataGridResult re = datacollectDao.getJobList(conditionMap, page, rows);
        //获取任务列表
        List<RsJobConfig> list = re.getDetailModelList();

        if (list != null && list.size() > 0) {
            List<DtoJobConfig> dtoList = new ArrayList<>();
            for (RsJobConfig job : list) {
                DtoJobConfig dto = new DtoJobConfig();
                dto.setId(job.getId());
                dto.setJobContent(job.getJobContent());
                dto.setJobContentType(job.getJobContentType());
                dto.setJobInfo(job.getJobInfo());
                dto.setJobName(job.getJobName());
                dto.setJobNextTime(job.getJobNextTime());
                //dto.setJobTimeInterval(job.getJobTimeInterval());
                dto.setJobType(job.getJobType());
                dto.setSchemeId(job.getSchemeId());
                dto.setValid(job.getValid());

                //获取版本名称
                String schemeAndVersion = datacollectDao.getSchemeAndVersion(job.getSchemeVersion());
                dto.setSchemeAndVersion(schemeAndVersion);

                //获取关联数据集
                List<RsJobDataset> datasetList = datacollectDao.getJobDataset(job.getId());
                if (datasetList != null && datasetList.size() > 0) {
                    String ds = "";
                    for (RsJobDataset dataset : datasetList) {
                        ds += dataset.getJobDatasetName() + ",";
                    }
                    ds = ds.substring(0, ds.length() - 1);
                    dto.setJobDataset(ds);
                }

//                String cron = datacollectDao.getCronByJobId(job.getId());
                String cron = job.getJobCron();
                ////执行计划翻译
                dto.setJobPlan(translationCron(cron));

                dtoList.add(dto);
            }
            re.setDetailModelList(dtoList);
        }

        return re;
    }

    /**
     * 根据适配方案获取数据集列表
     */

    public DataGridResult getSchemeDataset(String schemeId, String schemeVersion, String jobId) throws Exception {
        //获取适配数据集总和
        List<AdapterDatasetModel> datasetString = stdManager.getDatasetByScheme(schemeVersion);
        String jsonlist = objectMapper.writeValueAsString(datasetString);
        ArrayNode jsonArray = objectMapper.readValue(jsonlist, ArrayNode.class);
        //获取任务数据集
        List<RsJobDataset> jobDataset = datacollectDao.getJobDataset(jobId);

        DataGridResult re = new DataGridResult();
        List<DtoJobDataset> list = new ArrayList<>();
        for(JsonNode jsonItem : jsonArray)
        {
            String datasetId= jsonItem.get("adapterDatasetId").toString();
            //配置完整才显示
            if(datasetId.length()>0&&jsonItem.get("adapterDatasetName").toString().length()>0&&jsonItem.get("adapterDatasetName").toString()!="null"&&jsonItem.get("adapterDatasetCode").toString().length()>0&&jsonItem.get("adapterDatasetCode").toString()!="null")
            {
                DtoJobDataset obj = new DtoJobDataset();
                obj.setJobDatasetName(jsonItem.get("adapterDatasetName").asText());
                obj.setJobDatasetCode(jsonItem.get("adapterDatasetCode").asText());
                obj.setJobDatasetId(datasetId);

                //是否关联任务
                if(jobDataset!=null&&jobDataset.size()>0)
                {
                    for(RsJobDataset jd :jobDataset)
                    {
                        if(jd.getJobDatasetId().equals(datasetId))
                        {
                            obj.setId(jd.getId());
                            obj.setJobId(jobId);
                            obj.setJobDatasetKeyvalue(jd.getJobDatasetKeyvalue());
                            obj.setJobDatasetKey(jd.getJobDatasetKey());
                            obj.setJobDatasetKeytype(jd.getJobDatasetKeytype());
                            obj.setChecked("1");
                            obj.setJobDatasetCondition(jd.getJobDatasetCondition());
                            break;
                        }
                    }

                }
                list.add(obj);
            }
        }
        re.setDetailModelList(list);

        return re;
    }

    /**
     * 根据适配方案获取字段列表
     */

    public DataGridResult getSchemeDatasetCol(String schemeId, String schemeVersion, String datasetId) throws Exception {
        //获取适配字段
        List datacolString = stdManager.getDatacolByScheme(schemeVersion, datasetId);
        JSONArray datacolList = JSONArray.fromObject(datacolString);

        DataGridResult re = new DataGridResult();
        List<DtoDatasetCol> list = new ArrayList<>();
        for(Object item : datacolList)
        {
            JSONObject jsonItem = JSONObject.fromObject(item);
            DtoDatasetCol obj = new DtoDatasetCol();
            obj.setCode(jsonItem.getString("adapterMetadataCode"));
            obj.setText(jsonItem.getString("adapterMetadataName"));
            obj.setType(jsonItem.getString("adapterMetadataType"));
            obj.setDict(jsonItem.getString("stdDictId"));

            list.add(obj);
        }
        re.setDetailModelList(list);

        return re;
    }

    /**
     * 根据任务Id获取相关数据集下拉数据
     */

    public DataGridResult getJobDatasetByJobId(String jobId) throws Exception {
        //获取任务数据集
        List<RsJobDataset> jobDataset = datacollectDao.getJobDataset(jobId);

        DataGridResult re = new DataGridResult();
        List<DictItem> list = new ArrayList<>();

        for (RsJobDataset obj : jobDataset) {
            DictItem item = new DictItem();
            item.setValue(obj.getJobDatasetName());
            item.setCode(obj.getJobDatasetId());
            list.add(item);
        }
        re.setDetailModelList(list);
        return re;
    }

    /**
     * 新增任务
     */

    @Transactional
    public ActionResult addJob(RsJobConfig obj, String cron, String jobDataset) throws Exception {
        datacollectDao.saveEntity(obj);//保存任务
        Integer flowId = flowManage.genCamelFile(obj.getId(),obj.getFlowTempId(),cron);
        if (flowId!=null){
            obj.setFlowId(flowId);
            datacollectDao.updateEntity(obj);
            saveJobDataset(obj.getId(), jobDataset);
            return new ActionResult(true, "新增任务成功！");

        }else {
            datacollectDao.deleteEntity(obj);
            return new ActionResult(false, "新增任务失败-关联流程环节失败！");

        }

        //quartz新增任务
//        quartzManager.addJob(obj.getId(), obj.getJobContentType(), obj.getJobContent(), obj.getJobNextTime(), cron);
    }

    /**
     * 修改任务
     */

    @Transactional
    public ActionResult updateJob(RsJobConfig obj, String cron, String jobDataset) throws Exception {
        Integer flowId = flowManage.updateCamelFile(obj.getId(),obj.getFlowTempId(), obj.getFlowId(), cron);
        if (flowId!=null){
            obj.setFlowId(flowId);
            datacollectDao.updateEntity(obj);
            saveJobDataset(obj.getId(), jobDataset);

            //quartz修改cron表达式
//        quartzManager.modifyJob(obj.getId(), obj.getJobContentType(), obj.getJobContent(), obj.getJobNextTime(), cron);
            return new ActionResult(true, "修改成功！");
        }else {
            return new ActionResult(false, "修改失败，关联流程失败！");
        }

    }

    /**
     * 修改任务
     */

    @Transactional
    public ActionResult updateJob(RsJobConfig obj) throws Exception {
        datacollectDao.updateEntity(obj);
        return new ActionResult(true, "修改成功！");
    }

    /**
     * 修改任务状态
     */
    @Transactional
    public ActionResult validJob(String jobId, String valid) throws Exception {
        datacollectDao.validJob(jobId, valid);
        //暂停Quartz任务
        if (valid.equals("0")) {
//            quartzManager.pauseJob(jobId);
        } else { //恢复Quartz任务
//            quartzManager.resumeJob(jobId);
        }

        return new ActionResult(true, "状态修改成功！");
    }

    /**
     * 删除任务
     */
    @Transactional
    public ActionResult deleteJob(String jobId) throws Exception {
        //清空任务关联数据集
        datacollectDao.deleteJobDatasetByJobId(jobId);
        //删除相关流程记录
        RsJobConfig entity = datacollectDao.getEntity(RsJobConfig.class, jobId);
        if (entity.getFlowId()!=null){
           flowManage.deleteFlow(entity.getFlowId());
        }
        datacollectDao.deleteEntity(entity);

        //删除Quartz任务
//        quartzManager.removeJob(jobId);
        return new ActionResult(true, "删除成功！");
    }

    /**
     * 数据集数据源管理列表（包含全部数据集）
     */

    public DataGridResult getDatasetSource(String stdVersion) throws Exception {
        //获取版本下全部数据集
        List<StdDataSetModel> stdDataSetModelList = stdManager.getDatasetByVersion(stdVersion);
        String jsonlist = objectMapper.writeValueAsString(stdDataSetModelList);
        ArrayNode datasetList = objectMapper.readValue(jsonlist, ArrayNode.class);
        //获取已配数据集
        List<RsDatasourceDataset> jobDataset = datacollectDao.getDatasourceDataset(stdVersion);

        DataGridResult re = new DataGridResult();
        List<JsonNode> list = new ArrayList<>();
        for (JsonNode obj : datasetList) {
            ObjectNode dd = objectMapper.createObjectNode();
            dd.put("datasetId", obj.get("id").asText());
            dd.put("datasetCode", obj.get("code").asText());
            dd.put("datasetName", obj.get("name").asText());
            dd.put("stdVersion", stdVersion);

            if (jobDataset != null && jobDataset.size() > 0) {
                for (RsDatasourceDataset rdd : jobDataset) {
                    if (rdd.getDatasetId().equals(obj.get("id").asText())) {
                        dd.put("orgId", rdd.getOrgId());
                        dd.put("datasourceId", rdd.getDatasourceId());
                        dd.put("id", rdd.getId());
                        break;
                    }
                }
            }
            list.add(dd);
        }
        re.setDetailModelList(list);

        return re;
    }

    /**
     * 保存数据集数据源配置
     */

    @Transactional
    public ActionResult saveDatasetSource(String json) throws Exception {
        //TODO: Use jackson
        JSONArray jsonList = JSONArray.fromObject(json);


        for (Object item : jsonList) {
            JSONObject obj = JSONObject.fromObject(item);
            if (obj.containsKey("id") && obj.getString("id").length() > 0) {
                String id = obj.getString("id");
                //修改
                RsDatasourceDataset dd = (RsDatasourceDataset) JSONObject.toBean(obj, RsDatasourceDataset.class);
                datacollectDao.updateEntity(dd);
//                if(obj.containsKey("datasourceId") && obj.getString("datasourceId").length()>0)
//                {
//                    RsDatasourceDataset dd = (RsDatasourceDataset)JSONObject.toBean(obj,RsDatasourceDataset.class);
//                    datacollectDao.updateEntity(dd);
//                }
//                //删除
//                else{
//                    datacollectDao.deleteEntity(RsDatasourceDataset.class,id);
//                }
            } else {
                //新增
                RsDatasourceDataset dd = (RsDatasourceDataset) JSONObject.toBean(obj, RsDatasourceDataset.class);
                datacollectDao.saveEntity(dd);
            }
        }

        return new ActionResult(true, "保存成功！");

    }

    /************************* 数据集数据源管理 ***************************************************/

    /**
     * 获取任务详细日志列表
     */

    public DataGridResult getJobLogDetail(Map<String, Object> conditionMap, int page, int rows) throws Exception {
        return datacollectDao.getJobLogDetail(conditionMap, page, rows);
    }

    /**
     * 获取任务日志列表
     */

    public DataGridResult getJobLog(Map<String, Object> conditionMap, int page, int rows) throws Exception {
        DataGridResult re = datacollectDao.getJobLog(conditionMap, page, rows);

        List<RsJobLog> logList = re.getDetailModelList();

        List<DtoJobLog> list = new ArrayList<>();
        for (RsJobLog log : logList) {
            DtoJobLog dto = new DtoJobLog();
            BeanUtils.copyProperties(log, dto);
            List<Map<String, Object>> maps = datacollectDao.getJobLogCount(log.getId());

            if (maps != null && maps.size() > 0) {
                int count = Integer.parseInt(String.valueOf(maps.get(0).get("count")));
                int success = Integer.parseInt(String.valueOf(maps.get(0).get("success")));
                int repeat_num = Integer.parseInt(String.valueOf(maps.get(0).get("repeat_num")));
                dto.setCount(count);
                dto.setSuccess(success);
                dto.setRepeatNum(repeat_num);
            } else {
                dto.setCount(0);
                dto.setSuccess(0);
                dto.setRepeatNum(0);
            }
            list.add(dto);
        }
        re.setDetailModelList(list);

        return re;
    }

    /********************** 任务日志管理 *******************************************/

    /**
     * 任务详细根据数据集分组
     *
     * @return
     */

    public DataGridResult getJobLogDataset(String logId) throws Exception {
        DataGridResult re = new DataGridResult();
        List<SimpleChartItem> maps = datacollectDao.getJobLogDataset(logId);
        re.setDetailModelList(maps);


        return re;
    }

    /**
     * 翻译Cron表达式
     *
     * @return
     */
    private String translationCron(String cron) {
        try {
            if (cron != null && cron.length() > 0) {
                String re = "";
                String[] items = cron.split(" ");
                if (!items[5].equals("?")) //周
                {
                    String[] weekDay = items[5].split(",");
                    for (String day : weekDay) {
                        String WeekDay = day;
                        if (day.equals("1")) {
                            WeekDay = "日";
                        } else if (day.equals("2")) {
                            WeekDay = "一";
                        } else if (day.equals("3")) {
                            WeekDay = "二";
                        } else if (day.equals("4")) {
                            WeekDay = "三";
                        } else if (day.equals("5")) {
                            WeekDay = "四";
                        } else if (day.equals("6")) {
                            WeekDay = "五";
                        } else if (day.equals("7")) {
                            WeekDay = "六";
                        }

                        re += "星期" + WeekDay + ",";
                    }
                    re = re.substring(0, re.length() - 1);
                } else {
                    if (!items[3].equals("*")) {
                        String v = items[3];
                        if (v.indexOf('/') > 0) //天
                        {
                            String[] varry = v.split("/");
                            re = "每隔" + varry[1] + "天";
                        } else {//月
                            if (v.equals("1")) {
                                re = "每月第一天";
                            } else if (v.equals("L")) {
                                re = "每月最后一天";
                            } else {
                                re = "每月第" + v + "天";
                            }
                        }
                    } else {
                        String v1 = items[1];
                        String v2 = items[2];
                        if (v1.indexOf('/') > 0) //分
                        {
                            String[] varry = v1.split("/");
                            re = "每隔" + varry[1] + "分钟";
                        } else { //时
                            String[] varry = v2.split("/");
                            re = "每隔" + varry[1] + "小时";
                        }
                    }
                }
                return re + "执行";
            }
            return cron;
        } catch (Exception ex) {
            return cron;
        }
    }

    /**
     * 保存任务关联数据集
     */
    private void saveJobDataset(String jobId, String jobDataset) throws Exception {
        if(jobDataset!=null&&jobDataset.length()>0) {
            //清空任务关联数据集
            datacollectDao.deleteJobDatasetByJobId(jobId);

            ArrayNode array = objectMapper.readValue(jobDataset,ArrayNode.class);
            if (array != null && array.size() > 0) {
                for (JsonNode obj : array) {
                    RsJobDataset rs = new RsJobDataset();
                    if(obj.get("jobDatasetCondition")!=null&&obj.get("jobDatasetCondition").asText()!="null")
                    {
                        rs.setJobDatasetCondition(obj.get("jobDatasetCondition").asText());
                    }
                    if(obj.get("jobDatasetId")!=null&&obj.get("jobDatasetId").asText()!="null") {
                        rs.setJobDatasetId(obj.get("jobDatasetId").asText());
                    }
                    if(obj.get("jobDatasetKey")!=null&&obj.get("jobDatasetKey").asText()!="null") {
                        rs.setJobDatasetKey(obj.get("jobDatasetKey").asText());
                    }
                    if(obj.get("jobDatasetKeytype")!=null&&obj.get("jobDatasetKeytype").asText()!="null") {
                        rs.setJobDatasetKeytype(obj.get("jobDatasetKeytype").asText());
                    }
                    if(obj.get("jobDatasetKeyvalue")!=null&&obj.get("jobDatasetKeyvalue").asText()!="null") {
                        rs.setJobDatasetKeyvalue(obj.get("jobDatasetKeyvalue").asText());
                    }
                    if(obj.get("jobDatasetName")!=null&&obj.get("jobDatasetName").asText()!="null") {
                        rs.setJobDatasetName(obj.get("jobDatasetName").asText());
                    }
                    rs.setJobId(jobId);
                    datacollectDao.saveEntity(rs);
                }
            }
        }
        else{
            return;
        }
    }



}
