package com.huyi.service.bill.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huyi.service.base.entity.ZcInvoiceInf;
import com.huyi.service.bill.mapper.OwnBillMapper;
import com.huyi.service.bill.service.IOwnBillService;
import com.keao.tianhu.starter.mybatis.plus.entity.QueryRequest;
import com.tianhu.common.core.ocr.OcrUtil;
import com.tianhu.common.core.utils.CommonUtil;
import com.tianhu.common.redis.common.RedisUtils;
import com.tianhu.common.redis.service.RedisService;
import lombok.SneakyThrows;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

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

@Service
public class OwnBillServiceImpl implements IOwnBillService {

    /**
     * OCR appKey
     */
    private static String APP_KEY = "1nmSLQ4nRzQZzEznE5lbk2ja";

    /**
     * OCR secretKey
     */
    private static String SECRET_KEY = "d2OwQSGI1NqFXiuWuulTuXFN1fyKkkDH";

    /**
     * OCR 返回结果key
     */
    private static String WORDS_RESULT = "words_result";

    /**
     * OCR 验真状态key
     */
    private static String VERIFY_RESULT = "VerifyResult";

    /**
     * OCR 验真成功状态
     */
    private static String VERIFY_SUCCESS = "0001";

    /**
     * OCR文字识别token缓存时间
     */
    private static Long REDIS_TIMES = 2505600L;

    /**
     * redis缓存token的key
     */
    private static String OCR_TOKEN_KEY = "ocr_access_token";

    /**
     * 验证状态 0未验证1成功2失败
     */
    private static String CHECK_SUCCESS = "1";

    /**
     * 验证状态 0未验证1成功2失败
     */
    private static String CHECK_ERROR = "2";


    @Autowired
    private RedisService redisService;

    @Autowired
    private OwnBillMapper ownBillMapper;

    /**
     * 往来账款查询
     *
     * @return
     */
    @Override
    public IPage<Map> selectBillInfList(Map map, QueryRequest request) {
        Page page = new Page<>(request.getPageNum(), request.getPageSize());
        return ownBillMapper.selectBillInfList(page, map);
    }

    /**
     * 获取发票信息
     *
     * @return
     */
    @SneakyThrows
    @Override
    public ZcInvoiceInf getInvoice(MultipartFile file) {
        //获取发票信息
        JSONObject result = OcrUtil.vatInvoice(getToken(), file);
        System.out.print("发票文字提取结果==========>" + result);
        ZcInvoiceInf zcInvoiceInf = new ZcInvoiceInf();
        //校验返回结果是否成功
        if (result != null && result.get(WORDS_RESULT) != null) {
            JSONObject wordsResult = result.getJSONObject(WORDS_RESULT);
            //时间格式化
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            //开票日期
            String invoiceDate = wordsResult.getString("InvoiceDate");
            zcInvoiceInf.setZiiDate(sdf.parse(invoiceDate));
            //发票类型
            String invoiceType = wordsResult.getString("InvoiceType");
            //发票类型编码
            String type = RedisUtils.getDictValue("zc_invoice_type", invoiceType);
            zcInvoiceInf.setZiiType(type);
            //校验码
            String checkCode = wordsResult.getString("CheckCode");
            zcInvoiceInf.setZiiCheckCode(checkCode);
            //发票代码
            String invoiceCode = wordsResult.getString("InvoiceCode");
            zcInvoiceInf.setZiiNo(invoiceCode);
            //发票号码
            String invoiceNum = wordsResult.getString("InvoiceNum");
            zcInvoiceInf.setZiiNumber(invoiceNum);
            //购方名称
            String purchaserName = wordsResult.getString("PurchaserName");
            zcInvoiceInf.setZiiPurchaserName(purchaserName);
            //购方纳税人识别号
            String purchaserRegisterNum = wordsResult.getString("PurchaserRegisterNum");
            zcInvoiceInf.setZiiPurchaserNo(purchaserRegisterNum);
            //销方名称
            String sellerName = wordsResult.getString("SellerName");
            zcInvoiceInf.setZiiSellerName(sellerName);
            //销方纳税人识别号
            String sellerRegisterNum = wordsResult.getString("SellerRegisterNum");
            zcInvoiceInf.setZiiSellerNo(sellerRegisterNum);
            //价税合计
            String amountInFiguers = wordsResult.getString("AmountInFiguers");
            zcInvoiceInf.setZiiAmount(amountInFiguers);
            //合计不含税金额
            String totalAmount = wordsResult.getString("TotalAmount");
            zcInvoiceInf.setZiiExcludedAmount(totalAmount);
            zcInvoiceInf.setZiiTotalAmount(totalAmount);
        }
        //返回获取文字后的发票信息
        return zcInvoiceInf;
    }

    /**
     * 发票验真
     *
     * @return
     */
    @SneakyThrows
    @Override
    public ZcInvoiceInf invoiceVerification(ZcInvoiceInf zcInvoiceInf) {
        //时间格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        //发票代码
        String no = zcInvoiceInf.getZiiNo();
        //发票号码
        String number = zcInvoiceInf.getZiiNumber();
        //开票日期
        String date = sdf.format(zcInvoiceInf.getZiiDate());
        //校验码
        String checkCode = zcInvoiceInf.getZiiCheckCode();
        //发票类型
        String type = zcInvoiceInf.getZiiType();
        //不含税金额
        String amount = zcInvoiceInf.getZiiExcludedAmount();
        System.out.println("发票验真参数==========>：｛token:" + getToken() +
                                                    ",no:" + no +
                                                    ",number" + number +
                                                    ",date:" + date +
                                                    ",checkCode:" + checkCode +
                                                    ",type:" + type +
                                                    ",amount:" + amount +"}");
        //获取发票信息
        JSONObject result = OcrUtil.invoiceVerification(getToken(), no, number, date, checkCode, type, amount);
        System.out.println("发票验真结果==========>" + result);
        //返回结果校验是否成功
        if (result != null
                && result.get(WORDS_RESULT) != null
                && VERIFY_SUCCESS.equals(result.getString(VERIFY_RESULT))
        ) {
            //校验成功
            zcInvoiceInf.setZiiCheckStt(CHECK_SUCCESS);
        } else {
            //校验失败
            zcInvoiceInf.setZiiCheckStt(CHECK_ERROR);
        }
        return zcInvoiceInf;
    }

    /**
     * 获取授权token
     *
     * @return
     */
    private String getToken() {
        //授权token
        String accessToken = redisService.getCacheObject(OCR_TOKEN_KEY);
        if (!CommonUtil.isEmpty(accessToken)) {
            return accessToken;
        }
        //授权token
        accessToken = OcrUtil.getAuth(APP_KEY, SECRET_KEY);
        //缓存29天
        redisService.setCacheObject(OCR_TOKEN_KEY, accessToken, REDIS_TIMES, TimeUnit.SECONDS);
        return accessToken;
    }
}
