package com.dxhy.base.service.tdxrecordinvoice;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import com.dxhy.base.utils.InvoiceTypeUtils;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.common.util.StringHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.base.dao.BaseFpdrrzDao;
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.BaseFpdrrzRespVO;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FpqsjgEnum;
import com.dxhy.common.enums.QsfsEnum;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.InvoiceUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.utils.DateUtils;

/**
 * @author ld
 */
@SuppressWarnings({"AlibabaMethodTooLong", "AlibabaCollectionInitShouldAssignCapacity",
    "AlibabaLowerCamelCaseVariableNaming"})
@Service("baseIFpdrrzService")
public class BaseFpdrrzServiceImpl extends MpBaseServiceImpl<BaseFpdrrzDao, BaseFpdrrzRespVO>
    implements BaseIFpdrrzService {
    @Resource
    private BaseTDxRecordInvoiceDao baseTDxRecordInvoiceDao;
    @Resource
    private BaseTDxTaxCurrentDao baseTDxTaxCurrentDao;
    @Resource
    private TabulateRedisService tabulateRedisService;
    private static final Pattern PATTERN_DATE = 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)$");
    private static final Pattern PATTERN_AMOUNT = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");

    @Override
    public String selectByDrrzCxtj(Map<String, Object> pramsMap) {

        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
        // 需要设置返回列表标题时调用
        String qsflag = (String)pramsMap.get("qsflag");
//        String[] arr = {"01", "03", "08", "14"};
//        Arrays.sort(arr);
        List<Object> returnList = new ArrayList<>();
        String datalist = (String)pramsMap.get("datalist");
        List<String> list = (List<String>)pramsMap.get("gfsh");
        JSONObject listjson = JSONObject.parseObject(datalist);
        // 首先把字符串转成 JSONArray 对象
        JSONArray jsonArray = JSONArray.parseArray(listjson.getString("datalist"));
        String company = listjson.getString("company");
        String menuId = listjson.getString("menuId");
        JSONObject json = tabulateRedisService.getTabulateMenu(company, menuId);

        int cgsl = 0;
        int sbsl = 0;
        List<String> uuidList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String fpdm = jsonObject.getString("invoiceCode");
            String fphm = jsonObject.getString("invoiceNo");
            String kprq = jsonObject.getString("invoiceDate");
            String se = jsonObject.getString("taxAmount");
            String dkse1 = jsonObject.getString("taxAmount");
            BaseFpdrrzRespVO rzlb = new BaseFpdrrzRespVO();
            rzlb.setSelect(true);
            rzlb.setXh(String.valueOf(i + 1));
            rzlb.setBkrzts("");
            rzlb.setFpdm(fpdm);
            rzlb.setFphm(fphm);
            rzlb.setDkse(dkse1);
            if (fphm.length() == 20) {
                rzlb.setFpdm(fphm.substring(0, 12));
                rzlb.setFphm(fphm.substring(12, 20));
                rzlb.setEleInvoiceNo(fphm);
            }
            rzlb.setKprq(kprq);
            rzlb.setSe(se);
            if (StringUtils.isBlank(kprq)) {
                rzlb.setBkrzts("开票日期不能为空");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                sbsl = sbsl + 1;
                continue;
            } else {
                // 判断日期 yyyy-mm-dd 的正则表达式（能够区分真实日期，区分闰年）
                Matcher match = PATTERN_DATE.matcher(kprq);
                if (!match.matches()) {
                    rzlb.setBkrzts("开票日期格式错误");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
            }
            if (StringUtils.isBlank(se)) {
                rzlb.setBkrzts("税额不能为空");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                sbsl = sbsl + 1;
                continue;
            } else {
                // 判断小数点后2位的数字的正则表达式
                Matcher match = PATTERN_AMOUNT.matcher(se);
                if (!match.matches()) {
                    rzlb.setBkrzts("税额格式错误");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                se = MathUtil.round(se);
                rzlb.setSe(AmountFormatUtil.fmtMicrometer(se));
            }
            if (uuidList.contains(fpdm + fphm)) {
                rzlb.setBkrzts("重复发票");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                sbsl = sbsl + 1;
                continue;
            } else {
                uuidList.add(fpdm + fphm);
            }
            String fpdms = StringHelper.isBlank(fpdm) ? "" : fpdm;
            String uuid = fpdms + fphm;
            QueryWrapper<BaseTDxRecordInvoice> queryRecord = new QueryWrapper<>();
            queryRecord.eq("uuid", uuid);
            BaseTDxRecordInvoice rdxRecordInvoice = baseTDxRecordInvoiceDao.selectOne(queryRecord);
            if (rdxRecordInvoice.getDkTaxAmount() != null && StringUtils.isNotBlank(rdxRecordInvoice.getDkTaxAmount().toPlainString())){
                rzlb.setDkse(rdxRecordInvoice.getDkTaxAmount().toPlainString());
            }
            if (rdxRecordInvoice != null) {
                if (list == null || list.size() == 0 || !list.contains(rdxRecordInvoice.getGfTaxNo())) {
                    rzlb.setBkrzts("无该发票购方税号权限");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                rzlb.setInvoiceType(rdxRecordInvoice.getInvoiceType());
                if(StringUtils.isNotBlank(rdxRecordInvoice.getEleInvoiceNo())){
                    rzlb.setEleInvoiceNo(rdxRecordInvoice.getEleInvoiceNo());
                }
                if (rdxRecordInvoice.getDkTaxAmount() != null) {
                    String dkse = rdxRecordInvoice.getDkTaxAmount().toPlainString();
                    if (Double.parseDouble(se) < Double.parseDouble(dkse)) {
                        rzlb.setBkrzts("抵扣税额应小于等于税额");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    }
                    rzlb.setDkse(MathUtil.round(rdxRecordInvoice.getDkTaxAmount().toPlainString()));
                }
                rzlb.setGfmc(rdxRecordInvoice.getGfName());
                rzlb.setQsr(rdxRecordInvoice.getQsName());
                if (rdxRecordInvoice.getQsDate() != null) {
                    rzlb.setQsrq(DateUtils.dateToStr(rdxRecordInvoice.getQsDate()));
                }
                if (rdxRecordInvoice.getQsStatus() != null) {
                    if (rdxRecordInvoice.getQsStatus().equals(FpqsjgEnum.WQS.getQsjgDm())) {
                        rzlb.setQszt(FpqsjgEnum.WQS.getQsjgMc(FpqsjgEnum.WQS.getIndex()));
                    } else {
                        rzlb.setQszt(FpqsjgEnum.YQS.getQsjgMc(FpqsjgEnum.YQS.getIndex()));
                    }
                }
                if (rdxRecordInvoice.getQsType() != null) {
                    for (QsfsEnum e : QsfsEnum.values()) {
                        if (rdxRecordInvoice.getQsType().equals(e.getQsfsDm())) {
                            rzlb.setQsfs(e.getQsfsMc(e.getIndex()));
                        }
                    }
                }
                if ("1".equals(qsflag) && !"1".equals(rdxRecordInvoice.getQsStatus())) {
                    rzlb.setBkrzts("该发票未签收");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                Map<String, Object> curMap = new HashMap<>();
                List<String> gfshList = new ArrayList<>();
                gfshList.add(rdxRecordInvoice.getGfTaxNo());
                curMap.put("gfsh", gfshList);
                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)) {
                    rzlb.setBkrzts("该发票的购方税号已申请抵扣统计");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String invoiceDate = sdf.format(rdxRecordInvoice.getInvoiceDate());
                if (!kprq.equals(invoiceDate)) {
                    rzlb.setBkrzts("开票日期与底账数据不一致");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                if (!se.equals(rdxRecordInvoice.getTaxAmount().setScale(2, BigDecimal.ROUND_DOWN).toPlainString())) {
                    rzlb.setBkrzts("税额与底账数据不一致");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                QueryWrapper<BaseTDxTaxCurrent> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("taxno", rdxRecordInvoice.getGfTaxNo());
                BaseTDxTaxCurrent current = baseTDxTaxCurrentDao.selectOne(queryWrapper);
                if (current != null && current.getCurrentTaxPeriod() != null) {
                    rzlb.setDqskssq(current.getCurrentTaxPeriod());
                } else {
                    rzlb.setBkrzts("无该发票税号属期信息");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                boolean krz = InvoiceTypeUtils.isKrz( rdxRecordInvoice.getInvoiceType(), rdxRecordInvoice.getLqTdyslxdm());
                if(!krz){
                    rzlb.setBkrzts("发票类型有误");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
//                if ("1".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                    rzlb.setBkrzts("失控发票");
//                    rzlb.setSelect(false);
//                    returnList.add(rzlb);
//                    sbsl = sbsl + 1;
//                    continue;
//                } else if ("2".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                    rzlb.setBkrzts("作废发票");
//                    rzlb.setSelect(false);
//                    returnList.add(rzlb);
//                    sbsl = sbsl + 1;
//                    continue;
//                } else if ("3".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                    rzlb.setBkrzts("红冲发票");
//                    rzlb.setSelect(false);
//                    returnList.add(rzlb);
//                    sbsl = sbsl + 1;
//                    continue;
//                } else if ("4".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                    rzlb.setBkrzts("异常发票");
//                    rzlb.setSelect(false);
//                    returnList.add(rzlb);
//                    sbsl = sbsl + 1;
//                    continue;
//                }
                String invoiceStatus = "07";
                if (!invoiceStatus.contains(rdxRecordInvoice.getInvoiceStatus())) {
                    for (FpztEnum e : FpztEnum.values()) {
                        if (rdxRecordInvoice.getInvoiceStatus().equals(e.getFpztDm())) {
                            rzlb.setBkrzts(e.getFpztMc(e.getIndex()) + "发票");
                            rzlb.setSelect(false);
                            returnList.add(rzlb);
                            sbsl = sbsl + 1;
                        }
                    }
                    continue;
                }
                if ("1".equals(rdxRecordInvoice.getRzhYesorno())) {
                    rzlb.setBkrzts("该发票已认证抵扣");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                if (current.getSelectStartDate() != null && rdxRecordInvoice.getInvoiceDate() != null) {
                    if (rdxRecordInvoice.getInvoiceDate()
                        .compareTo(DateUtils.strToDatePeriod(current.getSelectStartDate())) < 0) {
                        rzlb.setBkrzts("发票逾期");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    }
                }
                if (StringUtils.isNotBlank(current.getSelectEndDate())) {
                    if (rdxRecordInvoice.getInvoiceDate()
                        .compareTo(DateUtils.strToDatePeriod(current.getSelectEndDate())) > 0) {
                        rzlb.setBkrzts("发票未到期");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    }
                }
                if ("1".equals(current.getLatchStatus())) {
                    rzlb.setBkrzts("该发票的购方税号已锁定");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                if ("1".equals(rdxRecordInvoice.getBdkStatus())) {
                    if ("1".equals(rdxRecordInvoice.getAuthStatus())) {
                        rzlb.setBkrzts("该发票已勾选未确认");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    } else if ("2".equals(rdxRecordInvoice.getAuthStatus())) {
                        rzlb.setBkrzts("该发票已确认");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    } else if ("3".equals(rdxRecordInvoice.getAuthStatus())) {
                        rzlb.setBkrzts("该发票已发送认证");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    } else if ("4".equals(rdxRecordInvoice.getAuthStatus())) {
                        rzlb.setBkrzts("该发票已认证抵扣");
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        sbsl = sbsl + 1;
                        continue;
                    }
                }

                if ("2".equals(rdxRecordInvoice.getBdkStatus()) && "1234".contains(rdxRecordInvoice.getAuthStatus())) {
                    rzlb.setBkrzts("该发票已认证不抵扣");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                if ("3".equals(rdxRecordInvoice.getBdkStatus()) && "1234".contains(rdxRecordInvoice.getAuthStatus())) {
                    rzlb.setBkrzts("该发票已做退税认证");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                if ("1".equals(rdxRecordInvoice.getExportMark())) {
                    rzlb.setBkrzts("该发票为出口转内销发票");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    sbsl = sbsl + 1;
                    continue;
                }
                returnList.add(rzlb);
                cgsl = cgsl + 1;
            } else {
                rzlb.setBkrzts("无底账信息");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                sbsl = sbsl + 1;
            }

        }
        json.put("cgsl", cgsl);
        json.put("sbsl", sbsl);
        json.put("datalist", returnList);

        return super.responseResult(json);
    }

}
