package com.xxfc.platform.universal.service.invoice.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.google.common.collect.Lists;
import com.xxfc.platform.universal.entity.Invoice;
import com.xxfc.platform.universal.entity.OrderData;
import com.xxfc.platform.universal.service.invoice.InvoiceDao;
import lombok.extern.slf4j.Slf4j;
import nuonuo.open.sdk.NNOpenSDK;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: Administrator
 * @Date: 2019/12/31 10:26
 * @Description:
 */
@Service
@Primary
@Slf4j
public class InvoiceDaoImpl implements InvoiceDao {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 诺诺-极速开票
     */
    private static final String taxnum = "91441900MA53C6713X";
    private static final String appKey = "80653463";
    private static final String appSecret = "EA55B47A6D0A4560";

    /**
     * 诺诺-诺诺发票
     */
    private static final String taxnum2 = "91441900MA53C6713X";
    //沙箱
    private static final String appKey2 = "SD26345711";
    private static final String appSecret2 = "SD1B543442BF41A1";

//    //正式
//    private static final String appKey2 = "26345711";
//    private static final String appSecret2 = "901B543442BF41A1";



    /**
     * 给定的部分名获取税号
     * @param name
     * @return
     */
    @Override
    public List<Map<String, String>> corporateName(String name) {
        NNOpenSDK sdk = NNOpenSDK.getIntance();
        HashMap<String, String> map = new HashMap();
        map.put("q", name);
        String content = JSON.toJSONString(map);

        //方法名
        String method = "nuonuo.speedBilling.prefixQuery";
        // SDK请求地址
        String url = "https://sdk.nuonuo.com/open/v1/services";
        // 唯一标识，由企业自己生成32位随机码
        String senid = UUID.randomUUID().toString().replace("-", "");
        String result = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, getTokenJS(), taxnum, method, content);
        JSONObject jsonObject = JSON.parseObject(result);
        List<Map<String, String>> mapList = (List<Map<String, String>>) jsonObject.get("result");
        if (CollectionUtil.isNotEmpty(mapList)) {
            return mapList;
        }
        return new ArrayList<>();
    }

    /**
     * 根据开票代码,调用第三方接口获取税号
     * @param code
     * @return
     */
    @Override
    public String getDutyParagraphByCode(String code) {
        NNOpenSDK sdk = NNOpenSDK.getIntance();
        // API方法名
        String method = "nuonuo.speedBilling.queryNameAndTaxByCode";
        // SDK请求地址
        String url = "https://sdk.jss.com.cn/open/v1/services";

        HashMap<String, String> map = new HashMap();
        map.put("code", code);
        String content = JSON.toJSONString(map);
        // 唯一标识，由企业自己生成32位随机码
        String senid = UUID.randomUUID().toString().replace("-", "");
        String result = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, getTokenJS(), taxnum, method, content);
        JSONObject jsonObject = JSON.parseObject(result);
        Map<String, String> resultMap = (Map<String, String>) jsonObject.get("result");
        return resultMap.get("kpCode");
    }



    @Override
    public String Invoicing(Invoice invoice, List<OrderData> orders) {

        NNOpenSDK sdk = NNOpenSDK.getIntance();
        // API方法名
        String method = "nuonuo.electronInvoice.requestBilling";
        // SDK请求地址
        //沙箱
        String url = "https://sandbox.nuonuocs.cn/open/v1/services";
        //正式
//        String url = "https://sdk.nuonuo.com/open/v1/services";

        String senid = UUID.randomUUID().toString().replace("-", "");
        HashMap<String, Object> map = new HashMap<>();
        HashMap<String, Map<String, Object>> orderMap = new HashMap<>();
        orderMap.put("order", map);
        //购方信息
        map.put("buyerName",invoice.getPurchaserName());
        map.put("buyerTaxNum", invoice.getPurchaserTaxCode());
//        map.put("buyerTel", invoice.getPurchaserPhone());
        map.put("buyerAddress", invoice.getPurchaserAddressPhone());
        map.put("buyerAccount", invoice.getPurchaserAccountBank());
        map.put("buyerPhone", invoice.getPurchaserPhone());
        map.put("email", invoice.getPurchaserEmail());
        map.put("remark", invoice.getRemark());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //销方信息
        map.put("orderNo", invoice.getOrderId());
        map.put("invoiceDate",dateFormat.format(invoice.getInvoiceDate()));
        map.put("salerName", invoice.getSalerName());
        map.put("salerTaxNum", invoice.getSalerTaxCode());
        map.put("salerAddress", invoice.getSalerAddressPhone());
        map.put("salerAccount",invoice.getSalerAccountBank());
        map.put("clerk", invoice.getIssuer());
        map.put("payee", invoice.getPayee());
        map.put("checker", invoice.getReviewer());

        //其他设置
        map.put("pushMode", String.valueOf(invoice.getPushMode()));
        map.put("invoiceType",String.valueOf(invoice.getInvoiceType()));


        //订单信息
        ArrayList<Map<String, String>> arrayList = Lists.newArrayList();
        map.put("invoiceDetail", arrayList);
        for (OrderData order : orders) {
            HashMap<String, String> mx = new HashMap<>();
            mx.put("goodsName", invoice.getContent());
            mx.put("num",String.valueOf(order.getNum()) );
            //单价含税标志，0:不含税,1:含税
            mx.put("withTaxFlag", String.valueOf(order.getWithTaxFlag()));
            mx.put("price", String.valueOf(order.getPrice()));
            mx.put("taxRate", String.valueOf(order.getTaxRate()));
            mx.put("unit", order.getUnit());
            mx.put("specType",order.getSpecType());
            arrayList.add(mx);
        }
        String token = getTokenFP();
        String jsonString = JSON.toJSONString(orderMap);
        //调用第三方接口
        String result = sdk.sendPostSyncRequest(url, senid, appKey2, appSecret2,token , taxnum2, method, jsonString);
        System.out.println(result);
        //把字符串json数据转换为map
        JSONObject jsonObject = JSON.parseObject(result);
        Map<String,String> data = (Map<String, String>) jsonObject.get("result");
       return data.get("invoiceSerialNum");
    }

    @Override
    public String invoiceResult(String invoiceSerialNum) {
        NNOpenSDK sdk = NNOpenSDK.getIntance();
        // API方法名
        String method = "nuonuo.electronInvoice.CheckEInvoice";
        HashMap<String, List<String>> map = new HashMap<>();
        ArrayList<String> arrayList = Lists.newArrayList();
        arrayList.add(invoiceSerialNum);
        map.put("invoiceSerialNum",arrayList);
        String content = JSON.toJSONString(map);
        // SDK请求地址
        //沙箱
        String url = "https://sandbox.nuonuocs.cn/open/v1/services";
        //正式
//        String url = "https://sdk.nuonuo.com/open/v1/services";

        // 唯一标识，由企业自己生成32位随机码
        String senid = UUID.randomUUID().toString().replace("-", "");
        String result = sdk.sendPostSyncRequest(url, senid, appKey2, appSecret2, getTokenFP(), taxnum2, method, content);
        System.out.println(result);
        return result;
    }


    /**
     * 获取极速开票token
     */

    private String getTokenJS() {
        return getToken(appKey, appSecret);
    }


    /**
     * 获取诺诺发票token
     */
    public String getTokenFP() {
        return getToken(appKey2, appSecret2);
    }



    private String getToken(String appKey, String appSecret) {
        String token = (String) redisTemplate.opsForValue().get(appKey);
        if (StringUtils.isBlank(token)) {
            String json = NNOpenSDK.getIntance().getMerchantToken(appKey, appSecret);
            log.info("token={}", json);
            JSONObject jsonObject = JSONObject.parseObject(json);
            token = (String) jsonObject.get("access_token");
            if (StringUtils.isBlank(token)) {
                throw new BaseException("获取极速开票token失败");
            }
            redisTemplate.opsForValue().set(appKey, token, 23, TimeUnit.HOURS);
        }
        return token;

    }


}
