package com.zfire.jiasm.syncdata.gree.recycle;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zfire.jiasm.syncdata.constant.Constant;
import com.zfire.jiasm.syncdata.gree.CommonLogic;
import com.zfire.jiasm.syncdata.gree.CommonParam;
import com.zfire.jiasm.syncdata.gree.OutAppDefaultReq;
import com.zfire.jiasm.syncdata.gree.helper.GreeResponseHelper;
import com.zfire.jiasm.syncdata.helper.ResponseExHelper;
import com.zfire.jiasm.syncdata.http.HttpUtils;
import com.zfire.jiasm.syncdata.plus.service.ProductService;
import com.zfire.jiasm.syncdata.utils.RedisUtil;
import com.zfire.jiasm.syncdata.utils.RemoteServiceException;
import com.zfire.jiasm.syncdata.utils.ResponseHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 格力总部接口
 */
@Slf4j
@Service
public class GreeLogicT {
    @Value("${gree.V3.gettoken}")
    private String tokenUrl;
    @Value("${gree.check.barcode}")
    private String checkBarcodeUrl;
    @Value("${gree.repair.settle.get}")
    private String getRepairSettleUrl;
    @Value("${gree.repair.settle.do}")
    private String doRepairSettleUrl;
    @Value("${gree.client.id}")
    private String clientId;
    @Value("${gree.V3.client.secert}")
    private String clientSecert;
    @Value("${gree.api.url}")
    private String apiUrl;
    @Value("${gree.gz.appid}")
    private String gzAppId;
    @Value("${gree.gz.appkey}")
    private String gzAppKey;
    @Value("${gree.fs.appid}")
    private String fsAppId;
    @Value("${gree.fs.appkey}")
    private String fsAppKey;
    @Value("${gree.V3.api.url}")
    private String v3ApiUrl;
    @Value("${gree.V3.gettoken}")
    private String v3TokenUrl;
    @Value("${gree.V3.client.secert}")
    private String v3ClientSecert;
    
    /*@Autowired
    ProductNewService productNewService;*/
    @Autowired
    ProductService productService;
    /*@Autowired
    RuleService ruleService;*/
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    CommonLogic commonLogic;

    public String getAppId(Integer belongType){
        if(belongType == 1){
            return gzAppId;
        }else{
            return fsAppId;
        }
    }

    public String getAppKey(Integer belongType){
        if(belongType == 1){
            return gzAppKey;
        }else{
            return fsAppKey;
        }
    }
    
    /**
     * 获取总部接口的请求token
     * @return
     * @throws RemoteServiceException
     */
    public String getAccessToken() throws RemoteServiceException {
        String redisKey = Constant.RedisPrefix.TOKEN_GREE;
        String token = (String)redisUtil.get(redisKey);
        if(token != null){
            return token;
        }
        MultiValueMap<String, String> forms= new LinkedMultiValueMap<String, String>();

        forms.put("client_id", Collections.singletonList(clientId));
        forms.put("client_secret", Collections.singletonList(clientSecert));
        forms.put("grant_type", Collections.singletonList("client_credentials"));
        String s = HttpUtils.requestXwww(tokenUrl, forms);
        //String s = HttpUtils.requestPostForm(tokenUrl, map, null);
        // log.info("【获取总部token】response:{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        String accessToken = jsonObject.getString("access_token");
        if(StringUtils.isNotEmpty(accessToken)) {
            redisUtil.set(Constant.RedisPrefix.TOKEN_GREE, accessToken, 2 * 60 * 60);
        }
        return accessToken;
    }
    
    /**
     * 获取总部接口的请求token
     * @return
     * @throws RemoteServiceException
     */
    public String getAccessTokenV3() throws RemoteServiceException {
        String redisKey = Constant.RedisPrefix.TOKEN_GREE_V3;
        String token = (String)redisUtil.get(redisKey);
//        if(token != null){
//            return token;
//        }
        MultiValueMap<String, String> forms= new LinkedMultiValueMap<String, String>();

        forms.put("client_id", Collections.singletonList(clientId));
        forms.put("client_secret", Collections.singletonList(v3ClientSecert));
        
        forms.put("grant_type", Collections.singletonList("client_credentials"));
        String s = HttpUtils.requestXwww(v3TokenUrl, forms);
        //String s = HttpUtils.requestPostForm(tokenUrl, map, null);
        // log.info("【获取总部token】response:{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        String accessToken = jsonObject.getString("access_token");
        if(StringUtils.isNotEmpty(accessToken)) {
            redisUtil.set(Constant.RedisPrefix.TOKEN_GREE_V3, accessToken, 2 * 60 * 60);
        }
        return accessToken;
    }

    /**
     *   获取机型名称
     * @param objCode 内积条码 或者 外机条码
     * @param mainNumber 大类id
     * @return
     * @throws RemoteServiceException
     */
    public CheckBarcodeBean getProductName(String objCode,Integer mainNumber){
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("clientid", clientId);
            map.put("barcode", objCode);
            map.put("spid", mainNumber);
            JSONObject jsonObject = this.post(checkBarcodeUrl, map);
            CheckBarcodeBean data = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("data")), CheckBarcodeBean.class);
            return data;
        }catch(Exception e){
            log.error("获取总部机型失败",e);
            return null;
        }
    }


    /**
     *   获取销司结算标准
     * @param jxbh 机型编号，条码前五位
     * @param wxxmh 维修项目号
     * @param gmrg 购买日期(yyyy-MM-dd)
     * @param wxlx 维修类型
     * @param spid 大类
     */
    public String getRepairSettle(String jxbh,String wxxmh,String gmrg,String wxlx,String spid){
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("jxbh", jxbh);
            map.put("wxxmh", wxxmh);
            map.put("gmrg", gmrg);
            map.put("wxlx", wxlx);
            map.put("spid", spid);
            map.put("clientid", clientId);

            JSONObject jsonObject = this.post(getRepairSettleUrl, map);
            return JSONObject.toJSONString(jsonObject.get("data"));
        }catch(Exception e){
            log.error("获取销司结算标准失败",e);
            return "";
        }

    }


    /**
     *   批量转结算
     * @param ids 多个逗号隔开
     */
    public String doRepairSettle(String ids){
        try {

            Map<String,Object> map = new HashMap<>();
            map.put("wxjsguids",ids);
            map.put("clientid",clientId);

            JSONObject jsonObject = this.post(doRepairSettleUrl, map);
            return JSONObject.toJSONString(jsonObject.get("data"));
        }catch(Exception e){
            log.error("【对接总部】批量转结算失败",e.getMessage());
        }
        return null;
    }

    /**
     * 请求总部接口
     * @return
     */
    public String post(String apiPath,Map<String,Object> bizContent,Integer belongType) throws Exception {
        CommonParam commonParam = new CommonParam();
        commonParam.setAppId(this.getAppId(belongType));
        commonParam.setAppKey(this.getAppKey(belongType));
        commonParam.setAppPath(apiPath);
        commonParam.setJson(JSONObject.toJSONString(bizContent));
        OutAppDefaultReq outAppDefaultReq = commonLogic.supplyParam(commonParam);
        Map<String,String> header = new HashMap<>();
        header.put("authorization","Bearer "+this.getAccessToken());
        //log.info("accessToken:{}", "Bearer "+this.getAccessToken());
        
        // log.info("【请求总部接口】request:{}",JSONObject.toJSONString(outAppDefaultReq));
        String s = HttpUtils.requestPostBody(apiUrl, JSONObject.toJSONString(outAppDefaultReq), header);
        // log.info("【请求总部接口】response:{}",s);
        GreeResponseHelper greeResponseHelper = JSONObject.parseObject(s, GreeResponseHelper.class);
        if(greeResponseHelper.getStatus() != 200){
            throw new RemoteServiceException("对接失败总部接口失败:"+greeResponseHelper.getMsg());
        }
        return (String)greeResponseHelper.getData();
    }
    
    public JSONObject post(String url,List param){
    	Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessToken());
        log.info("【总部接口对接】request:{}",  JSON.toJSONString(param));
        String s = HttpUtils.requestPostBody(url, JSON.toJSONString(param), header);
        log.info("【总部接口对接】response:{}",s);
        
        JSONObject jsonObject = JSONObject.parseObject(s);
        Integer statusCode = jsonObject.getInteger("status");
        if (statusCode != 200) {
            log.error("接口地址：{}，对接总部接口失败",url);
            return null;
        }
        return jsonObject;
    }

    /**
     * post请求，用3.0的token
     * @param url
     * @param param
     * @return
     */
    public JSONObject postV3(String url,List param){
    	Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessTokenV3());
        log.info("【总部接口对接】request:{}",  JSON.toJSONString(param));
        String s = HttpUtils.requestPostBody(url, JSON.toJSONString(param), header);
        log.info("【总部接口对接】response:{}",s);
        
        JSONObject jsonObject = JSONObject.parseObject(s);
        Integer statusCode = jsonObject.getInteger("status");
        if (statusCode != 200) {
            log.error("接口地址：{}，对接总部接口失败",url);
            return null;
        }
        return jsonObject;
    }
    
    private JSONObject post(String url,Map<String,Object> map){
        Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessToken());
        log.info("【总部接口对接】request:{}",JSONObject.toJSONString(map));
        String s = HttpUtils.requestPostBody(url, JSONObject.toJSONString(map), header);
        log.info("【总部接口对接】response:{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        Integer statusCode = jsonObject.getInteger("statusCode");
        if (statusCode != 200) {
            log.error("接口地址：{}，对接总部接口失败",url);
            return null;
        }
        return jsonObject;
    }


    public JSONObject postPubV3(String url,Map<String,Object> map) throws IOException {
        Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessTokenV3());
        log.info("【总部接口对接】request:{}",JSONObject.toJSONString(map));
        JSONObject jsonObject = new JSONObject();
        String s = HttpUtils.requestPostBodyIO(url, JSONObject.toJSONString(map), header);
        log.info("【总部接口对接】response:{}",s);
        jsonObject = JSONObject.parseObject(s);

        Integer statusCode = (jsonObject.containsKey("status") && null != jsonObject.get("status") ) ?
                jsonObject.getInteger("status") : jsonObject.getInteger("statusCode");
        jsonObject.put("status", statusCode);
        if (statusCode != 200) {
            log.error("接口地址：{}，对接总部接口失败",url);
        }
        return jsonObject;
    }


    public Object get(String url,Map<String,String> map) throws JsonMappingException, JsonProcessingException {
    	final String apiPath = v3ApiUrl;
    	Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessTokenV3());
        log.info("【总部接口对接】request:{}",JSONObject.toJSONString(map));
//        String s = HttpUtils.requestPostBody(url, JSONObject.toJSONString(map), header);
        String s = HttpUtils.requestGet(apiPath+url, map, header);
        log.info("【总部接口对接】response:{}",s);
        ObjectMapper mapper = new ObjectMapper();
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        ResponseExHelper responseHelper = mapper.readValue(s, ResponseExHelper.class);
        if(responseHelper.getStatusCode() != 200){
            throw new RemoteServiceException("对接失败总部接口失败:"+responseHelper.getMessage());
        }
        return responseHelper.getData();
    }
    
    public JSONObject getPub(String url,Map<String,String> map) {
    	Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessToken());
        log.info("【总部接口对接】request:{}",JSONObject.toJSONString(map));
        String s = HttpUtils.requestGet(url, map, header);
        log.info("【总部接口对接】response:{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        Integer statusCode = jsonObject.getInteger("status");
        if (statusCode != 200) {
            log.error("接口地址：{}，对接总部接口失败",url);
            return null;
        }
        return jsonObject;
    }
    
    
    public JSONObject getPubV3(String url,Map<String,String> map) {
    	Map<String, String> header = new HashMap<>();
        header.put("authorization", "Bearer " + this.getAccessTokenV3());
        log.info("【总部接口对接】request:{}",JSONObject.toJSONString(map));
        String s = HttpUtils.requestGet(url, map, header);
        log.info("【总部接口对接】response:{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        Integer statusCode = jsonObject.getInteger("status");
        if (statusCode != 200) {
            log.error("接口地址：{}，对接总部接口失败",url);
            return null;
        }
        return jsonObject;
    }

    /**
     * 同步总部机型名称和单价
     * @param outCode
     * @param mainNumber
     */
    /*public void syncProduct(String insideCode,String outCode,String mainNumber,Rule rule){
        try {
            CheckBarcodeBean checkBarcodeBean = null;
            if (StringUtils.isNotEmpty(insideCode)) {
                String insideShortCode = insideCode.substring(0, 5);
                Integer count = ruleService.lambdaQuery().eq(Rule::getInsideShortCode, insideShortCode).count();
                if(count > 0){
                    return;
                }
                checkBarcodeBean = this.getProductName(insideCode, Integer.parseInt(mainNumber));

                this.saveProduct(mainNumber,insideShortCode,checkBarcodeBean);
            }
            CheckBarcodeBean checkBarcodeBean2 = null;
            if (StringUtils.isNotEmpty(outCode)) {
                checkBarcodeBean2 = this.getProductName(outCode, Integer.parseInt(mainNumber));
            }
            log.info("【同步总部机型】,code:{},mainNumber:{},返回结果:{}", insideCode, mainNumber, JSONObject.toJSONString(checkBarcodeBean));
            if ((checkBarcodeBean != null  && mainNumber.equals(Constant.MAIN_NUMBER_101))
                    || !mainNumber.equals(Constant.MAIN_NUMBER_101)) {

                //生成新的结算规则
                if(rule == null) {
                   rule = new Rule();
                }
                if (checkBarcodeBean != null) {
                    rule.setPrice(checkBarcodeBean.getJsdj());
                    rule.setEnginPrice(checkBarcodeBean.getJsdj());
                    rule.setInsideShortCode(checkBarcodeBean.getJxbh());
                    rule.setInsideName(checkBarcodeBean.getJxmc());
                }
                if (checkBarcodeBean2 != null) {
                    if (rule.getPrice() == null || rule.getPrice().doubleValue() == 0) {
                        rule.setPrice(checkBarcodeBean2.getJsdj());
                        rule.setEnginPrice(checkBarcodeBean2.getJsdj());
                    }
                    rule.setOutShortCode(checkBarcodeBean2.getJxbh());
                    rule.setOutName(checkBarcodeBean2.getJxmc());
                }
                rule.setMainId(Integer.parseInt(mainNumber));
                rule.setMainNumber(mainNumber);
                rule.setInsideCode(insideCode);
                rule.setOutCode(outCode);
                rule.setCreateTime(new Date());
                if(rule.getStlRuleId() != null){
                    rule.updateById();
                }else {
                    rule.insert();
                }
            }
        }catch(Exception e){
            log.error("同步总部机型失败",e.getMessage());
        }
    }
*/
/*
    public void saveProduct(String mainNumber,String insideShortCode,CheckBarcodeBean checkBarcodeBean){
        if(StringUtils.isEmpty(mainNumber) || !mainNumber.equals(Constant.MAIN_NUMBER_101)){
            return;
        }
        Integer count = productService.lambdaQuery().eq(Product::getProductCode, insideShortCode).count();
        if(count > 0){
            return;
        }

        Product product = new Product();
        product.setMainNumber(mainNumber);
        //product.setMainName(checkBarcodeBean.get);
        product.setMaterialCode(checkBarcodeBean.getZjdm());
        product.setMaterialName(checkBarcodeBean.getZjmc());
        product.setNwbs("内机");
        product.setPrice(checkBarcodeBean.getJsdj());
        product.setProductCode(insideShortCode);
        product.setCreateTime(new Date());
        product.insert();

    }*/

    /*public void initProduct(){
        log.info("【初始化套机数据】开始："+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        List<Rule> list = ruleService.lambdaQuery().ne(Rule::getInsideShortCode, "").eq(Rule::getMainNumber,Constant.MAIN_NUMBER_101).list();
        for(Rule rule : list){
            CheckBarcodeBean checkBarcodeBean = this.getProductName(rule.getInsideCode(), Integer.parseInt(rule.getMainNumber()));
            if(checkBarcodeBean == null){
                continue;
            }
            this.saveProduct(Constant.MAIN_NUMBER_101,rule.getInsideShortCode(),checkBarcodeBean);
        }
        log.info("【初始化套机数据】结束："+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }*/


    /**
     * 初始化机型名称
     */
    /*public void init(){
        List<ProductNew> list = productNewService.list();
        for(ProductNew productNew : list){
            String mainNumber = productNew.getMainNumber();
            String insideCode = productNew.getInsideCode();

            CheckBarcodeBean checkBarcodeBean = this.getProductName(insideCode, Integer.parseInt(mainNumber));
            if(checkBarcodeBean == null){
                productNew.setRemark("调取总部接口获取机型失败");
                continue;
            }
            BeanUtils.copyProperties(checkBarcodeBean,productNew);
            productNew.setProductName(checkBarcodeBean.getJxmc());
            productNew.setPrice(checkBarcodeBean.getJsdj());
        }
        productNewService.updateBatchById(list);
    }*/

    /**
     * 请求总部接口
     * @return
     */
    public GreeResponseHelper greePost(String apiPath, Map<String,Object> bizContent, Integer belongType) throws Exception {
        CommonParam commonParam = new CommonParam();
        commonParam.setAppId(this.getAppId(belongType));
        commonParam.setAppKey(this.getAppKey(belongType));
        commonParam.setAppPath(apiPath);
        commonParam.setJson(JSONObject.toJSONString(bizContent));
        OutAppDefaultReq outAppDefaultReq = commonLogic.supplyParam(commonParam);
        Map<String,String> header = new HashMap<>();
        header.put("authorization","Bearer "+this.getAccessToken());

        log.info("【请求总部接口】request:{}",JSONObject.toJSONString(outAppDefaultReq));
//        String s = HttpUtils.post(apiUrl, JSONObject.toJSONString(outAppDefaultReq), header);
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        for(String str : header.keySet()){
            headers.set(str,header.get(str));
        }

        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(outAppDefaultReq), headers);
        //获取返回数据
        try {
            String body = restTemplate.postForObject(apiUrl, httpEntity, String.class);
            log.info("【请求总部接口】response:{}",body);
            return JSONObject.parseObject(body, GreeResponseHelper.class);
        }catch(HttpStatusCodeException ex) {
        	log.error("rawStatusCode = {}",ex.getRawStatusCode());
        	GreeResponseHelper greeResponseHelper = new GreeResponseHelper();
        	greeResponseHelper.setStatus(ex.getRawStatusCode());
//        	greeResponseHelper.setMsg(GreeResponseCodeEnum.valueOf(ex.getRawStatusCode()));
        	greeResponseHelper.setMsg(ex.getMessage().substring(0,100));
        	ex.printStackTrace();
        	return greeResponseHelper;
        }catch(Exception e){
        	GreeResponseHelper greeResponseHelper = new GreeResponseHelper();
        	greeResponseHelper.setStatus(ResponseHelper.ResponseCode_COMMON);
        	greeResponseHelper.setMsg("非法请求");
        	e.printStackTrace();
        	return greeResponseHelper;
        }
    }
}
