import re
import time
import numpy as np
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from .rmb_lower import rmb_handler
# from .rmb_upper import to_rmb_upper
from pandas._libs import tslib
from pandas._libs.tslibs.nattype import NaTType
from pandas.core.indexes.datetimes import DatetimeIndex
import logging

compare_log = logging.getLogger('compare')


class Comparison:

    def __init__(self):
        self.CSIBM = 'CSIBM'
        self.CSSME = 'CSSME'
        self.CSOTH = 'CSOTH'
        self.SPLIT_STR = '_'
        self.SCHEDULE_SPLIT_STR = '、'

        self.TYPE_MAPPING = (
            (r'个体工商户', self.CSIBM),
            (r'有限责任公司', self.CSSME),
            (r'个人独资企业', self.CSSME),
            (r'有限合伙企业', self.CSSME),
            (r'股份合作制', self.CSSME),
        )

        self.RESULT_Y = 'Y'
        self.RESULT_N = 'N'
        self.RESULT_N1 = 'N1'
        self.RESULT_N2 = 'N2'
        self.RESULT_NA = 'NA'

        self.TRANS_MAP = {
            ' ': '',
            '·': '',
        }
        self.KH_TRANS_MAP = {
            '(': '1',
            ')': '1',
            '(': '1',
            ')': '1',
        }
        self.TRANS = str.maketrans(self.TRANS_MAP)
        self.KH_TRANS = str.maketrans(self.KH_TRANS_MAP)
        self.re_obj = r'[(\(].*?[\))]'

    def build_res(self, result):
        if result:
            return self.RESULT_Y
        else:
            return self.RESULT_N

    def common_compare(self, input_str, ocr_str, idx, **kwargs):
        if not isinstance(ocr_str, str) or not isinstance(input_str, str):
            return self.RESULT_NA, ocr_str
        if ocr_str == '' or ocr_str.strip() == '':
            return self.RESULT_NA, None
        return self.build_res(input_str == ocr_str), ocr_str

    def company_compare(self, input_str, ocr_str, idx, **kwargs):
        if not isinstance(ocr_str, str) or not isinstance(input_str, str):
            return self.RESULT_NA, ocr_str
        if ocr_str == '' or ocr_str.strip() == '':
            return self.RESULT_NA, None
        input_tmp = re.sub(self.re_obj, '', input_str).strip()
        ocr_tmp = re.sub(self.re_obj, '', ocr_str).strip()
        return self.build_res(input_tmp == ocr_tmp), ocr_str

    def se_channel_compare(self, input_str, ocr_str, **kwargs):
        input_tmp = re.sub(self.re_obj, '', input_str).strip()
        ocr_tmp = re.sub(self.re_obj, '', ocr_str).strip()
        return self.build_res(input_tmp == ocr_tmp)

    def name_compare(self, input_str, ocr_str, idx, **kwargs):
        if not isinstance(ocr_str, str) or not isinstance(input_str, str):
            return self.RESULT_NA, ocr_str
        if ocr_str == '' or ocr_str.strip() == '':
            return self.RESULT_NA, None
        if kwargs.get('is_passport'):
            input_tmp = input_str.upper().replace(' ', '')
            ocr_tmp = ocr_str.upper().replace(' ', '')
            if input_tmp.find(ocr_tmp) == -1:
                return self.RESULT_N, ocr_str
            else:
                return self.RESULT_Y, ocr_str
        else:
            # if re.search(r'[a-zA-Z]]', input_str):
            #     return self.RESULT_NA, ocr_str
            input_s = input_str.translate(self.TRANS)
            ocr_s = ocr_str.translate(self.TRANS)
            return self.build_res(input_s == ocr_s), ocr_str

    def date_compare(self, input_str, ocr_str, idx, **kwargs):
        if not isinstance(ocr_str, str) or not isinstance(input_str, str):
            return self.RESULT_NA, ocr_str
        if ocr_str == '' or ocr_str.strip() == '':
            return self.RESULT_NA, None
        if kwargs.get('long', False):
            if '长期' in ocr_str or '永久' in ocr_str:
                if input_str == '2099-12-31' or input_str == '2099-01-01':
                    return self.RESULT_Y, '2099-12-31'
                else:
                    return self.RESULT_N, '2099-12-31'
        if kwargs.get('ocr_split', False):
            if '至' in ocr_str:
                ocr_str = ocr_str.split('至')[-1]
            elif '-' in ocr_str:
                ocr_str = ocr_str.split('-')[-1]
        if kwargs.get('ocr_replace', False):
            ocr_str = ocr_str.replace('年', '-').replace('月', '-').replace('日', '')
        if kwargs.get('input_replace') is not None:
            input_str = input_str.replace('-', kwargs.get('input_replace'))
            try:
                ocr_output = datetime.strptime(ocr_str, '%Y{0}%m{0}%d'.format(
                    kwargs.get('input_replace'))).strftime('%Y-%m-%d')
            except Exception as e:
                ocr_output = None
        else:
            try:
                ocr_output = datetime.strptime(ocr_str, '%Y-%m-%d').strftime('%Y-%m-%d')
            except Exception as e:
                ocr_output = None
        return self.build_res(input_str == ocr_str), ocr_output

    def mvi_special(self, amount_lower_str, amount_upper_str):
        # 不含税价, 增值税税额
        try:
            if float(amount_lower_str) != rmb_handler.to_rmb_lower(amount_upper_str):
                return self.RESULT_N
        except Exception:
            return self.RESULT_N
        else:
            return self.RESULT_Y

    def rmb_compare(self, input_str, ocr_str, idx, **kwargs):
        if not isinstance(ocr_str, str) or not isinstance(input_str, str):
            return self.RESULT_NA, None
        if ocr_str == '' or ocr_str.strip() == '':
            return self.RESULT_NA, None
        try:
            ocr_lower = rmb_handler.to_rmb_lower(ocr_str)
            res = self.build_res(float(input_str) == ocr_lower)
            # input_rmb_upper = to_rmb_upper(float(input_str))
            # res = self.build_res(input_rmb_upper == ocr_str)
        except Exception as e:
            return self.RESULT_N, None
        else:
            if res == self.RESULT_Y:
                return res, input_str
            else:
                return res, ocr_lower
                # return res, None

    def type_compare(self, input_str, ocr_str, idx, **kwargs):
        if not isinstance(ocr_str, str) or not isinstance(input_str, str):
            return self.RESULT_NA, ocr_str
        if ocr_str == '' or ocr_str.strip() == '':
            return self.RESULT_NA, None
        for map_tuple in self.TYPE_MAPPING:
            if re.search(map_tuple[0], ocr_str) is not None:
                compare_str = map_tuple[1]
                break
        else:
            compare_str = self.CSOTH

        return self.build_res(input_str == compare_str), compare_str

    def se_list_compare(self, input_str_or_list, ocr_str_or_list, **kwargs):
        if isinstance(ocr_str_or_list, list) and len(ocr_str_or_list) > 0:
            if isinstance(input_str_or_list, list) and len(input_str_or_list) > 0:
                if input_str_or_list[0] == ocr_str_or_list[0]:
                    return self.RESULT_Y
                return self.RESULT_N
            else:
                # if kwargs.get('pop_last', False):
                #     for item in ocr_str_or_list[:-1]:
                #         if item != input_str_or_list:
                #             return self.RESULT_N
                # else:
                for item in ocr_str_or_list:
                    if item != input_str_or_list:
                        return self.RESULT_N
                return self.RESULT_Y
        else:
            return self.RESULT_N

    def se_input_list_compare(self, input_list, ocr_str, **kwargs):
        if isinstance(input_list, list) and len(input_list) > 0 and isinstance(ocr_str, str):
            ocr_str = ocr_str.translate(self.KH_TRANS)

            for input_str in input_list:
                input_str = input_str.translate(self.KH_TRANS)
                compare_log.info('[se_input_list_compare] [input_str {0}] [ocr_str {1}]'.format(input_str, ocr_str))
                if input_str == ocr_str:
                    return self.RESULT_Y
            return self.RESULT_N
        else:
            return self.RESULT_N

    def super_list_compare(self, input_list, ocr_str, **kwargs):
        for input_str in input_list:
            if kwargs.get('method', 'common') == 'name':
                if self.se_name_compare(input_str, ocr_str, **kwargs) == self.RESULT_Y:
                    return self.RESULT_Y
            else:
                if self.se_common_compare(input_str, ocr_str, **kwargs) == self.RESULT_Y:
                    return self.RESULT_Y
        return self.RESULT_N

    def se_date_contain_compare(self, input_str, ocr_str_or_list, **kwargs):
        return self.RESULT_Y

    @staticmethod
    def amount_fix(src_str):
        replace_char_list = []
        for idx in range(len(src_str)):
            if src_str[idx].isdigit():
                replace_char_list.append(src_str[idx])
            elif idx == len(src_str) - 3:
                replace_char_list.append('.')
        return ''.join(replace_char_list)

    def se_schedule_compare(self, input_str, ocr_str_or_list, **kwargs):
        if isinstance(ocr_str_or_list, list):
            if len(ocr_str_or_list) > 0:
                ocr_str_or_list.pop(0)
                schedule_list = []
                for row_list in ocr_str_or_list:
                    tmp_str = "{1}{0}{2}".format(
                        self.SPLIT_STR,
                        row_list[0].replace('.', ''),
                        # 优化还款计划表页,小数点只存在与还款金额的倒数第三位。
                        self.amount_fix(row_list[kwargs.get('value_idx', 1)]))
                    schedule_list.append(tmp_str)
                return self.build_res(self.SCHEDULE_SPLIT_STR.join(schedule_list) == input_str)
            else:
                return self.RESULT_N
        else:
            return self.RESULT_N

    def se_asp_compare(self, input_list, ocr_str_or_list, **kwargs):
        if isinstance(ocr_str_or_list, list):
            try:
                for asp_name, asp_price, asp_fin in input_list[:-1]:
                    for row_list in ocr_str_or_list:
                        if len(row_list) != 3:
                            continue
                        if row_list[0].find(asp_name) == -1:
                            continue
                        if float(row_list[1].replace(',', '')) == float(asp_price) and \
                                float(row_list[2].replace(',', '')) == float(asp_fin):
                            break
                    else:
                        return self.RESULT_N

                _, _, sum_fin = input_list[-1]
                if float(ocr_str_or_list[-1][-1].replace(',', '')) == float(sum_fin):
                    return self.RESULT_Y
                else:
                    return self.RESULT_N
            except Exception as e:
                return self.RESULT_N
        else:
            return self.RESULT_N

    def se_gzs_compare(self, input_str, ocr_str_or_list, **kwargs):
        pass

    def se_name_compare(self, input_str, ocr_str, **kwargs):
        if kwargs.get('is_passport'):
            input_tmp = input_str.upper().replace(' ', '')
            ocr_tmp = ocr_str.upper().replace(' ', '')
            if kwargs.get('replace_kuohao'):
                input_tmp = input_tmp.translate(self.KH_TRANS)
                ocr_tmp = ocr_tmp.translate(self.KH_TRANS)
            if input_tmp.find(ocr_tmp) == -1:
                return self.RESULT_N
            else:
                if ocr_str.strip() == '':
                    return self.RESULT_N
                else:
                    return self.RESULT_Y
        else:
            # if re.search(r'[a-zA-Z]]', input_str):
            #     return self.RESULT_NA, ocr_str
            input_s = input_str.translate(self.TRANS)
            ocr_s = ocr_str.translate(self.TRANS)
            return self.build_res(input_s == ocr_s)

    def se_bs_name_compare(self, input_str, ocr_str, **kwargs):
        new_ocr_str = re.sub(r'[^\u4e00-\u9fa5]+', '', ocr_str)
        return self.build_res(input_str == new_ocr_str)

    def ca_name_compare(self, input_str, ocr_str, **kwargs):
        if kwargs.get('is_passport'):
            input_tmp = input_str.upper().replace(' ', '')
            ocr_tmp = ocr_str.upper().replace(' ', '')
            if input_tmp.find(ocr_tmp) == -1:
                return self.RESULT_N
            else:
                if ocr_str.strip() == '':
                    return self.RESULT_N
                else:
                    return self.RESULT_Y
        else:
            # if re.search(r'[a-zA-Z]]', input_str):
            #     return self.RESULT_NA, ocr_str
            input_s = input_str.translate(self.TRANS)
            ocr_s = ocr_str.translate(self.TRANS)
            return self.build_res(input_s == ocr_s)

    def se_common_compare(self, input_str, ocr_str, **kwargs):
        if kwargs.get('is_bd_id', False):
            if ocr_str == '':
                return self.RESULT_Y
        if kwargs.get('is_gsyh', False):
            if ocr_str == '' or ocr_str is None:
                return self.RESULT_Y
        if kwargs.get('remove_space', False):
            input_str = input_str.replace(' ', '')
        if kwargs.get('remove_all_space', False):
            input_str = input_str.replace(' ', '')
            ocr_str = ocr_str.replace(' ', '')
        if kwargs.get('brackets_replace', False):
            input_str = input_str.translate(self.KH_TRANS)
            ocr_str = ocr_str.translate(self.KH_TRANS)
        return self.build_res(input_str == ocr_str)

    def ca_common_compare(self, input_str, ocr_str, **kwargs):
        return self.build_res(input_str == ocr_str)

    @staticmethod
    def is_after_today(ocr_str, delayed_date):
        dt_array, _ = tslib.array_to_datetime(
            np.array([ocr_str, ], copy=False, dtype=np.object_),
            errors="coerce",
            utc=False,
            dayfirst=False,
            yearfirst=False,
            require_iso8601=True,
        )
        dti = DatetimeIndex(dt_array, tz=None, name=None)
        ts = dti[0]
        if isinstance(ts, NaTType) or ts.date() < (datetime.today() + relativedelta(days=delayed_date)).date():
            return False
        else:
            return True

    def is_after_today_pre(self, ocr_str):
        dt_array, _ = tslib.array_to_datetime(
            np.array([ocr_str, ], copy=False, dtype=np.object_),
            errors="coerce",
            utc=False,
            dayfirst=False,
            yearfirst=False,
            require_iso8601=True,
        )
        dti = DatetimeIndex(dt_array, tz=None, name=None)
        ts = dti[0]
        if isinstance(ts, NaTType):
            return self.RESULT_N1
        elif ts.date() < datetime.today().date():
            return self.RESULT_N1
        elif ts.date() > (datetime.today() + relativedelta(days=8)).date():
            return self.RESULT_Y
        else:
            return self.RESULT_N2

    @staticmethod
    def is_predate_two_year(ocr_str):
        dt_array, _ = tslib.array_to_datetime(
            np.array([ocr_str, ], copy=False, dtype=np.object_),
            errors="coerce",
            utc=False,
            dayfirst=False,
            yearfirst=False,
            require_iso8601=True,
        )
        dti = DatetimeIndex(dt_array, tz=None, name=None)
        ts = dti[0]
        if isinstance(ts, NaTType) or ts.date() > (datetime.today() - relativedelta(years=2)).date():
            return False
        else:
            return True

    def se_date_compare(self, input_str, ocr_str, **kwargs):
        if kwargs.get('long', False):
            if '长期' in ocr_str or '永久' in ocr_str or '***' in ocr_str or '至今' in ocr_str or '年—月—日' in ocr_str \
                    or '年 月 日' in ocr_str or '年月日' in ocr_str:
                if kwargs.get('today', False) or input_str in ['2099-12-31', '2099-01-01', '2999-12-31', '2999-01-01']:
                    return self.RESULT_Y
                else:
                    return self.RESULT_N
        if kwargs.get('ocr_split', False):
            if '至' in ocr_str:
                ocr_str = ocr_str.split('至')[-1]
            elif '-' in ocr_str:
                ocr_str = ocr_str.split('-')[-1]
        if kwargs.get('ocr_replace', False):
            ocr_str = ocr_str.replace('年', '-').replace('月', '-').replace('日', '')
        if kwargs.get('input_replace') is not None:
            input_str = input_str.replace('-', kwargs.get('input_replace'))
        if kwargs.get('today', False):
            delayed_date = kwargs.get('delayed_date', 8)
            return self.build_res(self.is_after_today(ocr_str, delayed_date))
        if kwargs.get('two_year', False):
            return self.build_res(self.is_predate_two_year(ocr_str))
        else:
            res = self.build_res(input_str == ocr_str)
            if res == self.RESULT_Y:
                return res
            else:
                try:
                    ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d")
                    input_date = datetime.strptime(input_str, "%Y-%m-%d")
                    return self.build_res(input_date == ocr_date)
                except Exception as e:
                    return self.RESULT_N

    def ca_date_compare(self, input_str, ocr_str, **kwargs):
        if kwargs.get('long', False):
            if '长期' in ocr_str or '永久' in ocr_str:
                if input_str in ['2099-12-31', '2099-01-01']:
                    return self.RESULT_Y
                else:
                    return self.RESULT_N
        if kwargs.get('ocr_split', False):
            if '至' in ocr_str:
                ocr_str = ocr_str.split('至')[-1]
            elif '-' in ocr_str:
                ocr_str = ocr_str.split('-')[-1]
        if kwargs.get('ocr_replace', False):
            ocr_str = ocr_str.replace('年', '-').replace('月', '-').replace('日', '')
        if kwargs.get('input_replace') is not None:
            input_str = input_str.replace('-', kwargs.get('input_replace'))
        return self.build_res(input_str == ocr_str)

    def se_contain_compare(self, input_str, ocr_str, **kwargs):
        if ocr_str.find(input_str) == -1:
            return self.RESULT_N
        else:
            if ocr_str.strip() == '':
                return self.RESULT_N
            else:
                return self.RESULT_Y

    def se_contain_compare_2(self, input_str, ocr_str, **kwargs):
        if kwargs.get('brackets_replace', False):
            input_str = input_str.translate(self.KH_TRANS)
            ocr_str = ocr_str.translate(self.KH_TRANS)
        if input_str.find(ocr_str) == -1:
            return self.RESULT_N
        else:
            if ocr_str.strip() == '':
                return self.RESULT_N
            else:
                return self.RESULT_Y

    def se_have_compare(self, input_str, ocr_str, **kwargs):
        if ocr_str == '' or ocr_str == '无':
            return self.RESULT_N
        return self.RESULT_Y

    def se_both_contain_compare(self, input_str, ocr_str, **kwargs):
        if kwargs.get('is_gsyh', False):
            if ocr_str == '' or ocr_str is None:
                return self.RESULT_Y
        if ocr_str.find(input_str) == -1 and input_str.find(ocr_str) == -1:
            return self.RESULT_N
        else:
            if ocr_str.strip() == '':
                return self.RESULT_N
            else:
                return self.RESULT_Y

    def se_amount_str_compare(self, input_str, ocr_str, **kwargs):
        if input_str == ocr_str:
            return self.RESULT_Y
        else:
            ocr_tmp = ocr_str.replace('元', '').replace(',', '')
            input_tmp = input_str.replace('元', '').replace(',', '')
            return self.build_res(ocr_tmp == input_tmp)

    def se_amount_lte_compare(self, input_str, ocr_str, **kwargs):
        try:
            float_input = float(input_str)
            float_ocr = float(ocr_str.replace('元', '').replace(',', ''))
            return self.build_res(float_ocr >= float_input)
        except Exception as e:
            try:
                ocr_lower = rmb_handler.to_rmb_lower(ocr_str.replace('元', '').replace(',', ''))
                return self.build_res(ocr_lower >= float(input_str))
            except Exception as e:
                return self.RESULT_N

    def se_amount_compare(self, input_str, ocr_str, **kwargs):
        if input_str == ocr_str:
            return self.RESULT_Y
        else:
            try:
                float_input = float(input_str)
                digit_ocr_str = ''.join(filter(lambda i: i in [',', '.'] or str.isdigit(i), ocr_str))
                float_ocr = float(digit_ocr_str)
            except Exception as e:
                return self.RESULT_N
            else:
                return self.build_res(float_ocr == float_input)

    def se_one_compare(self, input_list, ocr_str, **kwargs):
        if isinstance(input_list, list):
            if ocr_str in input_list:
                return self.RESULT_Y
        return self.RESULT_N

    def se_bs_one_compare(self, input_list, ocr_str, **kwargs):
        if isinstance(input_list, list):
            new_ocr_str = re.sub(r'[^\u4e00-\u9fa5]+', '', ocr_str)
            if new_ocr_str in input_list:
                return self.RESULT_Y
        return self.RESULT_N

    def se_company_compare(self, input_str, ocr_str, **kwargs):
        input_tmp = re.sub(self.re_obj, '', input_str).strip()
        ocr_tmp = re.sub(self.re_obj, '', ocr_str).strip()
        return self.build_res(input_tmp == ocr_tmp)

    def ca_company_compare(self, input_str, ocr_str, **kwargs):
        input_tmp = re.sub(self.re_obj, '', input_str).strip()
        ocr_tmp = re.sub(self.re_obj, '', ocr_str).strip()
        return self.build_res(input_tmp == ocr_tmp)

    def se_rmb_compare(self, input_str, ocr_str, **kwargs):
        try:
            ocr_lower = rmb_handler.to_rmb_lower(ocr_str)
            res = self.build_res(float(input_str) == ocr_lower)
            # input_rmb_upper = to_rmb_upper(float(input_str))
            # res = self.build_res(input_rmb_upper == ocr_str)
        except Exception as e:
            return self.RESULT_N
        else:
            return res

    def ca_rmb_compare(self, input_str, ocr_str, **kwargs):
        try:
            ocr_lower = rmb_handler.to_rmb_lower(ocr_str)
            res = self.build_res(float(input_str) == ocr_lower)
            # input_rmb_upper = to_rmb_upper(float(input_str))
            # res = self.build_res(input_rmb_upper == ocr_str)
        except Exception as e:
            return self.RESULT_N
        else:
            return res

    def se_type_compare(self, input_str, ocr_str, **kwargs):
        for map_tuple in self.TYPE_MAPPING:
            if re.search(map_tuple[0], ocr_str) is not None:
                compare_str = map_tuple[1]
                break
        else:
            compare_str = self.CSOTH
        return self.build_res(input_str == compare_str)

    def ca_type_compare(self, input_str, ocr_str, **kwargs):
        for map_tuple in self.TYPE_MAPPING:
            if re.search(map_tuple[0], ocr_str) is not None:
                compare_str = map_tuple[1]
                break
        else:
            compare_str = self.CSOTH
        return self.build_res(input_str == compare_str)

    def se_date_compare_2(self, input_str, ocr_str, **kwargs):
        try:
            input_date = datetime.strptime(input_str, "%Y-%m-%d").date()
            if kwargs.get('three_month', False):
                three_month_date = (datetime.today() - relativedelta(months=3)).date()
                compare_date = max(input_date, three_month_date)
            else:
                compare_date = input_date
            ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date()
        except Exception as e:
            return self.RESULT_N
        else:
            return self.build_res(compare_date <= ocr_date)

    def se_bd_date_compare(self, input_str, ocr_str, **kwargs):
        try:
            input_date = datetime.strptime(input_str, "%Y-%m-%d").date()
            ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date()
            if kwargs.get('start', False):
                if input_date != ocr_date:
                    return self.RESULT_N

                six_month_date = (datetime.today() - relativedelta(months=6)).date()
                today_date = (datetime.today() + relativedelta(days=1)).date()
                return self.build_res(six_month_date <= ocr_date <= today_date)
            else:
                if input_date == ocr_date or ocr_date == input_date + relativedelta(days=1):
                    return self.RESULT_Y
                return self.RESULT_N
        except Exception as e:
            return self.RESULT_N

    def se_bd_date_2_compare(self, input_str, ocr_str, **kwargs):
        try:
            # Convert strings to date objects
            ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date()

            # Get today's date
            today_date = datetime.today().date()
            '''
            开始时间<后天(不包含), 结束时间>昨天(不包含)
            '''
            if kwargs.get('start', False):
                # 开始时间 < 后天(不包含)
                day_after_tomorrow_date = today_date + relativedelta(days=2)
                if ocr_date < day_after_tomorrow_date:
                    return self.RESULT_Y
            else:
                # 结束时间>昨天(不包含)
                yesterday_date = today_date + relativedelta(days=-1)
                if ocr_date > yesterday_date:
                    return self.RESULT_Y

            # Default return value if conditions are not met
            return self.RESULT_N
        except Exception as e:
            # Return RESULT_N in case of any exception
            return self.RESULT_N

    def se_bs_print_date_compare(self, input_str, ocr_str, **kwargs):
        try:
            input_date = datetime.strptime(input_str, "%Y-%m-%d")
            ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d")
            if ocr_date >= input_date - relativedelta(days=kwargs.get('days', 15)):
                return self.RESULT_Y
            return self.RESULT_N
        except Exception as e:
            return self.RESULT_N

    def se_bs_date_compare(self, input_str, ocr_str, **kwargs):
        if not isinstance(ocr_str, int):
            try:
                ocr_int = int(ocr_str)
            except Exception as e:
                return self.RESULT_N
        else:
            ocr_int = ocr_str
        if ocr_int >= input_str:
            return self.RESULT_Y
        else:
            return self.RESULT_N

    def se_self_compare_gzs(self, input_list, ocr_str, **kwargs):
        if isinstance(input_list, list) and len(input_list) == 2:
            try:
                if isinstance(input_list[0], float) and isinstance(input_list[1], float) \
                        and input_list[0] >= input_list[1]:
                    return self.RESULT_Y
            except Exception as e:
                return self.RESULT_N
        return self.RESULT_N

    def se_self_compare_other_asp(self, input_str, ocr_str, **kwargs):
        return self.RESULT_N

    def se_jypz_date_compare(self, input_str, ocr_date_list, **kwargs):
        ocr_date_set = set(ocr_date_list)
        if len(ocr_date_set) > 1:
            return self.RESULT_N
        if not any(ocr_date_set):
            return self.RESULT_N
        return self.se_date_compare_2(input_str, ocr_date_set.pop(), three_month=True)

    # 'long': True, 'ocr_split': True, 'input_replace': '', 'today': True
    def se_date_compare_pre(self, input_str, ocr_str, **kwargs):
        if '长期' in ocr_str or '永久' in ocr_str or '***' in ocr_str or '至今' in ocr_str or '年—月—日' in ocr_str \
                or '年 月 日' in ocr_str or '年月日' in ocr_str:
            return self.RESULT_Y

        if '至' in ocr_str:
            ocr_str = ocr_str.split('至')[-1]
        elif '-' in ocr_str:
            ocr_str = ocr_str.split('-')[-1]

        # input_str = input_str.replace('-', '')

        return self.is_after_today_pre(ocr_str)

    def se_qrs_compare(self, input_str, ocr_str_or_list, **kwargs):
        try:
            target_count_str, application_id = input_str.split('_')
            search_count = 0
            for item_str in ocr_str_or_list:
                if item_str == application_id:
                    search_count += 1
            if search_count >= int(target_count_str):
                return self.RESULT_Y
            else:
                return self.RESULT_N
        except Exception as e:
            return self.RESULT_N

    def hash_code_compare(self, input_str, ocr_dict, **kwargs):
        try:
            balance_sheet_hash = ocr_dict.get('balance_sheet','')
            income_statement_hash = ocr_dict.get('income_statement','')
            cash_flow_statement_hash = ocr_dict.get('cash_flow_statement','')
            if balance_sheet_hash != input_str or income_statement_hash != input_str or cash_flow_statement_hash != input_str:
                return self.RESULT_N
            else:
                return self.RESULT_Y
        except Exception as e:
            return self.RESULT_N

    def stamp_dict_compare(self, input_str, ocr_dict, **kwargs):
        try:
            balance_sheet_stamp = ocr_dict.get('balance_sheet','')
            income_statement_stamp = ocr_dict.get('income_statement','')
            cash_flow_statement_stamp = ocr_dict.get('cash_flow_statement','')
            if balance_sheet_stamp != 1 or income_statement_stamp != 1 or cash_flow_statement_stamp != 1:
                return self.RESULT_N
            else:
                return self.RESULT_Y
        except Exception as e:
            return self.RESULT_N

    def stamp_str_compare(self, input_str, ocr_str, **kwargs):
        try:
            if ocr_str != 1:
                return self.RESULT_N
            else:
                return self.RESULT_Y
        except Exception as e:
            return self.RESULT_N

    def fiscal_year_compare(self, input_str, ocr_list, **kwargs):
        try:
            this_year_str = datetime.now().strftime('%Y')
            this_year = int(this_year_str)
            last_year = this_year - 1
            if str(input_str) != str(this_year) and str(input_str) != str(last_year):
                 return self.RESULT_N
            return self.RESULT_Y
        except Exception as e:
            return self.RESULT_N

    def input_list_not_zero_compare(self, input_list, ocr_list, **kwargs):
        try:
            for item in input_list:
                if float(item) == 0:
                    return self.RESULT_N
            return self.RESULT_Y
        except Exception as e:
            return self.RESULT_N


cp = Comparison()