package com.jpsoft.shinestar.modules.outapi.service.impl;

import cn.hutool.http.HttpRequest;
import com.jpsoft.shinestar.config.GreenCodeConfig;
import com.jpsoft.shinestar.modules.base.entity.PersonInfo;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.common.utils.IdCardUtils;
import com.jpsoft.shinestar.modules.outapi.dto.GreenCodeDTO;
import com.jpsoft.shinestar.modules.outapi.service.OutApiService;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;


/**
 * @author 墨鱼_mo
 * @date 2020-6-29 10:39
 */
@Slf4j
@Service
public class OutApiServiceImpl implements OutApiService {

    @Autowired
    private GreenCodeConfig greenCodeConfig;

    @Autowired
    private ValueOperations<String, Object> valueOperations;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private PersonInfoService personInfoService;

    @Override
    public GreenCodeDTO getGreenCode(String name, String idCard) throws Exception {

        GreenCodeDTO greenCodeDTO = null;
        idCard = idCard.toUpperCase();

        String codeKey = "greenCode_" + name + "_" + idCard;

        if(redisTemplate.hasKey(codeKey)) {
            greenCodeDTO = (GreenCodeDTO) valueOperations.get(codeKey);
        }
        else{
            greenCodeDTO = new GreenCodeDTO();

            try {
                HashMap map = new HashMap();
                map.put("XM", name);
                map.put("GMSFHM", idCard.trim());

                String body = HttpRequest.get(greenCodeConfig.getUrl())
                        .header("AppKey", greenCodeConfig.getAppKey())
                        .form(map)
                        .timeout(3000) //3秒内无返回则报错
                        .execute().body();

                log.warn("查询{}-{}健康码查询返回：{}",name,idCard, body);

                JSONObject jsonbody = JSONObject.fromObject(body);
                String data = (String) jsonbody.get("data");

                JSONObject jsonbody2 = JSONObject.fromObject(data);

                if(jsonbody2.containsKey("data") && jsonbody2.get("data") instanceof JSONArray) {
                    JSONArray jsonbody3 = jsonbody2.getJSONArray("data");

                    Iterator it = jsonbody3.iterator();

                    while (it.hasNext()) {
                        JSONObject json = (JSONObject) it.next();
                        if (json.containsKey("date")) {
                            greenCodeDTO.setDate(json.getString("date"));
                        }
                        if (json.containsKey("reason")) {
                            greenCodeDTO.setReason(json.getString("reason"));
                        }
                        if (json.containsKey("sjly")) {
                            greenCodeDTO.setSjly(json.getString("sjly"));
                        }
                        if (json.containsKey("healthy_code")) {
                            if ("99".equals(json.getString("healthy_code"))){
                                greenCodeDTO.setHealthyCode("11");
                            }else {
                            greenCodeDTO.setHealthyCode(json.getString("healthy_code"));
                            }
                        }
                    }
                }

                // 所有身份证已加密，不再需要重复更新
//                PersonInfo personInfo = personInfoService.findByNameAndIdCard(name,idCard);
//
//                if (personInfo==null){
//                    //身份证加密保存
//                    personInfo = personInfoService.findByNameAndIdCard(name,IdCardUtils.encrypt(idCard));
//                }
//
//                if (personInfo!=null){
//                    personInfo.setIdCard(IdCardUtils.encrypt(idCard)); //身份证统一加密保存
//                    personInfo.setHealthyCode(greenCodeDTO.getHealthyCode());
//                    personInfo.setUpdateHealthyTime(new Date());
//
//                    personInfoService.updateHealthyCode(personInfo);
//                }
            } catch (Exception ex) {
                log.error("未查询到绿码信息:{}",ex.getMessage());
            }

            PersonInfo personInfo = new PersonInfo();
            personInfo.setName(name);
//          personInfo.setIdCard(IdCardUtils.encrypt(idCard));
            personInfo.setIdCard(idCard);
            personInfo.setHealthyCode(greenCodeDTO.getHealthyCode());
            personInfo.setHealthyReason(greenCodeDTO.getReason());
            personInfo.setUpdateHealthyTime(new Date());

            personInfoService.updateHealthyCode(personInfo);

            if (greenCodeDTO!=null && StringUtils.isNotBlank(greenCodeDTO.getHealthyCode())) {
                //如果正常返回则缓存12小时
                valueOperations.set(codeKey, greenCodeDTO, 12, TimeUnit.HOURS);
            }
            else{
                personInfo = personInfoService.findByNameAndIdCard(name,idCard);

                if(personInfo!=null && personInfo.getUpdateHealthyTime()!=null) {
                    greenCodeDTO = new GreenCodeDTO();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                    greenCodeDTO.setDate(sdf.format(personInfo.getUpdateHealthyTime()));

                    greenCodeDTO.setReason(personInfo.getHealthyReason());
                    greenCodeDTO.setHealthyCode(personInfo.getHealthyCode());
                    greenCodeDTO.setSjly("1");
                    greenCodeDTO.setIdCard(idCard);
                    greenCodeDTO.setName(name);
                    greenCodeDTO.setHasIdCard(true);

                    //接口未正常返回，缓存5分钟
                    valueOperations.set(codeKey, greenCodeDTO, 5, TimeUnit.MINUTES);
                }
            }
        }

        return greenCodeDTO;
    }
}


