package com.dxhy.manage.service.impl;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.manage.config.ApplicationConfig;
import com.dxhy.manage.config.ManageConstants;
import com.dxhy.manage.dao.HttpLogDao;
import com.dxhy.manage.entity.HttpLogEntity;
import com.dxhy.manage.model.*;
import com.dxhy.manage.service.Security;
import com.dxhy.manage.service.TaxManageService;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaohongyang
 */
@Service
@Slf4j
public class TaxManageServiceImpl implements TaxManageService {

    @Resource
    private ApplicationConfig applicationConfig;
    @Resource
    private HttpLogDao httpLogDao;

    @Override
    public ReturnModel getTaxInfo(String taxno) {
        String body = "";
        ReturnModel returnModel = new ReturnModel();
        HttpLogEntity entity = new HttpLogEntity();
        try {
            String params = this.toTaxJson(taxno);
            entity.setCreateDate(new Date());
            entity.setTaxno(taxno);
            entity.setReqtext(params);
            entity.setType("0");
            body = this.getTaxUrl(params, applicationConfig.getInfoUrl);
            entity.setRestext(body);
            DynamicContextHolder.push(DbConstant.BASICS_WRITE);
            httpLogDao.insert(entity);
            if (StringUtils.isNotBlank(body)) {
                ReturnTaxInfoModel returnTaxInfoModel = JSON.parseObject(body, ReturnTaxInfoModel.class);
                if (ManageConstants.TAX_ERROR_CODE.equals(returnTaxInfoModel.getErrorCode())) {
                    returnModel.setCode(ManageConstants.SUCCESS_CODE);
                    returnModel.setMsg("成功");
                    returnModel.setData(this.toInfoModel(returnTaxInfoModel.getData()));
                } else {
                    returnModel.setCode(ManageConstants.ERROR_CODE);
                    returnModel.setMsg("失败");
                }
            } else {
                returnModel.setCode(ManageConstants.ERROR_CODE);
                returnModel.setMsg("失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnModel;
    }

    @Override
    public ReturnModel getKeyTaxManage(FunctionModel functionModel, String area, String taxno) {
        String body = "";
        ReturnModel returnModel = new ReturnModel();
        HttpLogEntity entity = new HttpLogEntity();
        try {
            String params = this.toKeyManageJson(functionModel, area, taxno);
            entity.setCreateDate(new Date());
            entity.setTaxno(taxno);
            entity.setReqtext(params);
            entity.setType("1");
            body = this.getTaxUrl(params, applicationConfig.taxManageUrl);
            entity.setRestext(body);
            DynamicContextHolder.push(DbConstant.BASICS_WRITE);
            httpLogDao.insert(entity);
            if (StringUtils.isNotBlank(body)) {
                ReturnTaxInfoModel returnTaxInfoModel = JSON.parseObject(body, ReturnTaxInfoModel.class);
                if (ManageConstants.TAX_ERROR_CODE.equals(returnTaxInfoModel.getErrorCode())) {
                    returnModel.setCode(ManageConstants.SUCCESS_CODE);
                    returnModel.setMsg("成功");
                    returnModel.setData(this.toInfoModel(returnTaxInfoModel.getData()));
                } else {
                    returnModel.setCode(ManageConstants.ERROR_CODE);
                    returnModel.setMsg("失败");
                }
            } else {
                returnModel.setCode(ManageConstants.ERROR_CODE);
                returnModel.setMsg("失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnModel;
    }

    /**
     * 获取税号采集状态 请求报文转换
     *
     * @param taxno
     * @return
     */
    public String toKeyManageJson(FunctionModel functionModel, String area, String taxno) {
        Map map = new HashMap<>(8);
        List<FunctionModel> functionModels = new ArrayList<>();
        functionModels.add(functionModel);
        try {
            String timestamp = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
            String uuid = UUID.randomUUID().toString();
            String signatureNonce = uuid.replace("-", "");
            String signStr = "accessKeyID=%s&signatureNonce=%s&timeStamp=%s&version=" + applicationConfig.version;
            signStr = String.format(signStr, applicationConfig.username, signatureNonce, timestamp);
            String signature =
                Security.getSignature(signStr.getBytes("UTF-8"), applicationConfig.password.getBytes("UTF-8"));
            map.put("accessKeyID", applicationConfig.username);
            map.put("timeStamp", timestamp);
            map.put("signature", signature);
            map.put("signatureNonce", signatureNonce);
            map.put("version", applicationConfig.version);
            map.put("taxno", taxno);
            map.put("zoneCode", area);
            map.put("functionList", functionModels);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return JSON.toJSONString(map);
    }

    /**
     * 转换返回结果
     *
     * @param dataModel
     * @return
     */
    private List<TaxInfoModel> toInfoModel(DataModel dataModel) {
        List<TaxInfoModel> functionList = dataModel.getFunctionList();
        if (functionList != null && functionList.size() > 0) {
            for (TaxInfoModel taxInfoModel : functionList) {
                taxInfoModel.setTaxno(dataModel.getTaxno());
            }
        }
        return functionList;
    }

    public String toTaxJson(String taxno) {
        Map map = new HashMap<>(6);
        try {
            String timestamp = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
            String uuid = UUID.randomUUID().toString();
            String signatureNonce = uuid.replace("-", "");
            String signStr = "accessKeyID=%s&signatureNonce=%s&timeStamp=%s&version=" + applicationConfig.version;
            signStr = String.format(signStr, applicationConfig.username, signatureNonce, timestamp);
            String signature =
                Security.getSignature(signStr.getBytes("UTF-8"), applicationConfig.password.getBytes("UTF-8"));
            map.put("accessKeyID", applicationConfig.username);
            map.put("timeStamp", timestamp);
            map.put("signature", signature);
            map.put("signatureNonce", signatureNonce);
            map.put("version", applicationConfig.version);
            map.put("taxno", taxno);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSON.toJSONString(map);
    }

    /**
     * 调用接口
     *
     * @return
     */
    public String getTaxUrl(String requestJson, String url) {
        log.info("<线程：{}>,请求接口开始：{}", Thread.currentThread().getId(), requestJson);
        String body = "";
        try {
            body = HttpUtil.post(url, requestJson, 30000);
            log.info("<线程：{}>,返回报文：{}", Thread.currentThread().getId(), body);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return body;
    }

    @Override
    public JSONObject getTitle() {
        JSONObject json = new JSONObject();
        String[] titlelist = {"税号", "请求时间", "请求报文", "返回报文", "请求类型"};
        String[] titleprop = {"taxno", "reqDate", "reqtext", "restext", "reqType"};
        // 需要设置返回列表标题时调用
        json = setTitleList(titlelist, titleprop);
        return json;
    }

    @Override
    public List<TaxManageModel> getHttpLogs(String taxno) {

        return httpLogDao.getLogList(taxno);
    }

    public JSONObject setTitleList(String[] titlelist, String[] titleprop) {
        JSONObject titleList = new JSONObject();
        if (titlelist != null) {
            titleList.put("titlelist", titlelist);
        }

        if (titleprop != null) {
            titleList.put("titleprop", titleprop);
        }

        JSONObject returnJson = new JSONObject();
        returnJson.put("titlelist", titleList);
        return returnJson;
    }
}
