package com.dxhy.erp.service.impl;

import java.text.DecimalFormat;
import java.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.ReturnCodeEnum;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.pojo.Authorize;
import com.dxhy.common.util.pojo.GlobalInfo;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.erp.dao.SysDeptDao;
import com.dxhy.erp.dao.TdxRecordInvoiceDao;
import com.dxhy.erp.entity.SysDeptEntity;
import com.dxhy.erp.entity.TdxOrderLog;
import com.dxhy.erp.entity.TdxRecordInvoice;
import com.dxhy.erp.model.AuthStatus;
import com.dxhy.erp.model.CollectData;
import com.dxhy.erp.model.OrderData;
import com.dxhy.erp.model.ReturnStateInfo;
import com.dxhy.erp.model.auth.InterfaceCode;
import com.dxhy.erp.service.OrderLogService;
import com.dxhy.erp.service.OrderService;
import com.dxhy.erp.utils.CheckUtils;

import cn.hutool.core.codec.Base64;
import lombok.extern.slf4j.Slf4j;

/**
 * @author dxhy
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
@Service("orderService")
@Slf4j
public class OrderServiceImpl extends MpBaseServiceImpl<TdxRecordInvoiceDao, TdxRecordInvoice> implements OrderService {

    @Resource
    private SysDeptDao sysDeptDao;

    @Resource
    private OrderLogService orderLogService;

    @Value("${db.YGtaxNo}")
    private String taxNo;

    @Override
    public String saveOrder(GlobalInfo globalInfo, Map<String, String> map, HttpServletRequest request,
        HttpServletResponse response, Authorize authorize) {

        ReturnStateInfo run = new ReturnStateInfo();
        String data = map.get("data");
        TdxOrderLog orderLog = new TdxOrderLog();
        orderLog.setReqDate(new Date());
        orderLog.setReqText(data);
        List<OrderData> orderDatas = null;
        log.info("推送的订单信息----" + data);
        try {

            orderDatas = JSONObject.parseArray(data, OrderData.class);
        } catch (Exception e) {
            run.setReturnCode(ReturnCodeEnum.QQBWGSCW.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.QQBWGSCW.getFhzMc(ReturnCodeEnum.QQBWGSCW.getIndex()));
            InterfaceCode interfaceCode = new InterfaceCode();
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            return JSON.toJSONString(interfaceCode);
        }
        String dbName = null;
        try {
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysDeptEntity deptEntity = sysDeptDao.getOrg(taxNo);
            if (deptEntity != null && deptEntity.getDbName() != null) {
                dbName = deptEntity.getDbName();
            } else {

                ReturnStateInfo runInfo = new ReturnStateInfo();
                runInfo.setReturnCode(ReturnCodeEnum.JTSHBF.getFhzDm());
                runInfo.setReturnMessage(ReturnCodeEnum.JTSHBF.getFhzMc(ReturnCodeEnum.JTSHBF.getIndex()));
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(runInfo);
                return JSON.toJSONString(interfaceCode);
            }

            List<OrderData> resultList = new ArrayList<>();
            for (OrderData order : orderDatas) {
                OrderData returnData = new OrderData();
                returnData.setInvoiceCode(order.getInvoiceCode());
                returnData.setInvoiceNo(order.getInvoiceNo());
                String uuid = order.getInvoiceCode() + order.getInvoiceNo();
                String orderNo = order.getOrderNo();

                DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
                QueryWrapper<TdxRecordInvoice> query = new QueryWrapper<>();
                query.eq("uuid", uuid);
                TdxRecordInvoice recordInvoice = super.getOne(query);
                if (recordInvoice != null) {

                    String auth = "0,5,6";
                    // 已认证成功不修改订单号
                    if (!"0".equals(recordInvoice.getRzhYesorno())) {
                        returnData.setReturnMessage("该发票已认证成功");
                        resultList.add(returnData);
                        // 已提交认证不修改订单号
                    } else if (!auth.contains(recordInvoice.getAuthStatus())) {
                        returnData.setReturnMessage("该发票已在认证处理中");
                        resultList.add(returnData);
                    } else {// 更新发票订单号
                        TdxRecordInvoice updateInvoice = new TdxRecordInvoice();
                        updateInvoice.setId(recordInvoice.getId());
                        updateInvoice.setOrderNo(orderNo);
                        updateInvoice.setIsAuth("1");
                        DynamicContextHolder.push(dbName + DbConstant.BUSINESS_WRITE);
                        super.updateById(updateInvoice);
                        returnData.setReturnMessage("处理成功");
                        resultList.add(returnData);
                    }
                } else {
                    returnData.setReturnMessage("发票不存在");
                    resultList.add(returnData);
                }

            }

            String result = JSON.toJSONString(resultList);
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
            InterfaceCode interfaceCode = new InterfaceCode();
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            interfaceCode.setData(Base64.encode(result));
            String message = JSON.toJSONString(interfaceCode);
            orderLog.setResText(message);
            orderLog.setResDate(new Date());
            orderLogService.saveLog(orderLog, dbName);
            return message;
        } catch (Exception e) {
            e.printStackTrace();
            run.setReturnCode("2011");
            run.setReturnMessage("其他异常");
            String globalJson = null;
            String runJson = null;
            try {
                runJson = JSON.toJSONString(run);
                globalJson = JSON.toJSONString(globalInfo);
            } catch (Exception ignored) {
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            orderLog.setResText("{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}");
            orderLog.setResDate(new Date());
            orderLogService.saveLog(orderLog, dbName);
            return "{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}";
        }

    }

    @Override
    public String countRzhInfo(GlobalInfo globalInfo, Map<String, String> map, HttpServletRequest request,
        HttpServletResponse response, Authorize authorize) {

        ReturnStateInfo run = new ReturnStateInfo();
        try {
            CollectData data = null;
            try {

                data = JSON.parseObject(map.get("data"), CollectData.class);
            } catch (Exception e) {
                run.setReturnCode(ReturnCodeEnum.QQBWGSCW.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.QQBWGSCW.getFhzMc(ReturnCodeEnum.QQBWGSCW.getIndex()));
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(run);
                return JSON.toJSONString(interfaceCode);
            }
            run = getCheck(data);
            if (run.getReturnCode() != null || run.getReturnMessage() != null) {
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(run);
                return JSON.toJSONString(interfaceCode);
            }

            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysDeptEntity deptEntity = sysDeptDao.getOrg(taxNo);
            String dbName = null;
            if (deptEntity != null && deptEntity.getDbName() != null) {
                dbName = deptEntity.getDbName();
            } else {
                ReturnStateInfo runInfo = new ReturnStateInfo();
                runInfo.setReturnCode(ReturnCodeEnum.JTSHBF.getFhzDm());
                runInfo.setReturnMessage(ReturnCodeEnum.JTSHBF.getFhzMc(ReturnCodeEnum.JTSHBF.getIndex()));
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(runInfo);
                return JSON.toJSONString(interfaceCode);
            }

            List<OrderData> resultList = new ArrayList<>();
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
            List<TdxRecordInvoice> selectAuth = selectAuth(data);
            if (selectAuth != null && selectAuth.size() > 0) {
                for (TdxRecordInvoice tDxRecordInvoice : selectAuth) {
                    OrderData resultData = new OrderData();
                    resultData.setInvoiceCode(tDxRecordInvoice.getInvoiceCode());
                    resultData.setInvoiceNo(tDxRecordInvoice.getInvoiceNo());
                    if (StringUtils.isNotBlank(tDxRecordInvoice.getIsAuth())) {

                        resultData.setAuthStatus(tDxRecordInvoice.getIsAuth());
                    } else {
                        resultData.setAuthStatus("0");
                    }

                    resultList.add(resultData);
                }
            }

            String result = JSON.toJSONString(resultList);
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
            InterfaceCode interfaceCode = new InterfaceCode();
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            interfaceCode.setData(Base64.encode(result));
            return JSON.toJSONString(interfaceCode);

        } catch (Exception e) {
            e.printStackTrace();
            run.setReturnCode("2011");
            run.setReturnMessage("其他异常");
            String globalJson = null;
            String runJson = null;
            try {
                runJson = JSON.toJSONString(run);
                globalJson = JSON.toJSONString(globalInfo);
            } catch (Exception ignored) {
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            return "{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}";
        }

    }

    public ReturnStateInfo getCheck(CollectData data) {
        ReturnStateInfo run = new ReturnStateInfo();

        if (CheckUtils.isNullOrEmpty(data.getInvoiceDateBegin())) {
            run.setReturnCode("2007");
            run.setReturnMessage("开票起始日期不能为空");
        }
        if (CheckUtils.isNullOrEmpty(data.getInvoiceDateEnd())) {
            run.setReturnCode("2010");
            run.setReturnMessage("开票结束日期不能为空");
        }

        return run;
    }

    public List<TdxRecordInvoice> selectAuth(CollectData data) throws Exception {
        Map<String, Object> map = new HashMap<>(16);
        map.put("buyerTaxNo", data.getBuyerTaxNo());
        map.put("invoiceDateBegin", data.getInvoiceDateBegin());
        map.put("invoiceDateEnd", data.getInvoiceDateEnd());
        return super.baseMapper.selectAuth(map);
    }

    @Override
    public String getRzhStatus(GlobalInfo globalInfo, Map<String, String> map, HttpServletRequest request,
        HttpServletResponse response, Authorize authorize) {
        ReturnStateInfo run = new ReturnStateInfo();
        try {

            CollectData data = null;
            try {
                data = JSON.parseObject(map.get("data"), CollectData.class);
            } catch (Exception e) {
                run.setReturnCode(ReturnCodeEnum.QQBWGSCW.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.QQBWGSCW.getFhzMc(ReturnCodeEnum.QQBWGSCW.getIndex()));
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(run);
                return JSON.toJSONString(interfaceCode);
            }
            run = check(data);
            if (run.getReturnCode() != null || run.getReturnMessage() != null) {
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(run);
                return JSON.toJSONString(interfaceCode);
            }

            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysDeptEntity deptEntity = sysDeptDao.getOrg(taxNo);
            String dbName = null;
            if (deptEntity != null && deptEntity.getDbName() != null) {
                dbName = deptEntity.getDbName();
            } else {
                ReturnStateInfo runInfo = new ReturnStateInfo();
                runInfo.setReturnCode(ReturnCodeEnum.JTSHBF.getFhzDm());
                runInfo.setReturnMessage(ReturnCodeEnum.JTSHBF.getFhzMc(ReturnCodeEnum.JTSHBF.getIndex()));
                InterfaceCode interfaceCode = new InterfaceCode();
                interfaceCode.setGlobalInfo(globalInfo);
                interfaceCode.setReturnStateInfo(runInfo);
                return JSON.toJSONString(interfaceCode);
            }

            String uuid = data.getInvoiceCode() + data.getInvoiceNo();
            DynamicContextHolder.push(dbName + DbConstant.BUSINESS_READ);
            TdxRecordInvoice selectStatus = super.baseMapper.selectRzhStatus(uuid);

            AuthStatus returnAuthStatus = new AuthStatus();
            if (selectStatus != null) {
                DecimalFormat df = new DecimalFormat("#0.00");
                returnAuthStatus.setInvoiceCode(selectStatus.getInvoiceCode());
                returnAuthStatus.setInvoiceNo(selectStatus.getInvoiceNo());
                String rzhYesorno = selectStatus.getRzhYesorno();
                if ("1".equals(rzhYesorno)) {
                    returnAuthStatus.setLegalizeState("1");
                } else if ("0".equals(rzhYesorno) && "0".equals(selectStatus.getIsAuth())) {
                    returnAuthStatus.setLegalizeState("0");
                } else if ("0".equals(rzhYesorno) && "1".equals(selectStatus.getIsAuth())) {
                    returnAuthStatus.setLegalizeState("2");
                }
                returnAuthStatus.setLegalizeDate(
                    selectStatus.getRzhDate() == null ? "" : DateUtils.dateToStr(selectStatus.getRzhDate()));
                returnAuthStatus.setLegalizeBelongDate(selectStatus.getRzhBelongDate());
                returnAuthStatus.setRzlx(selectStatus.getRzlx());
                returnAuthStatus
                    .setYxse(selectStatus.getDkTaxAmount() == null ? "" : df.format(selectStatus.getDkTaxAmount()));
            } else {
                run.setReturnCode(ReturnCodeEnum.FPBCZ.getFhzDm());
                run.setReturnMessage(ReturnCodeEnum.FPBCZ.getFhzMc(ReturnCodeEnum.FPBCZ.getIndex()));
                String globalJson = null;
                String runJson = null;
                try {
                    runJson = JSON.toJSONString(run);
                    globalJson = JSON.toJSONString(globalInfo);
                } catch (Exception ignored) {
                }
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                return "{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}";
            }

            String result = JSON.toJSONString(returnAuthStatus);
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
            InterfaceCode interfaceCode = new InterfaceCode();
            interfaceCode.setGlobalInfo(globalInfo);
            interfaceCode.setReturnStateInfo(run);
            interfaceCode.setData(Base64.encode(result));
            return JSON.toJSONString(interfaceCode);

        } catch (Exception e) {
            e.printStackTrace();
            run.setReturnCode("2011");
            run.setReturnMessage("其他异常");
            String globalJson = null;
            String runJson = null;
            try {
                runJson = JSON.toJSONString(run);
                globalJson = JSON.toJSONString(globalInfo);
            } catch (Exception ignored) {
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            return "{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}";
        }
    }

    public ReturnStateInfo check(CollectData data) {
        ReturnStateInfo run = new ReturnStateInfo();

        if (CheckUtils.isNullOrEmpty(data.getInvoiceCode())) {
            run.setReturnCode(ReturnCodeEnum.FPDMBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.FPDMBNWK.getFhzMc(ReturnCodeEnum.FPDMBNWK.getIndex()));
            return run;
        }

        if (CheckUtils.isNullOrEmpty(data.getInvoiceNo())) {
            run.setReturnCode(ReturnCodeEnum.FPHMBNWK.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.FPHMBNWK.getFhzMc(ReturnCodeEnum.FPHMBNWK.getIndex()));
            return run;
        }

        if (!(CheckUtils.stringLength(data.getInvoiceCode(), 10)
            || CheckUtils.stringLength(data.getInvoiceCode(), 12))) {
            run.setReturnCode(ReturnCodeEnum.DMHMBF.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.DMHMBF.getFhzMc(ReturnCodeEnum.DMHMBF.getIndex()));
        }
        boolean r =
            !(CheckUtils.stringLength(data.getInvoiceNo(), 8) || CheckUtils.stringLength(data.getInvoiceNo(), 10));
        if (CheckUtils.isNullOrEmpty(data.getInvoiceNo()) || r) {
            run.setReturnCode(ReturnCodeEnum.DMHMBF.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.DMHMBF.getFhzMc(ReturnCodeEnum.DMHMBF.getIndex()));
        }
        return run;
    }
}
