package com.dxhy.base.service.invoicecheck;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import com.dxhy.base.dao.BaseTDxInvoiceDao;
import com.dxhy.base.entity.BaseTDxInvoice;
import com.dxhy.base.utils.InvoiceTypeUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.base.dao.BaseTDxRecordInvoiceDao;
import com.dxhy.base.dao.BaseTDxTaxCurrentDao;
import com.dxhy.base.entity.BaseTDxDkCount;
import com.dxhy.base.entity.BaseTDxRecordInvoice;
import com.dxhy.base.entity.BaseTDxTaxCurrent;
import com.dxhy.base.model.BaseDrgxReqVO;
import com.dxhy.base.model.BaseInvoiceImportCheckRespVO;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FpqsjgEnum;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.common.enums.QsfsEnum;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.InvoiceUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.util.StringHelper;

/**
 * 导入勾选查询service实现类
 *
 * @author kangzq
 *
 *
 */

@SuppressWarnings({"AlibabaLowerCamelCaseVariableNaming", "AlibabaMethodTooLong",
    "AlibabaCollectionInitShouldAssignCapacity"})
@Service("baseInvoiceImportCheckService")
public class BaseInvoiceImportCheckServiceImpl extends MpBaseServiceImpl<BaseTDxRecordInvoiceDao, BaseTDxRecordInvoice>
    implements BaseInvoiceImportCheckService {
    private static final Pattern AMOUNT_PATTERN = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");
    private static final Pattern INVOICE_DATE_PATTERN = Pattern.compile(
        "^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$");

    @Resource
    private BaseTDxTaxCurrentDao baseTDxTaxCurrentDao;
    @Resource
    private BaseTDxRecordInvoiceDao baseTDxRecordInvoiceDao;
    @Resource
    private TabulateRedisService tabulateRedisService;

    @Resource
    private BaseTDxInvoiceDao baseTDxInvoiceDao;

    @Override
    public String selectByDrgxReqVo(Map<String, Object> pramsMap) {
        JSONObject json;
        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_WRITE);
        try {
            String company = (String)pramsMap.get("company");
            String menuId = (String)pramsMap.get("menuId");
            json = tabulateRedisService.getTabulateMenu(company, menuId);

            List<String> gfshList = (List<String>)pramsMap.get("gfsh");
            List<BaseDrgxReqVO> listReqVo = (List<BaseDrgxReqVO>)pramsMap.get("listReqVo");
            String qsflag = (String)pramsMap.get("qsflag");
            List<BaseInvoiceImportCheckRespVO> voList = new ArrayList<>();
            int sucess = 0;
            int fail = 0;
            if (listReqVo.size() > 0) {
                List<String> uuidList = new ArrayList<>();
                for (int i = 0; i < listReqVo.size(); i++) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    BaseInvoiceImportCheckRespVO vo = new BaseInvoiceImportCheckRespVO();
                    String invoiceCode = listReqVo.get(i).getInvoiceCode();
                    String invoiceNo = listReqVo.get(i).getInvoiceNo();
                    String invoiceDate = listReqVo.get(i).getInvoiceDate();
                    String taxAmount = listReqVo.get(i).getTaxAmount();
                    String settlementNo = listReqVo.get(i).getSettlementNo();
                    String settleSource = listReqVo.get(i).getSettleSource();
                    vo.setSelect(true);
                    vo.setBkgxts("");
                    vo.setXh(String.valueOf(i + 1));
                    vo.setInvoiceCode(invoiceCode);
                    vo.setInvoiceNo(invoiceNo);
                    if(invoiceNo.length()==20){
                        vo.setInvoiceCode(invoiceNo.substring(0,12));
                        vo.setInvoiceNo(invoiceNo.substring(12,20));
                        vo.setEleInvoiceNo(invoiceNo);
                    }
                    vo.setInvoiceDate(invoiceDate);
                    vo.setTaxAmount(taxAmount);

                    if (!StringHelper.isBlank(taxAmount)) {
                        // 判断小数点后2位的数字的正则表达式
                        Matcher match = AMOUNT_PATTERN.matcher(taxAmount);
                        if (!match.matches()) {
                            vo.setBkgxts("税额格式错误");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        taxAmount = MathUtil.round(taxAmount);
                        vo.setTaxAmount(taxAmount);
                    } else {
                        vo.setBkgxts("税额不能为空");
                        vo.setSelect(false);
                        voList.add(vo);
                        fail = fail + 1;
                        continue;
                    }
                    if (!StringHelper.isBlank(invoiceDate)) {
                        // 判断日期
                        // yyyy-mm-dd
                        // 的正则表达式（能够区分真实日期，区分闰年）
                        Matcher match = INVOICE_DATE_PATTERN.matcher(invoiceDate);
                        if (!match.matches()) {
                            vo.setBkgxts("开票日期格式错误");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                    } else {
                        vo.setBkgxts("开票日期不能为空");
                        vo.setSelect(false);
                        voList.add(vo);
                        fail = fail + 1;
                        continue;
                    }
                    if (uuidList.contains(invoiceCode + invoiceNo)) {
                        vo.setBkgxts("重复发票");
                        vo.setSelect(false);
                        voList.add(vo);
                        fail = fail + 1;
                        continue;
                    } else {
                        uuidList.add(invoiceCode + invoiceNo);
                    }
                    String invoiceCodes = StringHelper.isBlank(invoiceCode) ? "" : invoiceCode;
                    String uuid = invoiceCodes+invoiceNo;
                    QueryWrapper<BaseTDxRecordInvoice> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("uuid", uuid);

                    // 用于页面展示
                    BaseTDxRecordInvoice tDxRecordInvoice = baseTDxRecordInvoiceDao.selectOne(queryWrapper);
;                    if (tDxRecordInvoice != null) {

                        if (gfshList == null || gfshList.size() == 0
                            || !gfshList.contains(tDxRecordInvoice.getGfTaxNo())) {

                            vo.setBkgxts("无该发票购方税号权限");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }

                        // 今日头条无结算单号时更新
                        if (StringHelper.isNotBlank(settlementNo) && StringHelper.isNotBlank(settleSource)) {
                            QueryWrapper<BaseTDxInvoice> invoiceQueryWrapper = new QueryWrapper<>();
                            invoiceQueryWrapper.eq("uuid", invoiceCode + invoiceNo);
                            BaseTDxInvoice baseTDxInvoice = baseTDxInvoiceDao.selectOne(invoiceQueryWrapper);

                            if (baseTDxInvoice != null) {
                                if (StringHelper.isBlank(baseTDxInvoice.getSettlementNo())
                                    && StringHelper.isBlank(baseTDxInvoice.getSettleSource())) {
                                    baseTDxInvoice.setSettlementNo(settlementNo);
                                    baseTDxInvoice.setSettleSource(settleSource);
                                    baseTDxInvoiceDao.updateById(baseTDxInvoice);
                                }

                            }
                            if (StringHelper.isBlank(tDxRecordInvoice.getSettlementNo())
                                && StringHelper.isBlank(tDxRecordInvoice.getSettleSource())) {
                                tDxRecordInvoice.setSettlementNo(settlementNo);
                                tDxRecordInvoice.setSettleSource(settleSource);
                                baseTDxRecordInvoiceDao.updateById(tDxRecordInvoice);
                            }
                        }

                        if (!invoiceDate.equals(sdf.format(tDxRecordInvoice.getInvoiceDate()))) {
                            vo.setBkgxts("开票日期与底账数据不一致");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        if (!taxAmount.equals(
                            tDxRecordInvoice.getTaxAmount().setScale(2, BigDecimal.ROUND_DOWN).toPlainString())) {
                            vo.setBkgxts("税额与底账数据不一致");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        if (tDxRecordInvoice.getDkTaxAmount() != null) {
                            String dkTaxAmount = tDxRecordInvoice.getDkTaxAmount().toPlainString();
                            if (Double.parseDouble(taxAmount) < Double.parseDouble(dkTaxAmount)) {
                                vo.setBkgxts("抵扣税额应小于等于税额");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                            vo.setDkTaxAmount(MathUtil.round(tDxRecordInvoice.getDkTaxAmount().toPlainString()));
                        }

                        if ("1".equals(qsflag) && !"1".equals(tDxRecordInvoice.getQsStatus())) {
                            vo.setBkgxts("该发票未签收");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        vo.setId(tDxRecordInvoice.getId().toString());
                        vo.setInvoiceType(tDxRecordInvoice.getInvoiceType());
                        vo.setInvoiceAmount(MathUtil.round(tDxRecordInvoice.getInvoiceAmount().toPlainString()));
                        vo.setSettlementNo(tDxRecordInvoice.getSettlementNo());
                        vo.setSettleSource(tDxRecordInvoice.getSettleSource());
                        // 获取税款所属期起止时间
                        QueryWrapper<BaseTDxTaxCurrent> currentWrapper = new QueryWrapper<>();
                        currentWrapper.eq("taxno", tDxRecordInvoice.getGfTaxNo());
                        BaseTDxTaxCurrent current = baseTDxTaxCurrentDao.selectOne(currentWrapper);

                        if (current != null && current.getCurrentTaxPeriod() != null) {
                            vo.setDqskssq(current.getCurrentTaxPeriod());
                        } else {
                            vo.setBkgxts("无该发票税号属期信息");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }

                        if (tDxRecordInvoice.getQsDate() != null) {
                            vo.setQsDate(sdf.format(tDxRecordInvoice.getQsDate()));
                        }
                        if (tDxRecordInvoice.getQsStatus() != null) {
                            if (tDxRecordInvoice.getQsStatus().equals(FpqsjgEnum.WQS.getQsjgDm())) {
                                vo.setQsStatus(FpqsjgEnum.WQS.getQsjgMc(FpqsjgEnum.WQS.getIndex()));
                            } else {
                                vo.setQsStatus(FpqsjgEnum.YQS.getQsjgMc(FpqsjgEnum.YQS.getIndex()));
                            }
                        }
                        if (tDxRecordInvoice.getQsType() != null) {
                            for (QsfsEnum e : QsfsEnum.values()) {
                                if (tDxRecordInvoice.getQsType().equals(e.getQsfsDm())) {
                                    vo.setQsType(e.getQsfsMc(e.getIndex()));
                                }
                            }
                        }
                        vo.setQsName(tDxRecordInvoice.getQsName());
                        if (tDxRecordInvoice.getInvoiceDate() != null) {
                            vo.setInvoiceDate(sdf.format(tDxRecordInvoice.getInvoiceDate()));
                        }
                        // 设置不可勾选提示:"失控","作废","红冲","异常"等
                        if (current == null) {
                            vo.setBkgxts("企业属期表无该税号数据");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }

                        Map<String, Object> curMap = new HashMap<>();
                        List<String> shList = new ArrayList<>();
                        shList.add(tDxRecordInvoice.getGfTaxNo());
                        curMap.put("gfsh", shList);
                        List<BaseTDxDkCount> curList = baseTDxRecordInvoiceDao.selectDksh(curMap);
                        BaseTDxDkCount cur = curList.get(0);
                        String skssq = cur.getSkssq();
                        String year = skssq.substring(0, 4);
                        String mon = skssq.substring(4);
                        LocalDate localDate = LocalDate.of(Integer.parseInt(year), Integer.parseInt(mon), 1);
                        LocalDate localDate1 = localDate.plusMonths(1);
                        LocalDate localDate2 = LocalDate.now();
                        if (!"0".equals(cur.getTjStatus()) && !"3".equals(cur.getTjStatus())
                            && !localDate2.isBefore(localDate1)) {
                            vo.setBkgxts("该发票的购方税号已申请抵扣统计");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }

                        boolean krz = InvoiceTypeUtils.isKrz(tDxRecordInvoice.getInvoiceType(), tDxRecordInvoice.getLqTdyslxdm());
                        if(!krz){
                            vo.setBkgxts("发票类型有误");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        String invoiceStatus="07";
                        if ( !invoiceStatus.contains(tDxRecordInvoice.getInvoiceStatus())){
                            for (FpztEnum e : FpztEnum.values()) {
                                if (tDxRecordInvoice.getInvoiceStatus().equals(e.getFpztDm())) {
                                    vo.setBkgxts(e.getFpztMc(e.getIndex()) + "发票");
                                    vo.setSelect(false);
                                    voList.add(vo);
                                    fail = fail + 1;
                                }
                            }
                            continue;
                        }
                        if (tDxRecordInvoice.getInvoiceAmount().compareTo(BigDecimal.ZERO) < 0) {
                            vo.setBkgxts("金额小于0");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        if (tDxRecordInvoice.getTaxAmount().compareTo(BigDecimal.ZERO) < 0) {
                            vo.setBkgxts("税额小于0");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        if (!StringHelper.isBlank(tDxRecordInvoice.getBdkStatus())) {
                            if ("2".equals(tDxRecordInvoice.getBdkStatus())
                                && "1234".contains(tDxRecordInvoice.getAuthStatus())) {
                                vo.setBkgxts("该发票已认证不抵扣");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                            if ("3".equals(tDxRecordInvoice.getBdkStatus())
                                && "1234".contains(tDxRecordInvoice.getAuthStatus())) {
                                vo.setBkgxts("该发票已做退税认证");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                        }
                        if ("1".equals(current.getLatchStatus())) {
                            vo.setBkgxts("该发票的购方税号已锁定");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        if (!StringHelper.isBlank(tDxRecordInvoice.getAuthStatus())
                            && !StringHelper.isBlank(tDxRecordInvoice.getRzhYesorno())) {
                            if ("1".equals(tDxRecordInvoice.getRzhYesorno())
                                && "4".equals(tDxRecordInvoice.getAuthStatus())) {
                                vo.setBkgxts("该发票已认证抵扣");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                        }

                        if ("1".equals(tDxRecordInvoice.getBdkStatus())) {
                            if ("1".equals(tDxRecordInvoice.getAuthStatus())) {
                                vo.setBkgxts("该发票已勾选");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                            if ("2".equals(tDxRecordInvoice.getAuthStatus())) {
                                vo.setBkgxts("该发票已勾选确认");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                            if ("3".equals(tDxRecordInvoice.getAuthStatus())) {
                                vo.setBkgxts("该发票认证中");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                        }
                        if ("1".equals(tDxRecordInvoice.getExportMark())) {
                            vo.setBkgxts("该发票为出口转内销发票");
                            vo.setSelect(false);
                            voList.add(vo);
                            fail = fail + 1;
                            continue;
                        }
                        if (StringUtils.isNotBlank(current.getSelectStartDate())) {
                            if (tDxRecordInvoice.getInvoiceDate()
                                .compareTo(new SimpleDateFormat("yyyyMMdd").parse(current.getSelectStartDate())) < 0) {
                                vo.setBkgxts("发票逾期");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                        }
                        if (StringUtils.isNotBlank(current.getSelectEndDate())) {
                            if (tDxRecordInvoice.getInvoiceDate()
                                .compareTo(new SimpleDateFormat("yyyyMMdd").parse(current.getSelectEndDate())) > 0) {
                                vo.setBkgxts("发票未到期");
                                vo.setSelect(false);
                                voList.add(vo);
                                fail = fail + 1;
                                continue;
                            }
                        }
                        voList.add(vo);
                        sucess = sucess + 1;
                    } else {
                        // BaseInvoiceImportCheckRespVO vo = new BaseInvoiceImportCheckRespVO();
                        vo.setBkgxts("无抵账信息");
                        vo.setSelect(false);
                        vo.setXh(String.valueOf(i + 1));
                        vo.setTaxAmount(listReqVo.get(i).getTaxAmount() != null
                            ? MathUtil.round(listReqVo.get(i).getTaxAmount()) : "");
//                        vo.setInvoiceCode(listReqVo.get(i).getInvoiceCode());
//                        vo.setInvoiceNo(listReqVo.get(i).getInvoiceNo());
                        vo.setInvoiceDate(listReqVo.get(i).getInvoiceDate());
                        vo.setDkTaxAmount(listReqVo.get(i).getDkTaxAmount() != null
                            ? MathUtil.round(listReqVo.get(i).getDkTaxAmount()) : "");
                        voList.add(vo);
                        fail = fail + 1;
                    }

                }

            }
            // 设置总条数
            json.put("total", listReqVo.size());
            // 成功导入条数
            json.put("succtoal", sucess);
            // 导入失败条数
            json.put("failtotal", fail);
            json.put("datalist", voList);
        } catch (Exception e) {
            // 统一设置操作异常标识
            json = super.errorResult(e);
        }

        return super.responseResult(json);
    }

}
