package com.dxhy.base.service.tdxrecordinvoice;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.api.model.config.Tax;
import com.dxhy.base.dao.BaseFprzDao;
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.BaseFpsmrzRespVO;
import com.dxhy.base.utils.InvoiceTypeUtils;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
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;

/**
 *
 *
 * 发票扫码认证业务实现类
 *
 * @author zhanghong
 *
 *
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong", "AlibabaLowerCamelCaseVariableNaming",
    "AlibabaCollectionInitShouldAssignCapacity"})
@Service("baseIFpsmrzService")
public class BaseFpsmrzServiceImpl extends MpBaseServiceImpl<BaseFprzDao, BaseFpsmrzRespVO>
    implements BaseIFpsmrzService {
    @Resource
    private BaseTDxRecordInvoiceDao baseTDxRecordInvoiceDao;

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

    @Override
    public String selectBySmrzCxtj(Map<String, Object> pramsMap) {
        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
        // 需要设置返回列表标题时调用
        String company = (String)pramsMap.get("company");
        String menuId = (String)pramsMap.get("menuId");
        JSONObject json = tabulateRedisService.getTabulateMenu(company, menuId);
        QueryWrapper<BaseTDxRecordInvoice> queryWrapper = new QueryWrapper<>();
        String fpdm = (String)pramsMap.get("fpdm");
        String fphm = (String)pramsMap.get("fphm");
        String uuid = (StringUtils.isBlank(fpdm)?"":fpdm) + (String)pramsMap.get("fphm");
        queryWrapper.eq("uuid", uuid);
        BaseTDxRecordInvoice rdxRecordInvoice = baseTDxRecordInvoiceDao.selectOne(queryWrapper);
        String qsflag = (String)pramsMap.get("qsflag");
        List<Object> returnList = new ArrayList<>();
        String invoiceType = (String)pramsMap.get("invoiceType");
        BaseFpsmrzRespVO rzlb;
        if (rdxRecordInvoice != null) {
            rzlb = this.convertToRzlbView(rdxRecordInvoice);
            rzlb.setSelect(true);
            rzlb.setFpdm(rdxRecordInvoice.getInvoiceCode());
            rzlb.setFphm(rdxRecordInvoice.getInvoiceNo());
            rzlb.setEleInvoiceNo(rdxRecordInvoice.getEleInvoiceNo());
            String kprq = (String)pramsMap.get("kprq");
            String selInvoiceType = rdxRecordInvoice.getInvoiceType();
            String je = (String)pramsMap.get("je");
            if(ObjectUtil.isNotEmpty(rdxRecordInvoice.getTaxAmount())){
                rzlb.setSe(AmountFormatUtil
                        .fmtMicrometer(MathUtil.round(rdxRecordInvoice.getTaxAmount().toPlainString())));
            }
            if(ObjectUtil.isNotEmpty(rdxRecordInvoice.getTotalAmount())){
                rzlb.setJshj(AmountFormatUtil
                        .fmtMicrometer(MathUtil.round(rdxRecordInvoice.getTotalAmount().toPlainString())));
            }
            String jym = (String)pramsMap.get("jym");
            rzlb.setKprq(kprq);

            rzlb.setJym(jym);
            rzlb.setInvoiceType(rdxRecordInvoice.getInvoiceType());
            boolean krz = InvoiceTypeUtils.isKrz(rdxRecordInvoice.getInvoiceType(), rdxRecordInvoice.getLqTdyslxdm());
            if (!krz&&!"2".equals(rdxRecordInvoice.getYwlx())) {
                rzlb.setBkrzts("发票类型有误");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            List<String> list = (List<String>)pramsMap.get("gfsh");
            List<Tax> taxList = (List<Tax>)pramsMap.get("taxList");
            List<String> taxnoList = new ArrayList<>();
            if (taxList != null && taxList.size() > 0) {
                for (Tax tax : taxList) {
                    String upgradeStatus = tax.getUpgradeStatus();
                    if ("1".equals(upgradeStatus)) {
                        taxnoList.add(tax.getTaxno());
                    }
                }
            }
            if (taxnoList.contains(rdxRecordInvoice.getGfTaxNo())) {
                rzlb.setUpgradeStatus("1");
                if (rdxRecordInvoice.getDkTaxAmount() == null) {
                    if(ObjectUtil.isNotEmpty(rdxRecordInvoice.getTaxAmount())){
                        rzlb.setDkse(MathUtil.round(rdxRecordInvoice.getTaxAmount().toPlainString()));
                    }
                } else {
                    if(ObjectUtil.isNotEmpty(rdxRecordInvoice.getDkTaxAmount())){
                        rzlb.setDkse(MathUtil.round(rdxRecordInvoice.getDkTaxAmount().toPlainString()));
                    }
                }
            } else {
                rzlb.setUpgradeStatus("0");
                if (rdxRecordInvoice.getDkTaxAmount() == null) {
                    rzlb.setDkse(AmountFormatUtil
                        .fmtMicrometer(MathUtil.round(rdxRecordInvoice.getTaxAmount().toPlainString())));
                } else {
                    rzlb.setDkse(AmountFormatUtil
                        .fmtMicrometer(MathUtil.round(rdxRecordInvoice.getDkTaxAmount().toPlainString())));
                }
            }
            QueryWrapper<BaseTDxTaxCurrent> queryCurrent = new QueryWrapper<>();
            queryCurrent.eq("taxno", rdxRecordInvoice.getGfTaxNo());

            BaseTDxTaxCurrent current = baseTDxTaxCurrentDao.selectOne(queryCurrent);
            if (list == null || !list.contains(rdxRecordInvoice.getGfTaxNo())) {
                rzlb.setBkrzts("无该发票购方税号权限");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            if (current != null && current.getCurrentTaxPeriod() != null) {
                rzlb.setDqskssq(current.getCurrentTaxPeriod());
            } else {
                rzlb.setBkrzts("无该发票税号属期信息");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            if ("1".equals(qsflag) && !"1".equals(rdxRecordInvoice.getQsStatus())) {
                rzlb.setBkrzts("该发票未签收");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            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);
            for (BaseTDxDkCount cur : curList) {
                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);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                }
            }

            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);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            //如果是代扣代缴，不验证以下信息
            if(!"4".equals(rdxRecordInvoice.getXxly())){
                if (StringUtils.isNotBlank(je)) {
                    je = MathUtil.round(je);
                    BigDecimal recordMoney;
                    if(StringUtils.isNotBlank(fphm)&&fphm.length()==20){
                        recordMoney = rdxRecordInvoice.getTotalAmount();
                    }else{
                        recordMoney = rdxRecordInvoice.getInvoiceAmount();
                    }
                    if (!je.equals(recordMoney.setScale(2, BigDecimal.ROUND_DOWN).toPlainString())) {
                        if(StringUtils.isNotBlank(fphm)&&fphm.length()==20){
                            rzlb.setBkrzts("价税合计与底账数据不一致");
                        }else{
                            rzlb.setBkrzts("金额与底账数据不一致");
                        }
                        rzlb.setSelect(false);
                        returnList.add(rzlb);
                        json.put("datalist", returnList);
                        return super.responseResult(json);
                    }
                    rzlb.setJe(AmountFormatUtil.fmtMicrometer(MathUtil.round(je)));
                    //如果是20位。je这个值就是价税合计。重新赋值金额展示给前端
                    if(StringUtils.isNotBlank(fphm)&&fphm.length()==20){
                        rzlb.setJe(AmountFormatUtil.fmtMicrometer(MathUtil.round(rdxRecordInvoice.getInvoiceAmount().toPlainString())));
                    }
                } else {
                    rzlb.setJe(AmountFormatUtil
                            .fmtMicrometer(MathUtil.round(rdxRecordInvoice.getInvoiceAmount().toPlainString())));
                }
            }

            if (StringUtils.isNotBlank(jym)) {
                if (jym.equals(rdxRecordInvoice.getCheckCode())) {
                    rzlb.setJym(rdxRecordInvoice.getCheckCode());
                }
            }

//            if ("1".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                rzlb.setBkrzts("失控发票");
//                rzlb.setSelect(false);
//                returnList.add(rzlb);
//                json.put("datalist", returnList);
//                return super.responseResult(json);
//            } else if ("2".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                rzlb.setBkrzts("作废发票");
//                rzlb.setSelect(false);
//                returnList.add(rzlb);
//                json.put("datalist", returnList);
//                return super.responseResult(json);
//            } else if ("3".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                rzlb.setBkrzts("红冲发票");
//                rzlb.setSelect(false);
//                returnList.add(rzlb);
//                json.put("datalist", returnList);
//                return super.responseResult(json);
//            } else if ("4".equals(rdxRecordInvoice.getInvoiceStatus())) {
//                rzlb.setBkrzts("异常发票");
//                rzlb.setSelect(false);
//                returnList.add(rzlb);
//                json.put("datalist", returnList);
//                return super.responseResult(json);
//            }
            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);
                        json.put("datalist", returnList);
                        return super.responseResult(json);
                    }
                }
            }
            if ("1".equals(rdxRecordInvoice.getRzhYesorno())) {
                rzlb.setBkrzts("该发票已认证抵扣");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            if (current.getSelectStartDate() != null && rdxRecordInvoice.getInvoiceDate() != null) {
                if (rdxRecordInvoice.getInvoiceDate()
                    .compareTo(DateUtils.strToDatePeriod(current.getSelectStartDate())) < 0) {
                    rzlb.setBkrzts("发票逾期");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                }
            }
            if (StringUtils.isNotBlank(current.getSelectEndDate())) {
                if (rdxRecordInvoice.getInvoiceDate()
                    .compareTo(DateUtils.strToDatePeriodFormate(current.getSelectEndDate()+"235959","yyyyMMddHHmmss")) > 0) {
                    rzlb.setBkrzts("发票未到期");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                }
            }
            if ("1".equals(current.getLatchStatus())) {
                rzlb.setBkrzts("该发票购方税号已锁定");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            if ("1".equals(rdxRecordInvoice.getBdkStatus())) {
                if ("1".equals(rdxRecordInvoice.getAuthStatus())) {
                    rzlb.setBkrzts("该发票已勾选未确认");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                } else if ("2".equals(rdxRecordInvoice.getAuthStatus())) {
                    rzlb.setBkrzts("该发票已确认");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                } else if ("3".equals(rdxRecordInvoice.getAuthStatus())) {
                    rzlb.setBkrzts("该发票已发送认证");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                } else if ("4".equals(rdxRecordInvoice.getAuthStatus())) {
                    rzlb.setBkrzts("该发票已认证抵扣");
                    rzlb.setSelect(false);
                    returnList.add(rzlb);
                    json.put("datalist", returnList);
                    return super.responseResult(json);
                }
            }

            if ("2".equals(rdxRecordInvoice.getBdkStatus()) && "1234".contains(rdxRecordInvoice.getAuthStatus())) {
                rzlb.setBkrzts("已认证不抵扣");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            if ("3".equals(rdxRecordInvoice.getBdkStatus()) && "1234".contains(rdxRecordInvoice.getAuthStatus())) {
                rzlb.setBkrzts("已做退税认证");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }
            if ("1".equals(rdxRecordInvoice.getExportMark())) {
                rzlb.setBkrzts("该发票为出口转内销发票");
                rzlb.setSelect(false);
                returnList.add(rzlb);
                json.put("datalist", returnList);
                return super.responseResult(json);
            }

        } else {
            rzlb = new BaseFpsmrzRespVO();
            rzlb.setFpdm(ObjectUtil.isEmpty(pramsMap.get("fpdm"))?"":pramsMap.get("fpdm").toString());
            rzlb.setFphm(pramsMap.get("fphm").toString());
            rzlb.setKprq(pramsMap.get("kprq").toString());
            if(pramsMap.get("fphm").toString().length()==20){
                rzlb.setJshj(pramsMap.get("je") != null ? MathUtil.round(pramsMap.get("je").toString()) : "");
            }else{
                rzlb.setJe(pramsMap.get("je") != null ? MathUtil.round(pramsMap.get("je").toString()) : "");
            }
            rzlb.setJym(pramsMap.get("jym") != null ? pramsMap.get("jym").toString() : "");
            rzlb.setBkrzts("无底账信息");
            rzlb.setSelect(false);
            rzlb.setUpgradeStatus("0");
            rzlb.setInvoiceType(invoiceType);
        }
        returnList.add(rzlb);
        json.put("datalist", returnList);
        return super.responseResult(json);

    }

    /**
     * 转换结果数据为页面可展示表格
     *
     * @param ri
     *            待转换对象
     * @return 返回结果
     * 
     */
    private BaseFpsmrzRespVO convertToRzlbView(BaseTDxRecordInvoice ri) {
        BaseFpsmrzRespVO rzlb = new BaseFpsmrzRespVO();
        rzlb.setId(ri.getId() + "");

        rzlb.setXh(String.valueOf(1));
        rzlb.setBkrzts("");
        if (StringUtils.isNotBlank(ri.getCheckCode()) && ri.getCheckCode().length() > 6) {
            rzlb.setJym(ri.getCheckCode().substring(ri.getCheckCode().length() - 6));
        }
        if(ObjectUtil.isNotEmpty(ri.getTaxAmount())){
            rzlb.setSe(AmountFormatUtil.fmtMicrometer(MathUtil.round(ri.getTaxAmount().toPlainString())));
        }

        if (ri.getDkTaxAmount() == null) {
            if(ObjectUtil.isNotEmpty(ri.getTaxAmount())){
                rzlb.setDkse(MathUtil.round(ri.getTaxAmount().toPlainString()));
            }
        } else {
            if(ObjectUtil.isNotEmpty(ri.getDkTaxAmount())){
                rzlb.setDkse(MathUtil.round(ri.getDkTaxAmount().toPlainString()));
            }
        }
        return rzlb;
    }

}
