from typing import Dict, Optional, Tuple, Any, Union, TextIO, List

import pandas as pd

try:
    from service.booldata.base import BoolDataBase
    from utils import udict
    from utils.uexcel import Excel
    from utils.ujson import Json2Excel
    from utils.file import File
    from errors import RequestFailed
except (ImportError, ModuleNotFoundError) as e:
    from pysubway.service.booldata.base import BoolDataBase
    from pysubway.utils import udict
    from pysubway.utils.uexcel import Excel
    from pysubway.utils.ujson import Json2Excel
    from pysubway.utils.file import File
    from pysubway.errors import RequestFailed


class HzRiskModel(BoolDataBase):
    service = 'hz_risk_model_service'
    mode = 'hz_risk_model_personal_credit_mode'
    df_default_header = ('姓名',
                         '年龄',
                         '身份证号',
                         '审核建议',
                         '3个月手机号关联身份证数', '3个月身份证关联手机号数', '个人欺诈黑名单',
                         '信贷逾期名单', '助学贷款欠费历史', '命中风险标注',
                         '户籍', '户籍地位于高风险集中地区', '手机号', '手机号归属地',
                         '故意违章乘车名单', '是否结清', '最近一次放款日期', '最近一次申请日期',
                         '欠税公司法人代表名单', '欠税名单', '法院信息', '法院失信名单',
                         '法院执行名单', '法院结案名单', '消费分期类放款机构数', '消费分期类申请机构数',
                         '犯罪通缉名单', '综合评分', '网络贷款类放款机构数', '网络贷款类申请机构数',
                         '虚拟号码库', '距离最近一次申请日期天数', '车辆租赁违约名单',
                         '近12个月履约次数', '近12个月放款机构总数', '近12个月申请机构总数',
                         '近12个月申请次数', '近12个月还款异常次数', '近1个月履约次数', '近1个月放款次数',
                         '近1个月申请次数', '近1个月还款异常次数', '近30天P2P平台', '近30天一般消费分期平台',
                         '近30天信用卡', '近30天其他类型公司', '近30天大型消费金融公司',
                         '近30天小额贷款公司', '近30天申请查询总数', '近3个月放款次数', '近3个月申请次数',
                         '近6个月放款次数', '近6个月未结清逾期次数', '近6个月申请次数',
                         '近6个月逾期总次数', '近6个月逾期总金额（元）', '近6个月逾期机构总数',
                         '近7天P2P平台', '近7天一般消费分期平台', '近7天信用卡', '近7天其他类型公司',
                         '近7天大型消费金融公司', '近7天小额贷款公司', '近7天申请查询总数', '近90天P2P平台',
                         '近90天一般消费分期平台', '近90天信用卡', '近90天其他类型公司',
                         '近90天大型消费金融公司', '近90天小额贷款公司', '近90天申请查询总数',
                         '通信小号库', '逾期时长', '逾期时间', '逾期金额区间（元）', '高风险关注名单')

    @classmethod
    def generate_biz_data(cls, name: str, phone: str, ident_number: str) -> Dict[str, Any]:
        biz_data = udict.Dict.filter(locals())
        biz_data.update({
            "service": cls.service,
            "mode": cls.mode
        })
        import pandas as pd
        pd.Series({'a': 1, 'b': 2, 'c': 3, }, index=['c', 'b', 'a', 'f'])
        return biz_data

    def set_biz_data(self, name: str, phone: str, ident_number: str) -> 'HzRiskModel':
        self.biz_data = self.generate_biz_data(name, phone, ident_number)
        return self


def batch_test(
        input: Union[str, pd.DataFrame, TextIO],
        account: Dict[str, str],
        output_file: str,
        template: str = f'{File.this_dir(__file__)}/template_hz_risk_model.xlsx',
        names: Optional[Tuple[str, ...]] = ('name', 'phone', 'idcard'),
        columns: Tuple[str, ...] = HzRiskModel.df_default_header,
        skiprows: Union[int, Tuple[int, ...], None] = None,
        error_log: Optional[str] = None,
        header: Union[int, List[int], None] = 0,
        raise_failed_exception: bool = False,
        env: str = 'prod',
) -> None:
    """
    batch test HzRiskModel, read from excel -> request HzRiskModel -> save result to excel

    :param template: result is transferred excel as the template
    :param input: excel file or pd.DataFrame or TextIO. If input not str, you must specify param error_log
    :param account: booldata account
    :param output_file: xlsx file that saving booldata result
    :param names: input excel file header, you can adjust the sequence.
    :param columns: output_file columns header
    :param skiprows: strip rows
    :param error_log: records error biz_data item.
    :param header: input excel header, default first row in excel
    :param raise_failed_exception: if True, raise RequestFailed Exception when request booldata failed.
    :return: None
    """
    discard_params = ['', None]
    error_log = error_log or File.join_path(File(input).dirname, '.'.join((File(input).pure_name, 'error_log')))
    template_excel = Json2Excel(template)
    input_excel: pd.DataFrame = Excel(input).read(names=names, skiprows=skiprows,
                                                  header=header).dataframe if isinstance(input, str) else input
    df_final = pd.DataFrame()
    huizu_ins = HzRiskModel(account['rsa_prv_key'],
                            account['aes_key'],
                            account['company_uuid'],
                            url=HzRiskModel.urls[env])
    for _, series in input_excel.iterrows():
        name, phone, idcard = str(series['name']), str(series['phone']), str(series['idcard'])
        print(f'It is running params: name {name}, phone {phone}, idcard {idcard}')
        copied = discard_params.copy()
        copied.extend((name, phone, idcard))
        if len(set(copied)) != len(copied):
            print(f'invalid params name {name}, phone {phone}, idcard {idcard}')
            continue
        ins_result = huizu_ins.set_biz_data(name, str(phone), str(idcard)).request()
        if not huizu_ins.is_succeed():
            if raise_failed_exception:
                raise RequestFailed(f'{ins_result}')
            print('error ins_result  ----> ', ins_result)
            with open(error_log, mode='a') as f:
                print(f"param is {series['idcard']} {series['name']} {series['phone']}")
                f.write(f"{series['idcard']},{series['name']},{series['phone']}\n")
        df_parsed = template_excel.parse(ins_result, index=[0])
        df_final = df_final.append(df_parsed, ignore_index=True)
    Json2Excel.to_excel(df_final, output_file, columns=columns)


if __name__ == '__main__':
    from gitignore import BOOLDATA_ACCOUNT

    file = '/Users/yutou/shouxin/sxProject/pysubway/pysubway/gitignore/haosen.csv'
    output = '/Users/yutou/shouxin/sxProject/pysubway/pysubway/gitignore/haosen_result.xlsx'
    # 有表头
    batch_test(file, BOOLDATA_ACCOUNT, output, skiprows=None, names=('name', 'phone', 'idcard'), header=0)
    # 无表头
