package com.dxhy.erp.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.utils.StringUtils;
import com.dxhy.api.model.config.sys.SysEnterpriseConfigEntity;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.ReturnCodeEnum;
import com.dxhy.common.util.pojo.Authorize;
import com.dxhy.common.util.pojo.GlobalInfo;
import com.dxhy.erp.dao.SysEnterpriseConfigErpDao;
import com.dxhy.erp.dao.TdxInvoiceDao;
import com.dxhy.erp.model.*;
import com.dxhy.erp.service.IFEService;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 58同城接口（FE-FiveEight） 二期搬运工
 * 
 * @author JiangHuiTao
 * @date 2021/3/1
 */
@Slf4j
@Service
public class FEServiceImpl implements IFEService {

    @Autowired(required = false)
    private TdxInvoiceDao tdxInvoiceDao;

    @Autowired(required = false)
    private SysEnterpriseConfigErpDao enterpriseConfigErpDao;

    private static final Map<String, Integer> m = new HashMap<>();

    @Override
    public String getSignResult(GlobalInfo globalInfo, Map<String, String> map,
        HttpServletRequest request, HttpServletResponse response, Authorize authorize) {
        ReturnStateInfo run = new ReturnStateInfo();
        List<SignInvoiceInfos> list;
        SignResultRequest data;
        String signJsons = map.get("data");
        try {
            data = JSON.parseObject(signJsons, SignResultRequest.class);
            run = getSignResultCheck(data, globalInfo);
            if (run.getReturnCode() != null || run.getReturnMessage() != null) {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                return "{\"globalInfo\":" + JSON.toJSONString(globalInfo) + ",\"returnStateInfo\":"
                    + JSON.toJSONString(run) + "}";
            }
            Integer total;
            try {
                total = m.get(data.getBatchNo());
                if (total == null) {
                    total =
                        selectSignResultCount(data.getStartDate(), data.getEndDate(), globalInfo.getEnterpriseCode());
                    m.put(data.getBatchNo(), total);
                }
            } catch (Exception e) {
                log.error("获取总条数错误", e);
                total =
                    this.selectSignResultCount(data.getStartDate(), data.getEndDate(), globalInfo.getEnterpriseCode());
                m.put(data.getBatchNo(), total);
            }
            // 成功的集合
            List<SuccessInvoice> successInvoices = new ArrayList<>();
            List<FailInvoice> failInvoices = new ArrayList<>();// 失败的集合
            int totalSize = successInvoices.size() + failInvoices.size();
            int mxszie = 0;
            int startRow = Integer.parseInt(data.getStartRow());
            while (mxszie < 1000 && totalSize < total && startRow <= total) {
                list = selectSignResult(data.getStartDate(), data.getEndDate(), globalInfo.getEnterpriseCode(),
                    startRow - 1, 100);
                startRow += 100;
                if (list != null) {
                    mxszie += list.size();
                    for (SignInvoiceInfos info : list) {
                        if ("1".equals(info.getQsStatus())) {
                            // 如果签收成功的 加入到SuccessList 并查询明细表
                            String invoiceCode =StringUtils.isEmpty(info.getInvoiceCode())?"":info.getInvoiceCode();
                            String uuid =  invoiceCode+ info.getInvoiceNo();
                            DynamicContextHolder.push("business" + DbConstant.DETAIL_READ);
                            String goodsName = tdxInvoiceDao.findDetailByUUid(uuid);
                            SuccessInvoice success = new SuccessInvoice();
                            success.setInvoiceCode(
                                StringUtils.isEmpty(info.getInvoiceCode()) ? "" : info.getInvoiceCode());
                            success.setBuyerName(StringUtils.isEmpty(info.getGfName()) ? "" : info.getGfName());
                            success.setBuyerTaxno(StringUtils.isEmpty(info.getGfTaxNo()) ? "" : info.getGfTaxNo());
                            success.setGoodsName(StringUtils.isEmpty(goodsName) ? "" : goodsName);
                            success.setInvoiceDate(StringUtils.isEmpty(info.getInvoiceDate()) ? ""
                                : info.getInvoiceDate().substring(0, 10));
                            success.setInvoiceNo(StringUtils.isEmpty(info.getInvoiceNo()) ? "" : info.getInvoiceNo());
                            success.setRemark(StringUtils.isEmpty(info.getRemark()) ? "" : info.getRemark());
                            success.setTotalAmount(StringUtils.isEmpty(info.getTotalAmount()) ? ""
                                : info.getTotalAmount().substring(0, info.getTotalAmount().length() - 2));
                            success.setXfName(StringUtils.isEmpty(info.getXfName()) ? "" : info.getXfName());
                            successInvoices.add(success);
                        } else {
                            FailInvoice failInvoice = new FailInvoice();
                            failInvoice.setFailReason(info.getNotes());
                            failInvoice.setInvoiceCode(info.getInvoiceCode());
                            failInvoice.setInvoiceNo(info.getInvoiceNo());
                            failInvoices.add(failInvoice);
                        }
                    }
                }
            }
            GatherSignResultData gather = new GatherSignResultData();
            gather.setStartRow(Integer.parseInt(data.getStartRow()));
            gather.setContentRows(successInvoices.size() + failInvoices.size());
            gather.setTotalRows(total);
            gather.setSuccess(successInvoices);
            gather.setFailure(failInvoices);
            byte[] bs = Base64.encodeBase64(JSON.toJSONString(gather).getBytes(StandardCharsets.UTF_8));
            run.setReturnCode(ReturnCodeEnum.CLCG.getFhzDm());
            run.setReturnMessage(ReturnCodeEnum.CLCG.getFhzMc(ReturnCodeEnum.CLCG.getIndex()));
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            return "{\"globalInfo\":" + JSON.toJSONString(globalInfo) + ",\"returnStateInfo\":" + JSON.toJSONString(run)
                + ",\"data\":\"" + new String(bs) + "\"}";
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            run.setReturnCode("2011");
            run.setReturnMessage("其他异常");
            String globalJson = null;
            String runJson = null;
            runJson = JSON.toJSONString(run);
            globalJson = JSON.toJSONString(globalInfo);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            return "{\"globalInfo\":" + globalJson + ",\"returnStateInfo\":" + runJson + "}";
        }
    }

    private ReturnStateInfo getSignResultCheck(SignResultRequest data, GlobalInfo globalInfo) {
        ReturnStateInfo run = new ReturnStateInfo();
        String startDate = data.getStartDate();
        String endDate = data.getEndDate();
        String batchNo = data.getBatchNo();
        if (StringUtil.isEmpty(data.getStartRow())) {
            run.setReturnCode("2022");
            run.setReturnMessage("开始行数不能为空");
            return run;
        }
        if (Integer.parseInt(data.getStartRow()) <= 0) {
            run.setReturnCode("2022");
            run.setReturnMessage("开始行数必须是正整数");
            return run;
        }
        if (StringUtil.isEmpty(batchNo) || batchNo.length() < 32) {
            run.setReturnCode("2022");
            run.setReturnMessage("批次号不能为空或格式错误");
            return run;
        }
        if (StringUtil.isEmpty(startDate) || StringUtil.isEmpty(endDate)) {
            run.setReturnCode("2020");
            run.setReturnMessage("开始日期、结束日期不可为空");
            return run;
        } else {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            try {
                if (dateFormat.parse(endDate).before(dateFormat.parse(startDate))) {
                    run.setReturnCode("2020");
                    run.setReturnMessage("结束时间必须大于开始时间");
                    return run;
                }
            } catch (ParseException e) {
                log.error("", e);
                run.setReturnCode("2020");
                run.setReturnMessage("时间格式错误");
                return run;
            }
            // 判断税号是否存在
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            int count = enterpriseConfigErpDao.checkBuyerEnterpriseCode(globalInfo.getEnterpriseCode());
            if (count == 0) {
                run.setReturnCode("2021");
                run.setReturnMessage("企业代码不存在");
                return run;
            }
        }
        return run;
    }

    private Integer selectSignResultCount(String startDate, String endDate, String enterpriseCode)
        throws ParseException {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        List<SysEnterpriseConfigEntity> enterpriseConfigEntities = enterpriseConfigErpDao.selectByCompany(enterpriseCode);
        Date start = new SimpleDateFormat("yyyyMMddHHmmss").parse(startDate);
        Date end = new SimpleDateFormat("yyyyMMddHHmmss").parse(endDate);
        DynamicContextHolder.push("business" + DbConstant.BUSINESS_READ);
        List<String> taxNoList = enterpriseConfigEntities.stream().map(SysEnterpriseConfigEntity::getNsrsbh).collect(Collectors.toList());
        return tdxInvoiceDao.selectSignResultCount(start, end, taxNoList);
    }

    private List<SignInvoiceInfos> selectSignResult(String startDate, String endDate, String enterpriseCode, int start,
        int num) throws ParseException {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        List<SysEnterpriseConfigEntity> enterpriseConfigEntities = enterpriseConfigErpDao.selectByCompany(enterpriseCode);
        Date startTime = new SimpleDateFormat("yyyyMMddHHmmss").parse(startDate);
        Date endTime = new SimpleDateFormat("yyyyMMddHHmmss").parse(endDate);
        DynamicContextHolder.push("business" + DbConstant.BUSINESS_READ);
        List<String> taxNoList = enterpriseConfigEntities.stream().map(SysEnterpriseConfigEntity::getNsrsbh).collect(Collectors.toList());
        return tdxInvoiceDao.selectSignResul(startTime, endTime, taxNoList, start, num);

    }
}
