package com.xxfc.platform.universal.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.auth.client.config.UserAuthConfig;
import com.github.wxiaoqi.security.auth.client.jwt.UserAuthUtil;
import com.github.wxiaoqi.security.auth.common.util.jwt.IJWTInfo;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.xxfc.platform.universal.constant.InvoiceStatusEum;
import com.xxfc.platform.universal.entity.Invoice;
import com.xxfc.platform.universal.entity.OrderData;
import com.xxfc.platform.universal.entity.vo.InvoiceVo;
import com.xxfc.platform.universal.mapper.InvoiceMapper;
import com.xxfc.platform.universal.service.invoice.InvoiceDao;
import com.xxfc.platform.universal.utils.NumberToCN;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 发票服务
 *
 * @author Administrator
 * @Date: 2019/12/31 10:05
 * @Description:
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class InvoiceBiz extends BaseBiz<InvoiceMapper, Invoice> {

    private final InvoiceDao invoiceDao;
    private final UserAuthConfig userAuthConfig;
    private final HttpServletRequest request;
    private final UserAuthUtil userAuthUtil;
    private final ThreadPoolTaskExecutor taskExecutor;

    private static final String salerName = "欣新房车网络科技（广东）股份有限公司";
    //正式
//    private static final String salerTaxNum="91441900MA53C6713X";
    //测试
    private static final String salerTaxNum = "339901999999142";

    private static final String salerTel = "13926892766";
    private static final String salerAddress = "广东省东莞市松山湖园区科汇路1号1栋801室13926892766";
    private static final String salerAccount = "中国建设银行股份有限公司东莞虎门连升支行44050110140900000777";
    //收款人
    private static final String payee = "郑超";
    //复核人
    private static final String checker = "邹冬梅";
    //开票人
    private static final String clerk = "郑超";
    // 推送方式:-1,不推送;0,邮箱;1,手机（默认）;2,邮箱、手机
    private static final Integer pushMode = 2;
    private static final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(2);

    public String getDutyParagraphByCode(String code) {
        return invoiceDao.getDutyParagraphByCode(code);
    }

    public List<Map<String, String>> corporateName(String name) {
        return invoiceDao.corporateName(name);
    }

    public String Invoicing(InvoiceVo invoiceVo) throws Exception {
        IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request));
        Invoice invoice = new Invoice();
        BeanUtils.copyProperties(invoiceVo, invoice);
        invoice.setSalerName(salerName);
        invoice.setSalerTaxCode(salerTaxNum);
        invoice.setSalerAddressPhone(salerAddress);
        invoice.setSalerAccountBank(salerAccount);
        invoice.setPayee(payee);
        invoice.setReviewer(checker);
        invoice.setIssuer(clerk);
        invoice.setPushMode(pushMode);
        invoice.setInvoiceDate(new Date());
        List<OrderData> orders = invoiceVo.getOrders();
        //调用第三方开票
        String invoiceSerialNum = invoiceDao.Invoicing(invoice, orders);
        invoice.setInvoiceSerialNum(invoiceSerialNum);
        invoice.setUserId(Integer.valueOf(infoFromToken.getId()));
        //保存到数据库
        mapper.insert(invoice);

        //异步查询开票结果
        taskExecutor.execute(()->{
            queryInvoiceResult(invoiceSerialNum,invoice.getId(),0);
        });
        return invoiceSerialNum;
    }

    public String invoiceResult(String invoiceSerialNum) {
        return invoiceDao.invoiceResult(invoiceSerialNum);
    }

    public void queryInvoiceResult(String invoiceSerialNum, Integer id,Integer type) {
        String result = invoiceResult(invoiceSerialNum);
        JSONObject jsonObject = JSON.parseObject(result);
        Map<String,Object> data = (Map<String, Object>) jsonObject.get("data");
        Integer status = (Integer) data.get("status");
        if (InvoiceStatusEum.ONGOING.getCode().equals(status)&&type==0){
            executorService.schedule(()->{
                 queryInvoiceResult(invoiceSerialNum,id,1);
            },2, TimeUnit.HOURS);
        }else {
            Invoice invoice = new Invoice();
            invoice.setId(id);
            invoice.setInvoiceStatus(status);
            invoice.setInvoiceCode(String.valueOf(data.get("invoiceCode")));
            invoice.setInvoiceNo(String.valueOf(data.get("invoiceNum")));
            invoice.setInvoiceAmount(BigDecimal.valueOf((Double) data.get("invoiceNum")));
            invoice.setTaxAmount(BigDecimal.valueOf((Double) data.get("taxIncludedAmount")).subtract(BigDecimal.valueOf((Double) data.get("invoiceNum"))));
            invoice.setInvoiceSummaryAmount(BigDecimal.valueOf((Double) data.get("taxIncludedAmount")));
            invoice.setInvoiceSummaryAmountText(NumberToCN.number2CNMontrayUnit(BigDecimal.valueOf((Double) data.get("taxIncludedAmount"))));
            mapper.updateByPrimaryKeySelective(invoice);
        }
    }
}
