package com.highdatas.mdm.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.highdatas.mdm.entity.SysAssemble;
import com.highdatas.mdm.service.ISysAssembleService;
import com.highdatas.mdm.util.Constant;
import com.highdatas.mdm.util.DbUtils;
import com.highdatas.mdm.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@ConfigurationProperties(prefix = "xxljob")
@Component
public class JobClient {

    @Value("${xxljob.url}")
    String url;

    @Value("${xxljob.local}")
    String local;
    @Autowired
    ISysAssembleService assembleService;
    @Autowired
    RestTemplate client;
    String prefix ;

    private JobClient() {
        this.prefix = "/xxl-job-admin/";
    }
    public  boolean login() {
        String url = this.url + prefix + "login";
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.set("userName","mdmadmin");
        params.set("password","datacvg123");
        params.set("ifRemember","false");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.putAll(params);
        String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);
        String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, null);
        JSONObject result = (JSONObject) JSON.parse(s);
        boolean success = parse(result);
        return  success;
    }

    private boolean parse(JSONObject result) {
        boolean success = true;
        Integer code = result.getInteger(Constant.Code);
        if (code == 200) {
            success = true;
        }else {
            success = false;
        }
        return success;
    }


    public boolean saveJobGroup() {
        try {
            String url =  this.url + prefix + "xxlcustapi/saveJobGroup";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("appName","MDMApp");
            params.set("order", "1");
            params.set("title","数据汇集定时任务执行器");
            params.set("modelId","MDM");
            params.set("addressType","1");
            params.set("addressList",local);
            String s = null;
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);

            s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, MediaType.APPLICATION_JSON);

            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求saveJobGroup失败:" + result.getString("msg"));
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    public boolean removeJobGroup() {
        try {
            String url =  this.url + prefix + "xxlcustapi/saveJobGroup";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("modelid","MDM");
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);
            String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, null);
            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求saveJobGroup失败:" + result.getString("msg"));
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }


    public boolean addJob(SysAssemble assemble) {
        try {
            String jobId = createJobId(assemble.getId());
            String url =  this.url + prefix + "xxlcustapi/addJob";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("modelId","MDM");
            params.set("modelJobId", jobId);
            params.set("jobCron",assemble.getCron());
            params.set("author",assemble.getUserId());
            params.set("executorHandler","assembleJob");
            params.set("executorParam",assemble.getId());
            params.set("cronGen_display",assemble.getCron());
            params.set("executorBlockStrategy","DISCARD_LATER");
            params.set("executorTimeout","0");
            params.set("executorFailRetryCount","3");
            params.set("triggerStatus","1");
            params.set("glueType","BEAN");
            params.set("executorRouteStrategy","FIRST");
            params.set("jobDesc","创建汇集job");
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);

            String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, MediaType.APPLICATION_JSON);
            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求addJob失败:" + result.getString("msg"));
            }else{
                assemble.setJobId(jobId).updateById();
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    private String createJobId(String id) {
        if (StringUtils.isEmpty(id)) {
            id = DbUtils.getUUID();
        }
        try {
            String jobId  = "MDM-" + DbUtils.Bit16(id);
            return jobId;
        } catch (Exception e) {
            e.printStackTrace();
            return id;
        }
    }

    public boolean updateJob(SysAssemble assemble) {
        try {
            String url =  this.url + prefix + "xxlcustapi/updateJob";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("modelId","MDM");
            params.set("modelJobId",assemble.getJobId());
            params.set("jobCron",assemble.getCron());
            params.set("author",assemble.getUserId());
            params.set("executorHandler","assembleJob");
            params.set("executorParam",assemble.getId());
            params.set("cronGen_display",assemble.getCron());
            params.set("executorBlockStrategy","DISCARD_LATER");
            params.set("executorTimeout","0");
            params.set("executorFailRetryCount","3");
            params.set("triggerStatus","1");
            params.set("glueType","BEAN");
            params.set("executorRouteStrategy","FIRST");
            params.set("jobDesc","更新汇集job");
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);

            String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, MediaType.APPLICATION_JSON);
            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求updateJob失败:" + result.getString("msg"));
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    public boolean deleteJob(String jobId) {

        try {
            String url =  this.url + prefix + "xxlcustapi/removeJob";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("modelId","MDM");
            params.set("modelJobId", jobId);

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);

            String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, MediaType.APPLICATION_JSON);
            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求deleteJob失败:" + result.getString("msg"));
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    public boolean queryJobLogById(SysAssemble assemble) {
        if (StringUtils.isEmpty(assemble.getJobId())) {
            return false;
        }
        try {
            String url =  this.url + prefix + "xxlcustapi/queryJobLogById";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("modelId","MDM");
            params.set("modelJobId", assemble.getJobId());

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);

            String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, MediaType.APPLICATION_JSON);
            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求queryJobLogById失败:" + result.getString("msg"));
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    public boolean trigger(SysAssemble assemble) {
        if (StringUtils.isEmpty(assemble.getJobId())) {
            return false;
        }
        try {
            String url =  this.url + prefix + "xxlcustapi/trigger";
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.set("modelId","MDM");
            params.set("modelJobId", assemble.getJobId());
            params.set("executorParam", assemble.getId());

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.putAll(params);
            String urlParamsByMap = HttpUtils.getUrlParamsByMap(paramMap);

            String s = HttpRestClient(url, HttpMethod.POST, null, urlParamsByMap, MediaType.APPLICATION_JSON);
            JSONObject result = (JSONObject) JSON.parse(s);
            boolean success = parse(result);
            if (!success){
                log.error("请求trigger失败:" + result.getString("msg"));
            }
            return success;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }


    private  String     HttpRestClient(String url, HttpMethod method, MultiValueMap<String, String> formParams, String getParams,  MediaType mediaType) {
        if (!StringUtils.isEmpty(getParams)) {
            url = url + Constant.QUESTION + getParams;
        }

        client.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));
        HttpHeaders headers = new HttpHeaders();
        if (mediaType == null){
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        }else {
            headers.setContentType(mediaType);
        }

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(formParams, headers);
        //  执行HTTP请求
        ResponseEntity<String> response = client.exchange(url, method, requestEntity, String.class);

        return response.getBody();
    }
}