package com.dxhy.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

import com.dxhy.common.enums.FplxEnum;
import org.apache.commons.lang3.StringUtils;

/**
 * 发票信息校验处理类
 *
 * @author Administrator 2016-8-18 @version(版本)1.0
 *
 *
 *
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaAvoidComplexCondition"})
public class InvoiceUtil {

    /**
     * 电子发票号段
     */
    public static final String HD =
        "111001571071,111001571072,131001570151,133011501118,133020691510,133021591000,134021522401,144031539110";

    /**
     * 是否10位数字
     */
    private static final Pattern FPDM10_PATTERN = Pattern.compile("\\d{10}");

    /**
     * 是否12位数字
     */
    private static final Pattern FPDM12_PATTERN = Pattern.compile("\\d{12}");

    /**
     * 是否8位数字
     */
    private static final Pattern FPHM8_PATTERN = Pattern.compile("\\d{8}");

    /**
     * 是否10位数字
     */
    private static final Pattern FPHM10_PATTERN = Pattern.compile("\\d{10}");

    /**
     * 是否保留2位小数的钱数
     */
    private static final Pattern MONEY_PATTERN = Pattern.compile(
        "(^(([1-9]+\\d*)|(0{1}))(\\.\\d{1,2})?$)|(^-([1-9]+\\d*(\\.\\d{1,2})?|0\\.(0[1-9]{1}|[1-9]{1}\\d?))$)");

    /**
     * 发票类型代码
     */
    private static String fplxdm;

    /**
     * 发票类型名称
     */
    private static String fplxmc;

    /**
     * 发票代码
     */
    private String fpdm;

    /**
     * 发票号码
     */
    private String fphm;

    /**
     * 开票日期
     */
    private String kprq;

    /**
     * 金额
     */
    private String je;

    /**
     * 税额
     */
    private String se;

    /**
     * 校验码
     */
    private String jym;

    public InvoiceUtil() {}

    /**
     *
     * 根据发票代码判断发票类型 判断通行费发票时，需要传入特殊票种标识
     *
     * @param fpdm
     *            发票代码
     *
     */
    public InvoiceUtil(String fpdm) {
        if (fpdm != null && fpdm.length() >= 10) {
            this.fpdm = fpdm;
            this.getFplx(fpdm);
        }
    }

    /**
     * 根据发票代码获取发票类型
     *
     * @param fpdm
     *            发票代码
     *
     *             1、 电子发票
     *            特殊的发票代码包括：'144031539110', '131001570151', '133011501118', '111001571071'，如果发票代码为以上代码之一，则判定为电子发票。
     *            代码长度为12位，首位为0，最后两位为11。 2、 通行费发票 代码长度为12位，首位为0，最后两位是12。 3、 增值税普通发票 代码长度为12位，首位为0，最后两位是04或05；
     *            代码长度为10位，第8位是3或者6。 4、 卷式发票 代码长度为12位，首位为0，最后两位是06或07； 5、 机动车发票 代码长度为12位，首位不是0，第8位是2 6、 增值税专用发票
     *            代码长度为10位，第8位为1或5。 7、 货物运输发票 代码长度为10位，第8位为2或7 8、 二手车发票 代码长度为12位，首位为0，最后两位是17
     */
    private void getFplx(String fpdm) {

        String invoiceTypeCode;

        invoiceTypeCode = fpdm.substring(7, 8);

        if (fpdm.length() == 12) {
            if (HD.contains(fpdm)) {
                fplxdm = FplxEnum.DZP.getFplxDm();
                fplxmc = FplxEnum.DZP.getFplxMc(FplxEnum.DZP.getIndex());
            } else if ("0".equals(fpdm.substring(0, 1)) && "11".equals(fpdm.substring(10, 12))) {
                fplxdm = FplxEnum.DZP.getFplxDm();
                fplxmc = FplxEnum.DZP.getFplxMc(FplxEnum.DZP.getIndex());
            } else if ("0".equals(fpdm.substring(0, 1)) && "12".equals(fpdm.substring(10, 12))) {
                fplxdm = FplxEnum.TXF.getFplxDm();
                fplxmc = FplxEnum.TXF.getFplxMc(FplxEnum.TXF.getIndex());
            } else if (!"0".equals(fpdm.substring(0, 1)) && "2".equals(invoiceTypeCode)) {
                fplxdm = FplxEnum.JDC.getFplxDm();
                fplxmc = FplxEnum.JDC.getFplxMc(FplxEnum.JDC.getIndex());
            } else if ("0".equals(fpdm.substring(0, 1))
                && ("06".equals(fpdm.substring(10, 12)) || "07".equals(fpdm.substring(10, 12)))) {
                fplxdm = FplxEnum.JSP.getFplxDm();
                fplxmc = FplxEnum.JSP.getFplxMc(FplxEnum.JSP.getIndex());
            } else if ("0".equals(fpdm.substring(0, 1))
                && ("04".equals(fpdm.substring(10, 12)) || "05".equals(fpdm.substring(10, 12)))) {
                fplxdm = FplxEnum.PP.getFplxDm();
                fplxmc = FplxEnum.PP.getFplxMc(FplxEnum.PP.getIndex());
            } else if ("0".equals(fpdm.substring(0, 1)) && "17".equals(fpdm.substring(10, 12))) {
                fplxdm = FplxEnum.ESC.getFplxDm();
                fplxmc = FplxEnum.ESC.getFplxMc(FplxEnum.ESC.getIndex());
            } else if ("0".equals(fpdm.substring(0, 1)) && "13".equals(fpdm.substring(10, 12))) {
                fplxdm = FplxEnum.DZZP.getFplxDm();
                fplxmc = FplxEnum.DZZP.getFplxMc(FplxEnum.DZZP.getIndex());
            } else {
                fplxdm = null;
            }
        } else if (fpdm.length() == 10) {
            if ("1".equals(invoiceTypeCode) || "5".equals(invoiceTypeCode)) {
                fplxdm = FplxEnum.ZP.getFplxDm();
                fplxmc = FplxEnum.ZP.getFplxMc(FplxEnum.ZP.getIndex());
            } else if ("6".equals(invoiceTypeCode) || "3".equals(invoiceTypeCode)) {
                fplxdm = FplxEnum.PP.getFplxDm();
                fplxmc = FplxEnum.PP.getFplxMc(FplxEnum.PP.getIndex());
            } else {
                fplxdm = null;
            }
        } else {
            fplxdm = null;
        }
    }

    /**
     * 判断发票代码位数是否合法
     *
     * 合法返回true，否则返回false
     *
     *
     */
    public boolean fpdmValid() {
        boolean valid = false;
        if (!StringHelper.isBlank(fpdm) && (FPDM10_PATTERN.matcher(fpdm).matches() || FPDM12_PATTERN.matcher(fpdm).matches())) {
            valid = true;
        }else if(fpdm == null || StringHelper.isBlank(fpdm)){
            valid = true;
        }
        return valid;
    }

    /**
     * 判断发票号码位数是否合法
     *
     * 合法返回true，否则返回false
     *
     *
     */
    public boolean fphmValid() {
        boolean valid = false;
        if (!StringHelper.isBlank(fphm)
            && (FPHM8_PATTERN.matcher(fphm).matches() || FPHM10_PATTERN.matcher(fphm).matches())) {
            valid = true;
        }
        return valid;
    }

    public static void main(String[] args) {
        String fphm ="1033697";
        boolean valid = false;
        if (!StringHelper.isBlank(fphm)
                && (FPHM8_PATTERN.matcher(fphm).matches() || FPHM10_PATTERN.matcher(fphm).matches())) {
            valid = true;
        }
        System.out.println(valid);
    }


    /**
     * 判断金额是否合法
     *
     * 合法返回true，否则返回false
     *
     *
     */
    public boolean jeValid() {
        boolean valid = false;
        if (!StringHelper.isBlank(je) && (MONEY_PATTERN.matcher(je).matches())) {
            valid = true;
        }
        return valid;
    }

    /**
     * 判断税额是否合法
     *
     * 合法返回true，否则返回false
     *
     *
     */
    public boolean seValid() {
        boolean valid = false;
        if (!StringHelper.isBlank(se) && (MONEY_PATTERN.matcher(se).matches())) {
            valid = true;
        }
        return valid;
    }

    /**
     * 判断税额是否合法
     *
     * 合法返回true，否则返回false
     *
     *
     */
    public boolean kprqValid(String dataFormat) {
        boolean valid = true;
        SimpleDateFormat format;
        if (dataFormat == null) {
            format = new SimpleDateFormat("yyyy-MM-dd");
        } else {
            format = new SimpleDateFormat(dataFormat);
        }

        try {
            format.parse(kprq);
        } catch (ParseException e) {
            valid = false;
        }
        return valid;
    }

    /**
     * 判断税额是否合法
     *
     * 合法返回true，否则返回false
     *
     *
     */
    public boolean jymValid() {
        boolean valid = false;
        if (!StringHelper.isBlank(jym) && jym.length() >= 6) {
            valid = true;
        }
        return valid;
    }

    /**
     * 获取发票类型代码
     *
     *
     *
     */
    public String getFplxdm() {
        return fplxdm;
    }

    /**
     * 获取发票类型名称
     *
     *
     *
     */
    public String getFplxmc() {
        return fplxmc;
    }

    public String getFpdm() {
        return fpdm;
    }

    public void setFpdm(String fpdm) {
        this.fpdm = fpdm;
        this.getFplx(fpdm);
    }

    public String getFphm() {
        return fphm;
    }

    public void setFphm(String fphm) {
        this.fphm = fphm;
    }

    public String getKprq() {
        return kprq;
    }

    public void setKprq(String kprq) {
        this.kprq = kprq;
    }

    public String getJe() {
        return je;
    }

    public void setJe(String je) {
        this.je = je;
    }

    public String getSe() {
        return se;
    }

    public void setSe(String se) {
        this.se = se;
    }

    public String getJym() {
        return jym;
    }

    public void setJym(String jym) {
        this.jym = jym;
    }
}
