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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.core.domain.entity.Companyservice;
import com.jianshui.common.exception.jianshui.JianshuiParamErrorException;
import com.jianshui.common.utils.DateUtils;
import com.jianshui.common.utils.DictUtils;
import com.jianshui.common.utils.StringUtils;
import com.jianshui.common.utils.bean.BeanUtils;
import com.jianshui.invoice.domain.*;
import com.jianshui.invoice.domain.dto.HXResponse;
import com.jianshui.invoice.domain.dto.adapter.request.aisino_jn.HxRedInfoDTO;
import com.jianshui.invoice.domain.dto.adapter.request.aisino_jn.HxRedInfoDetailsDTO;
import com.jianshui.invoice.domain.dto.adapter.response.RedInfoDTO;
import com.jianshui.invoice.domain.dto.adapter.response.RedInfoDetailDTO;
import com.jianshui.invoice.domain.dto.adapter.response.aisino_jn.AisinoJnInvoiceDetailResponse;
import com.jianshui.invoice.domain.dto.adapter.response.aisino_jn.AisinoJnInvoiceResponse;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo1.Invoice2Nuonuo1;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo1.InvoiceDetail2Nuonuo1;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo1.RedInfo2Nuonuo1;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo1.RedInfoDetail2Nuonuo1;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo2.Invoice2Nuonuo2;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo2.InvoiceDetail2Nuonuo2;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo2.RedinfoDTO2Nuonuo2;
import com.jianshui.invoice.domain.dto.adapter.response.nuonuo2.RedinfoDetailDTO2Nuonuo2;
import com.jianshui.invoice.service.IInvoiceResponseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.DateUtil;
import org.springframework.stereotype.Component;
import sun.reflect.annotation.ExceptionProxy;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

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

    private JSONObject handleNuonuoResp(HXResponse result) {
        JSONObject nuonuoResp = new JSONObject();
        String errorCode = "E0000";
        String hxCode = result.getString("status");
        switch (hxCode) {
            case "0000":
                errorCode = "E0000";
                break;
            default:
                errorCode = "E4000";
        }
        nuonuoResp.put("code", errorCode);
        nuonuoResp.put("describe", result.getString("message"));
        return nuonuoResp;
    }

    private JSONObject handleNuonuoRespData(HXResponse result, Object data) {
        JSONObject resp = handleNuonuoResp(result);
        resp.put("result", data);
        return resp;
    }

    @Override
    public JSONObject response(HXResponse result, Companyservice companyservice, String query) {

        // 如果是开具
        if (StringUtils.equals("add", query)) {
            JSONObject nuonuoResp = handleNuonuoResp(result);
            JSONObject fpqqlsh = new JSONObject();
            fpqqlsh.put("invoiceSerialNum", result.getString("fpqqlsh"));
            nuonuoResp.put("result", fpqqlsh);
            return nuonuoResp;
        }

        // 如果是发票查询
        if (StringUtils.equals("query", query)) {
            // 判断有无data
            Object datas = result.getData();
            JSONObject nuonuoResp = handleNuonuoResp(result);
            // 如果datas不为Null
            if (datas != null) {
                // 如果返回将诶过为invioce
                List<Invoice2Nuonuo2> responses = new ArrayList<>();
                if (datas instanceof List) {
                    for (int ij = 0; ij < ((List<?>) datas).size(); ij++) {
                        Object data = ((List<?>) datas).get(ij);
                        // 转为HxInvoice
                        Invoice invoice = (Invoice) data;
                        if (invoice == null) {
                            continue;
                        }
                        Invoice2Nuonuo2 invoiceResponse = new Invoice2Nuonuo2();
                        BeanUtils.copyProperties(invoice, invoiceResponse);
                        String invoiceType = DictUtils.getDictLabel("invoice_type", invoice.getInvoiceType());
                        if (invoiceType != null) {
                            invoiceResponse.setInvoiceType(invoiceType);
                        }

                        // 处理Detail
                        List<InvoiceDetail> detailList = invoice.getInvoiceDetailList();
                        if (detailList != null) {
                            List<InvoiceDetail2Nuonuo2> invoiceDetailResponses = new ArrayList<>();
                            for (int i = 0; i < detailList.size(); i++) {
                                InvoiceDetail2Nuonuo2 response = new InvoiceDetail2Nuonuo2();
                                InvoiceDetail tempDetail = detailList.get(i);
                                BeanUtils.copyProperties(tempDetail, response);
                                // 含税标志 isIncludeTax
                                Integer hsbz = tempDetail.getHsbz();

                                // 金额
                                if (hsbz == 0) {
                                    response.setIsIncludeTax("false");
                                    response.setItemAmount(tempDetail.getTaxfreeamt());
                                    // 如果不含税
                                } else {
                                    // 如果含税
                                    response.setIsIncludeTax("false");
                                    response.setItemAmount(tempDetail.getTaxamt());
                                }

                                invoiceDetailResponses.add(response);
                            }
                            invoiceResponse.setInvoiceDetailList(invoiceDetailResponses);
                        }
                        responses.add(invoiceResponse);
                    }

                    nuonuoResp.put("result", responses);
                    return nuonuoResp;
                }

            }
            return nuonuoResp;
        }

        // 如果是开具红票
        if (StringUtils.equals("add_redinfo", query)) {
            return handleNuonuoResp(result);
            // return result;
        }

        // 如果是下载红票
        if (StringUtils.equals("download_redinfo", query)) {

            Object datas = result.getData();

            // 如果datas不为Null
            if (datas != null) {
                // 如果返回将诶过为invioce
                List<RedinfoDTO2Nuonuo2> responses = new ArrayList<>();
                if (datas instanceof List) {
                    for (int ij = 0; ij < ((List<?>) datas).size(); ij++) {
                        Object data = ((List<?>) datas).get(ij);
                        // 转为RedInfoDTO
                        List<RedinfoDetailDTO2Nuonuo2> details = new ArrayList<>();
                        RedInfoDTO redInfoDTO = (RedInfoDTO) data;
                        RedinfoDTO2Nuonuo2 redinfoDTO2Nuonuo2 = (RedinfoDTO2Nuonuo2) data;
                        BeanUtils.copyProperties(redInfoDTO, redinfoDTO2Nuonuo2);
                        if (CollectionUtil.isNotEmpty(redInfoDTO.getMyRedinfodetailList())) {
                            List<RedInfoDetailDTO> temp = redInfoDTO.getMyRedinfodetailList();
                            for (RedInfoDetailDTO t : temp) {
                                RedinfoDetailDTO2Nuonuo2 myt = new RedinfoDetailDTO2Nuonuo2();
                                BeanUtils.copyProperties(t, myt);
                                details.add(myt);
                            }
                            redinfoDTO2Nuonuo2.setDetails(details);
                        }
                        responses.add(redinfoDTO2Nuonuo2);
                    }
                }
                return handleNuonuoRespData(result, responses);
            }
            // return result;
        }


        return handleNuonuoResp(result);
    }

    @Override
    public Object response(JianshuiParamErrorException result, Companyservice companyservice) {
        JSONObject myResult = new JSONObject();
        myResult.put("status", result.getErrorCode());
        myResult.put("message", result.getMsg());
        return myResult;
    }

    /**
     * 发票回调接口
     *
     * @param billInfo
     * @param invoice
     * @param companyservice
     * @param src            操作来源，add 发票开具，
     * @return
     */
    @Override
    public AjaxResult callback(BillInfo billInfo, Invoice invoice, Redinfo redinfo, Companyservice companyservice, String src) {
        Map<String, Object> requestBody = null;

        // 取一下回调地址
        String callbackUrl = billInfo.getCallbackUrl();
        if (StringUtils.isEmpty(callbackUrl)) {
            // 如果billinfo里的回写地址为空，看一下companyservice的rebackurl是否为空
            callbackUrl = companyservice.getRebackurl();
        }

        if (StringUtils.isEmpty(callbackUrl)) {
            return AjaxResult.error("回调地址为空，取消回调");
        }

        // 如果是开票回调
        if (StringUtils.equals(src, "add")) {

            // 进行开票回调组装。坑比诺诺，2.0的回调用的1.0的文档
            // 处理invoice
            Invoice2Nuonuo1 invoice2Nuonuo1 = new Invoice2Nuonuo1();
            BeanUtils.copyProperties(invoice, invoice2Nuonuo1);
            // 修改status
            Integer state = invoice2Nuonuo1.getState();
            // 1完成，2失败，3签章失败
            switch (state) {
                case 2:
                    state = 1;
                    break;
                case 22:
                    state = 2;
                    break;
                case 24:
                    state = 3;
                    break;
            }
            invoice2Nuonuo1.setState(state);

            String invoiceType = DictUtils.getDictLabel("invoice_type", invoice.getInvoiceType());
            if (invoiceType != null) {
                invoice2Nuonuo1.setInvoiceType(invoiceType);
            }

            // 处理detail
            List<InvoiceDetail2Nuonuo1> detail2Nuonuo1s = new ArrayList<>();
            List<InvoiceDetail> details = invoice.getInvoiceDetailList();
            if (CollectionUtil.isNotEmpty(details)) {
                for (int i = 0; i < details.size(); i++) {
                    InvoiceDetail2Nuonuo1 temp = new InvoiceDetail2Nuonuo1();
                    InvoiceDetail tempDetail = details.get(i);
                    BeanUtils.copyProperties(tempDetail, temp);
                    Integer hsbz = tempDetail.getHsbz();
                    if (hsbz == 0) {
                        temp.setHsbz("false");
                        temp.setTaxamt(null);
                        // 如果不含税
                    } else {
                        // 如果含税
                        temp.setHsbz("true");
                        temp.setTaxfreeamt(temp.getTaxamt());
                    }
                    detail2Nuonuo1s.add(temp);
                }
            }
            invoice2Nuonuo1.setInvoiceDetailList(detail2Nuonuo1s);
            requestBody = new LinkedHashMap<>();
            requestBody.put("operater", "callback");
            requestBody.put("orderno", billInfo.getOutTradeOrderno());
            requestBody.put("content", JSONObject.toJSONString(invoice2Nuonuo1));
        }

        // 发票作废
        if (StringUtils.equals(src, "deprecate")) {
            JSONObject contentJson = new JSONObject();
            contentJson.put("c_fpdm", invoice.getFpdm());
            contentJson.put("c_fphm", invoice.getFphm());
            contentJson.put("c_saletaxnum", invoice.getSellerTaxnum());
            contentJson.put("invalidTime", DateUtils.getNowDate());
            String status = null;
            switch (invoice.getState()) {
                case 3:
                    status = "3"; // 作废成功
                    break;
                case 31:
                    status = "1"; // 作废中
                    break;
                default:
                    status = "3"; // 未作废
                    break;
            }
            contentJson.put("invalidStatus", status);
            contentJson.put("invalidErrorMessage", "");
            requestBody = new LinkedHashMap<>();
            requestBody.put("operater", "invoiceInvalid");
            requestBody.put("fpqqlsh", billInfo.getSystemOrderno());
            requestBody.put("content", JSONObject.toJSONString(contentJson));
        }

        // 红字信息表上传
        if (StringUtils.equals(src, "add_redinfo")) {
            // 开始把航信报文转成billInfo
            RedInfo2Nuonuo1 redInfo2Nuonuo1 = new RedInfo2Nuonuo1();
            BeanUtils.copyProperties(redinfo, redInfo2Nuonuo1);

            // 处理detail
            List<RedInfoDetail2Nuonuo1> redInfoDetail2Nuonuo1s = new ArrayList<>();
            List<Redinfodetail> detailList = redinfo.getRedinfodetailList();
            if (CollectionUtil.isNotEmpty(detailList)) {
                for (int i = 0; i < detailList.size(); i++) {
                    Redinfodetail detial = detailList.get(i);
                    RedInfoDetail2Nuonuo1 temp = new RedInfoDetail2Nuonuo1();
                    org.springframework.beans.BeanUtils.copyProperties(detial, temp);
                    redInfoDetail2Nuonuo1s.add(temp);
                }
            }
            redInfo2Nuonuo1.setRedinfodetailList(redInfoDetail2Nuonuo1s);

            requestBody = new LinkedHashMap<>();
            requestBody.put("operater", "invoiceInvalid");
            requestBody.put("fpqqlsh", billInfo.getOutTradeOrderno());
            requestBody.put("content", JSONObject.toJSONString(redInfo2Nuonuo1));
        }


        // 如果resquestBody不为null则开始发送请求
        if (requestBody != null) {
            // 开始发送请求
            String response = HttpRequest.post(callbackUrl)
                    // .setHttpProxy("127.0.0.1", 9090)
                    .contentType(ContentType.MULTIPART.getValue())
                    .form(requestBody)//表单内容
                    .timeout(50000)//超时，毫秒
                    .execute().body();
            try {
                log.info("【发票返回适配器】【诺诺2.0】【回调方法】发送URL：{}，甲方响应结果：{}", JSONObject.toJSONString(requestBody), response);
                JSONObject resp = JSONObject.parseObject(response);
                if (resp == null) {
                    return AjaxResult.error("解析返回报文json失败，解析结果为Null");
                }

                // 处理返回结果，看是否还需要继续投入回调
                if (!StringUtils.equals("200", resp.getString("status"))) {
                    AjaxResult errorResp = AjaxResult.error("甲方回调未返回状态码0000，重新投入队列");
                    errorResp.put("code", 501);
                    return errorResp;
                }

                return AjaxResult.success("回调成功！");

            } catch (Exception e) {
                e.printStackTrace();
                log.error("【发票返回适配器】【诺诺2.0】【回调方法】诺诺回调出现异常，解析用户返回的json信息失败，原报文信息{}", response);
                return AjaxResult.error("解析返回报文json失败");
            }
        }

        return AjaxResult.error("不支持的回调形式");
    }
}
