package com.hs.admin.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hs.admin.base.PageResult;
import com.hs.admin.bean.*;
import com.hs.admin.dao.JcbDao;
import com.hs.admin.dao.SysTaskDao;
import com.hs.admin.service.TaskService;
import com.hs.admin.util.DateUtil;
import com.hs.admin.util.DbUtil;
import com.hs.admin.util.JsonUtils;
import com.hs.admin.util.LogUtil;
import com.hs.admin.vo.ResponseVO;
import com.hs.admin.vo.ResultVO;
import org.apache.http.client.utils.DateUtils;
import org.quartz.CronExpression;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;

/**
 * @author xieheng
 */
@Service
public class TaskServiceImpl implements TaskService {
    @Resource
    SysTaskDao sysTaskDao;
    @Resource
    JcbDao jcbDao;

    @Override
    public PageResult<Map> getTaskRecordList(String jcbId, Integer pageNum, Integer pageSize) {
        Integer index = (pageNum - 1) * pageSize;
        Long totalCount = sysTaskDao.getTotalCountById(jcbId);
        List<Map> jcbList = sysTaskDao.findPage(jcbId, index, pageSize);
        Map tmp = jcbList.get(0);
        DataBase dataBase = new DataBase();
        dataBase.setHost(tmp.get("host").toString());
        dataBase.setPort(tmp.get("port").toString());
        dataBase.setName(tmp.get("dbName").toString());
        dataBase.setUsername(tmp.get("dbUsername").toString());
        dataBase.setPassword(tmp.get("dbPwd").toString());
        dataBase.setDbType(tmp.get("dbType").toString());
        List<Map> list = new ArrayList<>();
        for (Map map : jcbList) {
            Map<String, Object> result = new HashMap<>();
            result.put("jcbId", jcbId);
            result.put("jcbName", map.get("jcbName").toString());
            result.put("jobName", map.get("jobName").toString());
            Object contentObj = map.get("content");
            if (!ObjectUtils.isEmpty(contentObj)) {
                String content = contentObj.toString();
                ResponseVO vo = null;
                try {
                    vo = JsonUtils.jsonToBean(content, ResponseVO.class);
                } catch (Exception e) {
                    continue;
                }
                Object params = vo.getParams();
                if (!ObjectUtils.isEmpty(params)) {
                    SysTask task = JsonUtils.jsonToBean(params.toString(), SysTask.class);
                    MqData mqData = JsonUtils.jsonToBean(task.getContent(), MqData.class);
                    String tableName = mqData.getTableName();
                    String cronExpression = task.getCronExpression();
                    if (!ObjectUtils.isEmpty(tableName)) {
                        getTableTime(tableName, dataBase, map);
                    } else {
                        Object createTime = map.get("createTime");
                        Date date = new Date(Long.valueOf(String.valueOf(createTime)));
                        map.put("lastExecuteTime", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
                    }
                    if (!ObjectUtils.isEmpty(cronExpression)) {
                        getNextExecuteTime(cronExpression, map);
                    }
                }
            }
        }
        return new PageResult<>(totalCount, jcbList);
    }

    private Map getNextExecuteTime(String cronExpression, Map map) {
        if (ObjectUtils.isEmpty(cronExpression)) {
            map.put("nextTime", "");
        } else {
            try {
                CronExpression cron = new CronExpression(cronExpression);
                Date date = cron.getNextValidTimeAfter(new Date());
                map.put("nextTime", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    private Map getTableTime(String tableName, DataBase dataBase, Map map) {
        JdbcTemplate jdbcTemplate = DbUtil.getJdbcTemplate(dataBase);
        TableLog tableLog = null;
        try {
            tableLog = jdbcTemplate.queryForObject("select * from table_log where table_name=?", new BeanPropertyRowMapper<>(TableLog.class), tableName);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        if (!ObjectUtils.isEmpty(tableLog)) {
            Date hsCloudLastTime = tableLog.getHsCloudLastTime();
            map.put("lastExecuteTime", DateUtil.format(hsCloudLastTime, "yyyy-MM-dd HH:mm:ss"));
        } else {
            Object createTime = map.get("createTime");
            Date date = new Date(Long.valueOf(String.valueOf(createTime)));
            map.put("lastExecuteTime", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
        }
        return map;
    }

    @Override
    public PageResult<Map> getTaskListByCid(Integer cid, String jcbId, Integer pageNum, Integer pageSize) {
        Integer index = (pageNum - 1) * pageSize;
        Long totalCount = sysTaskDao.getRecordTotalCount(cid, jcbId);
        List<Map> jcbList = sysTaskDao.findPageByCid(cid, jcbId, index, pageSize);
        if (!CollectionUtils.isEmpty(jcbList)) {
            for (Map map : jcbList) {
                String ctype = map.get("ctype").toString();
                String content = map.get("content").toString();
                ResponseVO vo = null;
                try {
                    vo = JsonUtils.jsonToBean(content, ResponseVO.class);
                } catch (Exception e) {
                    map.put("content", "");
                    continue;
                }
                ResultVO resultVO = vo.getResultVO();
                if (ObjectUtils.isEmpty(resultVO)) {
                    map.put("content", "");
                } else {
                    //除上传操作不显示result
                    if (!"2".equals(ctype)) {
                        resultVO.setResult(null);
                    }
                    map.put("content", resultVO);
                }
            }
        }
        return new PageResult<>(totalCount, jcbList);
    }

    @Override
    public String getContentById(Integer id) {
        return sysTaskDao.getContentById(id);
    }
}