package com.jianshui.invoice.service.impl.adapter.request;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.core.domain.entity.Companyservice;
import com.jianshui.common.enums.ErrorCode;
import com.jianshui.common.exception.jianshui.JianshuiParamErrorException;
import com.jianshui.common.utils.DateUtils;
import com.jianshui.common.utils.IdcardUtils;
import com.jianshui.common.utils.StringUtils;
import com.jianshui.common.utils.TimeUtil;
import com.jianshui.common.utils.encrypt.AisinoInvoiceDecryptUtil;
import com.jianshui.common.utils.http.HttpHelper;
import com.jianshui.invoice.domain.BillDetail;
import com.jianshui.invoice.domain.BillInfo;
import com.jianshui.invoice.domain.Redinfo;
import com.jianshui.invoice.domain.Redinfodetail;
import com.jianshui.invoice.domain.dto.*;
import com.jianshui.invoice.domain.dto.adapter.request.nuonuo2.*;
import com.jianshui.invoice.service.IInvoiceRequestService;
import com.jianshui.system.service.ICompanyserviceService;
import lombok.extern.slf4j.Slf4j;
import nuonuo.open.sdk.NNOpenSDK;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Description 航信入口报文适配器
 * @Author 巩权林
 * @Date 2022/3/19 21:28
 **/
@Slf4j
@Component("nuonuo2.0_invoice_request_adapter")
public class Nuonuo2InvoiceRequestAdapterImpl implements IInvoiceRequestService {

    @Autowired
    private ICompanyserviceService companyserviceService;

    /**
     * 解密函数
     *
     * @param request
     * @param companyservice
     * @return
     */
    @Override
    public JSONObject decrypt(HttpServletRequest request, Companyservice companyservice, String serviceKey) {
        JSONObject result = new JSONObject();
        String rawJson = HttpHelper.getBodyString(request);
        log.info("【诺诺转invoice请求适配器】客户请求报文原始数据：{}，销方id：{}，serviceKey：{}", rawJson, companyservice.getCompanyid(), serviceKey);

        if (StringUtils.isEmpty(rawJson)) {
            throw new JianshuiParamErrorException(ErrorCode.ERROR_PARAMS, companyservice, "invoice");
        }
        // 发票开具
        if (StringUtils.equals(serviceKey, "add")) {
            Nuonuo2BillInfoDTO nuonuo2BillInfoDTO = JSONObject.parseObject(rawJson, Nuonuo2BillInfoDTO.class);
            // 解析报文
            if (nuonuo2BillInfoDTO == null) {
                throw new JianshuiParamErrorException(ErrorCode.ERROR_PARAMS, companyservice, "invoice");
            }
            // 解析报文完成，转换成Billinfo
            BillInfo billInfo = new BillInfo();
            BeanUtils.copyProperties(nuonuo2BillInfoDTO, billInfo);
            // 处理BillInfo字段
            billInfo.setCompanyId(companyservice.getCompanyid());
            /*if (StringUtils.isEmpty(billInfo.getBuyerBank()) && StringUtils.isNotEmpty(billInfo.getBuyerAccount())) {
                String bankNo = IdcardUtils.getBankNo(billInfo.getBuyerAccount());
                if (StringUtils.isNotEmpty(bankNo)) {
                    String raw = billInfo.getBuyerAccount();
                    billInfo.setBuyerAccount(bankNo);
                    billInfo.setBuyerBank(raw.replace(bankNo, ""));
                }
            }*/
            // 银行处理
            if (StringUtils.isEmpty(billInfo.getBuyerBank()) && StringUtils.isNotEmpty(billInfo.getBuyerAccount())) {
                Map<String, String> bank = IdcardUtils.getBankNoAndName(billInfo.getBuyerAccount());
                billInfo.setBuyerAccount(bank.getOrDefault("bankNo", ""));
                billInfo.setBuyerBank(bank.getOrDefault("bankName", ""));
            }
            // 处理销方信息
            if (StringUtils.isEmpty(billInfo.getSellerBank()) && StringUtils.isNotEmpty(billInfo.getSellerAccount())) {
                String bankNo = IdcardUtils.getBankNo(billInfo.getSellerAccount());
                if (StringUtils.isNotEmpty(bankNo)) {
                    String raw = billInfo.getSellerAccount();
                    billInfo.setSellerAccount(bankNo);
                    billInfo.setSellerBank(raw.replace(bankNo, ""));
                }
            }
            // 处理BillDetail字段
            List<Nuonuo2BillDetailDTO> detailDTOS = nuonuo2BillInfoDTO.getBillDetailList();
            if (CollectionUtil.isNotEmpty(detailDTOS)) {
                List<BillDetail> detailList = new ArrayList<>();
                for (int i = 0; i < detailDTOS.size(); i++) {
                    BillDetail billDetail = new BillDetail();
                    Nuonuo2BillDetailDTO nuonuo2BillDetailDTO = detailDTOS.get(i);
                    BeanUtils.copyProperties(nuonuo2BillDetailDTO, billDetail);
                    billDetail.setIndex(Long.parseLong(Integer.toString(i)));
                    detailList.add(billDetail);
                }
                billInfo.setBillDetailList(detailList);
            }
            result = (JSONObject) JSONObject.toJSON(billInfo);
        }

        if (StringUtils.equals(serviceKey, "query")) {
            QueryInvoiceDTO queryInvoiceDTO = JSONObject.parseObject(rawJson, QueryInvoiceDTO.class);
            BillInfo billInfo = new BillInfo();
            BeanUtils.copyProperties(queryInvoiceDTO, billInfo);
            if (StringUtils.isNotEmpty(billInfo.getFpqqlsh())) {
                billInfo.setFpqqlsh("[\"" + billInfo.getFpqqlsh() + "\"]");
            }
            if (StringUtils.isNotEmpty(billInfo.getOutTradeOrderno())) {
                billInfo.setOutTradeOrderno("[\"" + billInfo.getOutTradeOrderno() + "\"]");
            }
            result = (JSONObject) JSONObject.toJSON(billInfo);
        }

        // 发票作废
        if (StringUtils.equals(serviceKey, "deprecate")) {
            JSONObject temp = new JSONObject();
            temp.put("fpqqlsh", JSONObject.parseObject(rawJson).getString("invoiceId"));
            return temp;
        }

        if (StringUtils.equals(serviceKey, "add_redinfo")) {
            Nuonuo2RedInfoDTO nuonuo2RedInfoDTO = null;
            try {
                nuonuo2RedInfoDTO = JSONObject.parseObject(rawJson, Nuonuo2RedInfoDTO.class);
            } catch (Exception e) {
                e.printStackTrace();
                throw new JianshuiParamErrorException(ErrorCode.ERROR_PARAMS, companyservice, "invoice");
            }
            Redinfo redinfo = new Redinfo();
            BeanUtils.copyProperties(nuonuo2RedInfoDTO, redinfo);
            redinfo.setCompanyId(companyservice.getCompanyid());
            redinfo.setRedInfoNo(redinfo.getOutTradeOrderno());
            // TODO 多税率标识
            redinfo.setMultTaxRate("0");
            redinfo.setBillInputTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()));
            redinfo.setApplyTime(DateUtils.parseDate(redinfo.getBillInputTime()));
            if (redinfo.getTaxfreeamt() != null && redinfo.getTax() != null) {
                redinfo.setTaxamt(redinfo.getTaxfreeamt().add(redinfo.getTax()));
            }
            redinfo.setReqnsrsbh(companyservice.getSellertax());
            List<Redinfodetail> redinfodetailList = new ArrayList<>();
            List<Nuonuo2RedDetailDTO> redDetailDTOS = nuonuo2RedInfoDTO.getRedinfodetailList();
            String taxrate = "";
            for (int i = 0; i < redDetailDTOS.size(); i++) {
                Nuonuo2RedDetailDTO temp = redDetailDTOS.get(i);
                Redinfodetail tempReddDetail = new Redinfodetail();
                BeanUtils.copyProperties(temp, tempReddDetail);
                tempReddDetail.setIndex(i);
                tempReddDetail.setTaxamt(tempReddDetail.getTaxfreeamt().add(tempReddDetail.getTax()));
                if (StringUtils.equals(temp.getFavouredPolicyFlag(), "true")) {
                    tempReddDetail.setYhzcbs(1);
                } else {
                    tempReddDetail.setYhzcbs(0);
                }
                if (StringUtils.equals(temp.getFavouredPolicyFlag(), "true")) {
                    tempReddDetail.setYhzcbs(1);
                } else {
                    tempReddDetail.setYhzcbs(0);
                }
                if (StringUtils.equals("0", redinfo.getMultTaxRate()) && StringUtils.isNotEmpty(taxrate) && StringUtils.equals(tempReddDetail.getTaxrate().toString(), taxrate)) {
                    redinfo.setMultTaxRate("1");
                } else if (StringUtils.isEmpty(taxrate)) {
                    taxrate = tempReddDetail.getTaxrate().toString();
                }
                redinfodetailList.add(tempReddDetail);
            }
            redinfo.setRedinfodetailList(redinfodetailList);
            result = (JSONObject) JSONObject.toJSON(redinfo);
        }

        if (StringUtils.equals(serviceKey, "download_redinfo")) {
            Nuonuo2DownloadRedinfoDTO nuonuo2RedInfoDTO = JSONObject.parseObject(rawJson, Nuonuo2DownloadRedinfoDTO.class);
            DownloadRedInfoDTO downloadRedInfoDTO = new DownloadRedInfoDTO();
            BeanUtils.copyProperties(nuonuo2RedInfoDTO, downloadRedInfoDTO);
            result = (JSONObject) JSONObject.toJSON(downloadRedInfoDTO);
        }

        return result;
    }

    @Override
    public JSONObject decryptZq(String identity, String order, Companyservice companyservice, String serviceKey) {
        return null;
    }

    /**
     * 转换报文类型
     *
     * @param method
     * @return
     */
    @Override
    public String covertMethodName(String method) {
        switch (method) {
            // 发票开具
            case "nuonuo.ElectronInvoice.requestBillingNew":
                return "add";
            // 开票结果查询
            case "nuonuo.ElectronInvoice.queryInvoiceResult": // 这里需要单独处理下发票流水号还是请求流水号
                return "query";
            // 红字发票申请
            case "nuonuo.ElectronInvoice.InvoiceRedApply":
                return "add_redinfo";
            // 红字发票结果查询
            case "nuonuo.ElectronInvoice.InvoiceRedQueryNew":
                return "download_redinfo";
            // 发票作废
            case "nuonuo.electronInvoice.invoiceCancellation":
                return "deprecate";
        }
        return null;
    }
}
