package com.jianshui.api.controller.webservice.income.v1.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.XmlUtil;
import com.alibaba.fastjson.JSONObject;
// import com.jianshui.api.controller.webservice.income.v1.InvoiceCheckWebService;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.core.domain.entity.Companyservice;
import com.jianshui.common.utils.DateUtils;
import com.jianshui.common.utils.StringUtils;
import com.jianshui.income.domain.entity.InvoiceCheck;
import com.jianshui.income.domain.entity.InvoiceCheckDetail;
import com.jianshui.income.domain.vo.render.*;

import com.jianshui.income.factory.ICheckServiceFactory;
import com.jianshui.income.service.ICheckInvoice;
import com.jianshui.income.service.impl.EleCheckInvoiceImpl;
import com.jianshui.system.domain.CompanyserviceProp;
import com.jianshui.system.service.ICompanyservicePropService;
import com.jianshui.system.service.ICompanyserviceService;
import com.jianshui.system.service.IServiceManageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.JAXBElement;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.jianshui.income.constant.WebServiceConstant.NAMESPACE;

@Component
@Slf4j
@WebService(targetNamespace = NAMESPACE)
// public class InvoiceCheckWebServiceImpl implements InvoiceCheckWebService {
public class InvoiceCheckWebServiceImpl {

    @Autowired
    private ICheckServiceFactory incomeServiceFactory;

    @Autowired
    private IServiceManageService serviceManageService;

    @Autowired
    private ICompanyserviceService companyserviceService;

    @Autowired
    private ICompanyservicePropService companyservicePropService;


    @WebMethod
    public ResponseCheckVO getInvoice(String order) {
        DocumentBuilder resultBuilder = XmlUtil.createDocumentBuilder();
        Document result = resultBuilder.newDocument();


        log.info("【webservice接到请求】order:{}", order);
        Document xml = XmlUtil.parseXml(order);
        Element element = xml.getDocumentElement();
        // 获得xml虾的InvData
        Element invData = XmlUtil.getElement(element, "InvData");
        Node invDataNode = invData == null ? null : invData.getFirstChild();
        Element TaxCodeElement = XmlUtil.getElement(invData, "TaxCode");
        Node TaxCodeElementNode = TaxCodeElement == null ? null : TaxCodeElement.getFirstChild();
        Element PasswordElement = XmlUtil.getElement(invData, "Password");
        Node PasswordElementNode = PasswordElement == null ? null : PasswordElement.getFirstChild();
        Element InvCodeElement = XmlUtil.getElement(invData, "InvCode");
        Node InvCodeElementNode = InvCodeElement == null ? null : InvCodeElement.getFirstChild();
        Element InvNoElement = XmlUtil.getElement(invData, "InvNo");
        Node InvNoElementNode = InvNoElement == null ? null : InvNoElement.getFirstChild();
        Element InvTimeElement = XmlUtil.getElement(invData, "InvTime");
        Node InvTimeElementNode = InvTimeElement == null ? null : InvTimeElement.getFirstChild();
        Element InvOtherElement = XmlUtil.getElement(invData, "InvOther");
        Node InvOtherElementNode = InvOtherElement == null ? null : InvOtherElement.getFirstChild();

        String InvOther = InvOtherElementNode != null ? InvOtherElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(InvOther)) {
            return buildResult(result, "1", "不含税金额/校验码不能为空", null);
        }
        String Kpje = InvOtherElementNode != null ? InvOtherElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(Kpje)) {
            Kpje = InvOther;
//            return buildResult(result, "1", "开票金额不能为空", null);
        }
        // 获得value
        String TaxCode = TaxCodeElementNode != null ? TaxCodeElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(TaxCode)) {
            return buildResult(result, "1", "税号不能为空", null);
        }

        // 根据税号获得companyService
        Companyservice companyservice = companyserviceService.selectCompanyserviceByTaxcode(TaxCode);
        if (companyservice == null) {
            return buildResult(result, "1", "税号不存在", null);
        }

        String Password = PasswordElementNode != null ? PasswordElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(Password)) {
            return buildResult(result, "1", "交互密码不能为空", null);
        }

        String InvCode = InvCodeElementNode != null ? InvCodeElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(InvCode)) {
            return buildResult(result, "1", "发票代码不能为空", null);
        }
        String InvNo = InvNoElementNode != null ? InvNoElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(InvNo)) {
            return buildResult(result, "1", "发票号码不能为空", null);
        }
        String InvTime = InvTimeElementNode != null ? InvTimeElementNode.getNodeValue() : "";
        if (StringUtils.isEmpty(InvTime)) {
            return buildResult(result, "1", "开票日期不能为空", null);
        }
        // 如果Jym这个参数为空，我就去判断InvOther是否为6位且不带小数点，如果确实如此，那就直接将InvOther作为校验码传给大象
        // 2023.03.09 如果InvOtherNode是6位且不到小数点，那么就直接将InvOtherNode作为校验码传给大象
        String Jym = InvOtherElementNode != null ? InvOtherElementNode.getNodeValue() : "";
        if (StringUtils.isNotEmpty(Jym)) {
            // 判断InvOther是否为6位且不带小数点
            if (!(Jym.length() == 6 && !Jym.contains("."))) {
                Jym = "";
            }

            // return buildResult(result, "1", "校验码不能为空", null);
        }

        // String Fpzl = TaxCodeElementNode != null ? TaxCodeElementNode.getNodeValue() : "";
        String Fpzl = "";
        // 如果发票号码位数为20位，则fpzl为21,否则为01，中举在2022-12-06 20:08给巩权林说的解决方案，是大象那边提的，可以用来适配远得
        if (InvNo.length() == 20) {
            Fpzl = "21";
        } else {
            Fpzl = "01";
        }

        CompanyserviceProp keyProp = companyservicePropService.selectPropByKey(companyservice.getCompanyid(), "webservice_password");
        if (keyProp == null || !StringUtils.equals(keyProp.getValue(), Password)) {
            return buildResult(result, "1", "交互密码错误", null);
        }

        // 调用发票查询接口
        String serviceKey = "";
        try {
            serviceKey = serviceManageService.getCompanyServiceSupplier("income", companyservice.getCompanyid());
        } catch (Exception e) {
            e.printStackTrace();
            return buildResult(result, "1", "发票查询失败", null);
        }
        if (StringUtils.isEmpty(serviceKey)) {
            log.error("【发票查询失败】companyid:{}，serviceKey为空", companyservice.getCompanyid());
            return buildResult(result, "1", "发票查询失败", null);
        }

        ICheckInvoice incomeService = incomeServiceFactory.getService(serviceKey);
        if (incomeService == null) {
            log.error("【发票查询失败】companyid:{}，serviceKey:{}，incomeService为空", companyservice.getCompanyid(), serviceKey);
            return buildResult(result, "1", "发票查询失败", null);
        }

        // 调用发票查询接口
        JSONObject request = new JSONObject();
        request.put("fpzl", Fpzl); // TODO 新增发票种类字段
        request.put("fpje", Kpje); // TODO 开票金额字段
        request.put("fpdm", InvCode);
        Date kprqDate = null;
        try {
            kprqDate = DateUtils.parseDate(InvTime, "yyyy-MM-dd");
        } catch (ParseException e) {
            log.error("【发票查询失败】companyid:{}，serviceKey:{}，kprqDate解析失败", companyservice.getCompanyid(), serviceKey);
        }
        String kprq = InvTime;
        if (kprqDate != null) {
            kprq = DateUtils.parseDateToStr("yyyyMMdd", kprqDate);
        }
        request.put("kprq", kprq);
        request.put("fphm", InvNo);
        request.put("jym", Jym);
        AjaxResult invoiceResult = incomeService.checkInvoiceSingle(companyservice, request);
        log.info("【发票查询结果】companyid:{}，serviceKey:{}，invoiceResult:{}", companyservice.getCompanyid(), serviceKey, JSONObject.toJSONString(invoiceResult));
        // JSONObject data = JSONObject.parseObject("{\n" +
        //         "        \"robUserMoney\": 0,\n" +
        //         "        \"resultContent\": {\n" +
        //         "            \"cjhj\": \"\",\n" +
        //         "            \"dzzfbs\": \"\",\n" +
        //         "            \"gmfmc\": \"\",\n" +
        //         "            \"zgswjgmc\": \"\",\n" +
        //         "            \"qydjyddd\": \"\",\n" +
        //         "            \"dw\": \"\",\n" +
        //         "            \"bswjurl\": \"\",\n" +
        //         "            \"shrmc\": \"\",\n" +
        //         "            \"jypmdwdzsbh\": \"\",\n" +
        //         "            \"skr\": \"\",\n" +
        //         "            \"cllx\": \"\",\n" +
        //         "            \"djzh\": \"\",\n" +
        //         "            \"mfdwgr\": \"\",\n" +
        //         "            \"cyjg\": \"1005\",\n" +
        //         "            \"khyh\": \"\",\n" +
        //         "            \"qdbz\": \"\",\n" +
        //         "            \"xhfdzdh\": \"\",\n" +
        //         "            \"txfbz\": \"\",\n" +
        //         "            \"jypmdw\": \"\",\n" +
        //         "            \"zrdcgsmc\": \"\",\n" +
        //         "            \"jypmdwdz\": \"\",\n" +
        //         "            \"fpse\": \"\",\n" +
        //         "            \"kpr\": \"\",\n" +
        //         "            \"sjdh\": \"\",\n" +
        //         "            \"shrsbh\": \"\",\n" +
        //         "            \"czch\": \"\",\n" +
        //         "            \"cpxh\": \"\",\n" +
        //         "            \"smfdwgr\": \"\",\n" +
        //         "            \"gmfdzdh\": \"\",\n" +
        //         "            \"fpje\": \"1403016L1NN5336\",\n" +
        //         "            \"detailList\": [],\n" +
        //         "            \"cyjgxx\": \"查询发票不规范\",\n" +
        //         "            \"jshj\": \"\",\n" +
        //         "            \"zgswjgdm\": \"\",\n" +
        //         "            \"zfbz\": \"\",\n" +
        //         "            \"fdjhm\": \"\",\n" +
        //         "            \"jypmdwdh\": \"\",\n" +
        //         "            \"escsc\": \"\",\n" +
        //         "            \"gmfyhzh\": \"\",\n" +
        //         "            \"xhfmc\": \"\",\n" +
        //         "            \"cycs\": \"\",\n" +
        //         "            \"hgzs\": \"\",\n" +
        //         "            \"fhrmc\": \"\",\n" +
        //         "            \"xhfyhzh\": \"\",\n" +
        //         "            \"gmfsbh\": \"\",\n" +
        //         "            \"fpzl\": \"01\",\n" +
        //         "            \"mfdwgrdz\": \"\",\n" +
        //         "            \"xcrs\": \"\",\n" +
        //         "            \"clsbh\": \"\",\n" +
        //         "            \"kprq\": \"2022-08-31\",\n" +
        //         "            \"smfdh\": \"\",\n" +
        //         "            \"bz\": \"\",\n" +
        //         "            \"sl\": \"\",\n" +
        //         "            \"ccdw\": \"\",\n" +
        //         "            \"khyhjzh\": \"\",\n" +
        //         "            \"escscdz\": \"\",\n" +
        //         "            \"cd\": \"\",\n" +
        //         "            \"escscsbh\": \"\",\n" +
        //         "            \"fpdm\": \"2200214130\",\n" +
        //         "            \"skph\": \"\",\n" +
        //         "            \"mfdwdmsfzh\": \"\",\n" +
        //         "            \"yshwxx\": \"\",\n" +
        //         "            \"xhfsbh\": \"\",\n" +
        //         "            \"mfdh\": \"\",\n" +
        //         "            \"fhr\": \"\",\n" +
        //         "            \"wspzhm\": \"\",\n" +
        //         "            \"lslbs\": \"\",\n" +
        //         "            \"smfdwgrzz\": \"\",\n" +
        //         "            \"smfdwdmsfzh\": \"\",\n" +
        //         "            \"escscdh\": \"\",\n" +
        //         "            \"cyrsbh\": \"\",\n" +
        //         "            \"spfshb\": \"\",\n" +
        //         "            \"sfzh\": \"\",\n" +
        //         "            \"fhrsbh\": \"\",\n" +
        //         "            \"cpzh\": \"\",\n" +
        //         "            \"spfmc\": \"\",\n" +
        //         "            \"jkzmsh\": \"\",\n" +
        //         "            \"escsckhyhzh\": \"\",\n" +
        //         "            \"khzh\": \"\",\n" +
        //         "            \"cyrmc\": \"\",\n" +
        //         "            \"jqbh\": \"\",\n" +
        //         "            \"fphm\": \"01779700\",\n" +
        //         "            \"jym\": \"1403016L1NN5336\"\n" +
        //         "        }\n" +
        //         "    }");
        // AjaxResult invoiceResult = AjaxResult.success(data);
        if (invoiceResult.isError()) {
            return buildResult(result, "1", invoiceResult.getMsg(), null);
        }

        if (invoiceResult.isSuccess()) {
            JSONObject resp = invoiceResult.getJsonData();
            Integer robUser = resp.getInteger("robUserMoney");
            if (robUser != null && robUser >= 1) {
                serviceManageService.companyConsume("income", companyservice.getCompanyid());
            }
        }

        // 如果开票成功
        JSONObject invoiceJsonResult = invoiceResult.getJsonData();
        JSONObject resultContent = invoiceJsonResult.getJSONObject("resultContent");
        InvoiceCheck invoiceCheck = new InvoiceCheck();
        invoiceCheck = EleCheckInvoiceImpl.handelCheckResult(invoiceCheck, resultContent);
        GetInvoiceVO getInvoiceVO = new GetInvoiceVO();
        BeanUtils.copyProperties(invoiceCheck, getInvoiceVO);
        String zfbz = getInvoiceVO.getZfbz();
        if (StringUtils.equals(zfbz, "Y")) {
            getInvoiceVO.setZfbz("Y");
        }
        if (StringUtils.equals(zfbz, "H")) {
            getInvoiceVO.setZfbz("Y");
            getInvoiceVO.setHcbz("Y");
        }
        if (StringUtils.equals(zfbz, "N")) {
            getInvoiceVO.setZfbz("N");
            getInvoiceVO.setHcbz("N");
        }

        List<GetInvoiceSphVO> getInvoiceSphVOList = new ArrayList<>();
        List<InvoiceCheckDetail> details = invoiceCheck.getInvoiceCheckDetail();
        if (CollectionUtil.isNotEmpty(details)) {
            for (InvoiceCheckDetail detail : details) {
                GetInvoiceSphVO getInvoiceSphVO = new GetInvoiceSphVO();
                BeanUtils.copyProperties(detail, getInvoiceSphVO);
                getInvoiceSphVOList.add(getInvoiceSphVO);
            }
        }

        // getInvoiceVO转成JSONObject
        JSONObject getInvoiceVOJson = (JSONObject) JSONObject.toJSON(getInvoiceVO);
        Element getInvoiceDoc = json2Element(result, "Fp", getInvoiceVOJson);
        for (GetInvoiceSphVO getInvoiceSphVO : getInvoiceSphVOList) {
            JSONObject getInvoiceSphVOJson = (JSONObject) JSONObject.toJSON(getInvoiceSphVO);
            Element sphElement = json2Element(result, "Sph", getInvoiceSphVOJson);
            getInvoiceDoc.appendChild(sphElement);
        }
        return buildResult(result, "0", "发票查询成功", getInvoiceDoc);
    }

    private Element json2Element(Document result, String elementName, JSONObject jsonObject) {
        Element parent = result.createElement(elementName);
        jsonObject.keySet().forEach(key -> {
            String value = jsonObject.getString(key);
            Element element = result.createElement(key);
            element.setTextContent(value);
            // result.appendChild(element);
            parent.appendChild(element);
        });
        return parent;
    }

    private ResponseCheckVO buildResult(Document result, String code, String message, Element fp) {
        Element Data = result.createElement("Data");
        Element Result = result.createElement("Result");
        Element Code = result.createElement("Code");
        Code.setTextContent(code);  //1:查验成功 其余失败
        Element Message = result.createElement("Message");
        Message.setTextContent(message);
        Result.appendChild(Code);
        Result.appendChild(Message);
        Data.appendChild(Result);
        if (fp == null) {
            fp = result.createElement("Fp");
        }
        Data.appendChild(fp);

        ResponseCheckVO resp = new ResponseCheckVO();
        ResponseCheckDataVO vo = new ResponseCheckDataVO();
        ResponseCheckResultVO responseCheckResultVO = new ResponseCheckResultVO();
        responseCheckResultVO.setCode(Code.getTextContent());
        responseCheckResultVO.setMessage(Message.getTextContent());
        Object myFp = fp;

        vo.setFp(myFp);
        vo.setResult(responseCheckResultVO);

        resp.setDATA(vo);
        return resp;


    }

    // private WebServiceRespVO buildResult(Document result, String code, String message, Element fp) {
    //     WebServiceRespVO webServiceRespVO = new WebServiceRespVO();
    //     WebServiceRespVO.Result respResult = new WebServiceRespVO.Result();
    //     respResult.setCode(code);
    //     respResult.setMessage(message);
    //     webServiceRespVO.setResult(respResult);
    //     if (fp != null) {
    //         webServiceRespVO.setFp(XmlUtil.toStr(fp, "GBK", false, true));
    //     }
    //     return webServiceRespVO;
    // }
}
