# -*- coding: utf-8 -*-
# # 开始匹配各个放款表
from threading import Thread

import pandas as pd
from sqlalchemy import create_engine
import numpy as np

pd.options.mode.chained_assignment = None
import sys

reload(sys)
sys.setdefaultencoding('utf8')

# --------------------配置变量-------------------------------
years = (2017,)
months = (5,)
# fundcodes = (
#     1, 0, 3, 2, 5, 29, 4, 141, 50, 70, 80, 90, 100, 120, 110, 130, 150, 170, 180, 140, 190, 200, 160, 210, 135, 230,
#     240,
#     250, 251, 260, 300, 290, 270, 330, 310, 320, 350, 340)
fundcodes = (
    150,)
file_path = u'E:/loan_test/'
sql_funding_corp = """select funding_code 'funding_code', name '资金方' from funding_corp;"""

sql_loan_account = """select id loan_account_id, accountName '放款账户' from loan_account;"""

sql_loan = """SELECT lm.funding_code 'funding_code',lm.loan_id 'loan_id',lm.ref_id 'ref_id', lm.`user_biz_id` '用户id',loan_paid_at '放款日期',lm.real_loan_amount '放款金额',lm.loan_account_id 'loan_account_id',lm.contract_loan_amount '本金（债权）',lm.qg_one_time_service_fee '一次性扣除手续费QG',lm.funding_one_time_service_fee '一次性手续费（点滴）',lm.contract_term '贷款总期数',lm.per_term_service_fee '每期手续费',lm.monthly_required_repayment_amount '每期还款额',lm.monthly_interest_rate '月利率',
t2.qg_one_time_service_fee '应扣趸收服务费'
FROM loan_manifest lm LEFT JOIN new_transaction.xjd_dunjiao_plan t2 ON lm.ref_id=t2.ref_id WHERE lm.loan_paid_at>="%d-%d-01" AND lm.loan_paid_at<"%d-%d-01" AND lm.funding_code=%d AND lm.is_active in (1,-2)  ;"""

sql_plan = """SELECT ref_id ,term_no ,deadline ,required_repayment  FROM user_repayment_plan WHERE ref_id in %s """
chunksize = 10000
step = 3000
columns = [u'资金方', u'loan_id', u'ref_id', u'用户id', u'放款日期', u'放款金额', u'放款账户', u'本金（债权）', u'一次性手续费（QG）', u'一次性手续费（点滴）',
           u'贷款总期数', u'每期手续费', u'每期还款额', u'月利率',u'应扣趸收服务费', u'第1期应还款额', u'客户应还款日-第1期', u'第2期应还款额', u'客户应还款日-第2期', u'第3期应还款额', u'客户应还款日-第3期',
           u'第4期应还款额', u'客户应还款日-第4期', u'第5期应还款额', u'客户应还款日-第5期', u'第6期应还款额', u'客户应还款日-第6期']


# ------------------多线程处理还款计划---------------------
def process_plan(ref_ids):
    engine_new_transaction = create_engine(
        'mysql+mysqldb://yulong_rw:TouBStYwN8wkdxVt@172.16.3.201:3306/new_transaction?charset=utf8', echo=True)
    if len(ref_ids) > 1:
        df_plan = pd.read_sql(sql=sql_plan % str(ref_ids),
                              con=engine_new_transaction)
    else:
        df_plan = pd.read_sql(sql=sql_plan % str(ref_ids).replace(',', ''),
                              con=engine_new_transaction)
    print 'read plan over'
    gp_plan = df_plan.groupby('ref_id')
    df_loan_plan = pd.DataFrame()
    for ref_id, sub_gp in gp_plan:
        new_row = pd.DataFrame(index=[0])
        new_row['ref_id'] = ref_id
        new_row['plan_len'] = len(sub_gp)
        for j, row in sub_gp.iterrows():
            term_no = int(row['term_no'])
            new_row[u'第%s期应还款额' % (term_no,)] = row['required_repayment']
            new_row[u'客户应还款日-第%s期' % (term_no,)] = row['deadline']
        df_loan_plan = df_loan_plan.append(new_row)
    return df_loan_plan


class MyThread(Thread):
    def __init__(self, ids):
        Thread.__init__(self)
        self.ref_ids = ids

    def run(self):
        self.result = process_plan(self.ref_ids)

    def get_result(self):
        return self.result


# ---------------------------按月开始构造还款计划------------------------------
def cal_out_of_inst(x):
    a = x[u'放款金额']
    b = x[u'月利率']
    c = int(x[u'贷款总期数'])
    inst = 0
    for i in xrange(1, c + 1):
        inst += np.round(np.ipmt(b, i, c, -a), 2)
    return inst

con_audit = create_engine(
        'mysql+mysqldb://yulong_rw:TouBStYwN8wkdxVt@172.16.3.201:3306/audit?charset=utf8', echo=True)

con_audit_audit = create_engine(
        'mysql+mysqldb://yulong_rw:TouBStYwN8wkdxVt@172.16.3.201:3306/audit?charset=utf8', echo=True)
for year in years:
    for mon in months:
        for fund_code in fundcodes:
            # 生成式方式读取数据库数据，并拼接到一起

            df_fund_corp_gen = pd.read_sql(sql=sql_funding_corp, con=con_audit_audit, chunksize=chunksize)
            df_fund_corp = pd.DataFrame()
            for tmp in df_fund_corp_gen:
                df_fund_corp = df_fund_corp.append(tmp, ignore_index=True)

            df_loan_account_gen = pd.read_sql(sql=sql_loan_account, con=con_audit_audit, chunksize=chunksize)
            df_loan_account = pd.DataFrame()
            for tmp in df_loan_account_gen:
                df_loan_account = df_loan_account.append(tmp, ignore_index=True)

            if mon == 12:
                print sql_loan % (year, mon, year + 1, 1, fund_code)
                df_loan_gen = pd.read_sql(sql=sql_loan % (year, mon, year + 1, 1, fund_code), con=con_audit,
                                          chunksize=chunksize)
            else:
                print sql_loan % (year, mon, year, mon + 1, fund_code)
                df_loan_gen = pd.read_sql(sql=sql_loan % (year, mon, year, mon + 1, fund_code), con=con_audit,
                                          chunksize=chunksize)
            df_loan = pd.DataFrame()
            for tmp in df_loan_gen:
                df_loan = df_loan.append(tmp, ignore_index=True)
            # 检查数据，可以不要
            # print df_loan.info()
            # 检查是否有重复的数据
            if len(df_loan) < 1:
                continue
            print '删除重复前', len(df_loan['loan_id'])
            print '删除重复后', len(df_loan['loan_id'].drop_duplicates())
            df_loan['loan_id'] = df_loan['loan_id'].astype(str)
            df_loan['ref_id'] = df_loan['ref_id'].astype(str)
            ref_ids = tuple(df_loan['ref_id'])
            td_list = []
            for i in xrange(0, len(ref_ids), step):
                # 多线程处理还款计划
                td = MyThread(ref_ids[i: i + step])
                td.start()
                td_list.append(td)
            # 等待线程结束
            for td in td_list:
                td.join()
            result_list = []
            # 获取线程返回的结果
            for td in td_list:
                result_list.append(td.get_result())
            df_loan_plan = pd.concat(result_list, ignore_index=True)
            df_loan_plan['ref_id'] = df_loan_plan['ref_id'].astype(str)
            df_loan['funding_code'] = df_loan['funding_code'].astype(int)
            df_loan['loan_account_id'] = df_loan['loan_account_id'].astype(int)
            df_loan = df_loan.merge(df_fund_corp, on='funding_code', how='left').merge(df_loan_account,
                                                                                       on='loan_account_id', how='left')
            df_loan.drop(['funding_code', 'loan_account_id'], axis=1, inplace=True)
            result = pd.merge(df_loan, df_loan_plan, on='ref_id', how='left')

            # 验证数据是否有丢失
            print '放款记录汇总长度：', len(result)
            print '期数不一致的记录', list(result[result[u'贷款总期数'] != result['plan_len']]['ref_id'])
            del result['plan_len']
            result.to_excel(file_path + u'现金贷放款表明细%s年-%s月-%s.xlsx' % (year, mon, fund_code), index=None, columns=columns)
