# encoding: utf8
from __future__ import unicode_literals
import pandas as pd
from sqlalchemy import create_engine
import datetime
import numpy as np

pd.set_option('display.float_format', lambda x: '%.5f' % x)


class Params:
    def __init__(self):
        pass

    deadline_start = datetime.datetime(2015, 1, 1)
    deadline_end = datetime.datetime(2017, 6, 1)
    repaid_at_start = datetime.datetime(2015, 1, 1)
    repaid_at_end = datetime.datetime(2017, 6, 1)
    step = 10000
    out_path = 'E:/财务/赔付/'
    out_path_tmp = 'E:/财务/赔付/tmp/'


class SqlStatement:
    def __init__(self):
        pass

    engine_new_transaction = create_engine(
        'mysql+mysqldb://yulong_rw:TouBStYwN8wkdxVt@172.16.3.201:3306/new_transaction?charset=utf8',
        echo=True)
    sql_fund = """SELECT id fund_code,name fund_name FROM new_transaction.funding_corp"""
    sql_repay_channel = """SELECT id repay_channel, approach_name channel_name FROM new_transaction.repay_channel"""

    sql_fund_record = """
    SELECT lc.class, frr.ref_id, frr.term_no, DATE(frr.deadline) fund_deadline, frr.funding_code fund_code, 
    frr.principle plan_principle, frr.interest plan_interest, frr.principle + frr.interest plan_prin_inst 
    FROM audit.funding_repayment_record frr JOIN temp.loan_class lc ON lc.ref_id = frr.ref_id AND is_active = 1 
    AND funding_code = %s AND deadline >= %s AND deadline < %s"""

    sql_plan = """SELECT lc.class, urp.ref_id, urp.term_no, DATE(urp.deadline) fund_deadline, urp.principle plan_principle, 
    urp.interest plan_interest, urp.principle + urp.interest plan_prin_inst
     FROM new_transaction.user_repayment_plan urp JOIN temp.loan_class lc ON lc.ref_id = urp.ref_id 
     WHERE urp.fund_code = %s AND urp.deadline >= %s AND urp.deadline < %s"""

    sql_record_online = """
    SELECT t3.ref_id, t3.term_no, DATE(t3.xyqb_repaid_at) repaid_at, DATE(t3.deadline) plan_deadline, t1.repay_channel,
      t1.principle real_principle, t1.mitigate_principle mitigate_principle, t1.interest real_interest,
      t1.mitigate_interest mitigate_interest, t1.service_fee real_service_fee, t1.mitigate_service_fee mitigate_service_fee,
      t1.punish real_punish, t1.mitigate_collection_relief mitigate_punish
    FROM new_transaction.xjd_repay_plan_repay_record_ref t1
    JOIN new_transaction.repay_record_online t2 ON t1.repay_channel < 13 AND t1.record_id = t2.id
    JOIN new_transaction.user_repayment_plan t3 ON t1.plan_id = t3.id
    AND t3.fund_code = %s AND t3.deadline >= %s AND t3.deadline < %s AND t3.xyqb_repaid_at >= %s AND t3.xyqb_repaid_at < %s 
    """

    sql_record_bank = """
    SELECT t3.ref_id, t3.term_no, DATE(t2.transfer_time) repaid_at, DATE(t3.deadline) plan_deadline, t1.repay_channel,
      t1.principle real_principle, t1.mitigate_principle mitigate_principle, t1.interest real_interest,
      t1.mitigate_interest mitigate_interest, t1.service_fee real_service_fee, t1.mitigate_service_fee mitigate_service_fee,
      t1.punish real_punish, t1.mitigate_collection_relief mitigate_punish
    FROM new_transaction.xjd_repay_plan_repay_record_ref t1
    JOIN new_transaction.offline_bank_repay_record t2 ON t1.repay_channel IN (14,15,16) AND t1.record_id = t2.id
    JOIN new_transaction.user_repayment_plan t3 ON t1.plan_id = t3.id
    AND t3.fund_code = %s AND t3.deadline >= %s AND t3.deadline < %s AND t2.transfer_time >= %s AND t2.transfer_time < %s"""

    sql_record_alipay = """
    SELECT t3.ref_id, t3.term_no, DATE(t2.transfer_time) repaid_at, DATE(t3.deadline) plan_deadline, t1.repay_channel,
      t1.principle real_principle, t1.mitigate_principle mitigate_principle, t1.interest real_interest,
      t1.mitigate_interest mitigate_interest, t1.service_fee real_service_fee, t1.mitigate_service_fee mitigate_service_fee,
      t1.punish real_punish, t1.mitigate_collection_relief mitigate_punish
    FROM new_transaction.xjd_repay_plan_repay_record_ref t1
    JOIN new_transaction.offline_alipay_record t2 ON t1.repay_channel = 13 AND t1.record_id = t2.id
    JOIN new_transaction.user_repayment_plan t3 ON t1.plan_id = t3.id
    AND t3.fund_code = %s AND t3.deadline >= %s AND t3.deadline < %s AND t2.transfer_time >= %s AND t2.transfer_time < %s"""

    sql_huarong_record = """
    SELECT t3.ref_id, t3.term_no, DATE(t3.xyqb_repaid_at) repaid_at, DATE(t4.deadline) plan_deadline, t1.repay_channel,
      t1.principle real_principle, t1.mitigate_principle mitigate_principle, t1.interest real_interest,
      t1.mitigate_interest mitigate_interest, t1.service_fee real_service_fee, t1.mitigate_service_fee mitigate_service_fee,
      t1.punish real_punish, t1.mitigate_collection_relief mitigate_punish
    FROM new_transaction.xjd_repay_plan_repay_record_ref t1
    JOIN new_transaction.repay_record_online t2 ON t1.repay_channel < 13
    AND t1.record_id = t2.id
    JOIN new_transaction.user_repayment_plan t3 ON t1.plan_id = t3.id
    JOIN audit.funding_repayment_record t4 ON t4.ref_id = t3.ref_id AND t4.term_no = t3.term_no
    WHERE t3.fund_code =  %s AND t4.deadline >= %s AND t4.deadline < %s AND t3.xyqb_repaid_at >= '%s' AND t3.xyqb_repaid_at < %s
    """

    file_columns = ['fund_code', 'fund_name', 'ref_id', 'term_no', 'fund_deadline', 'plan_prin_inst', '2016_prin_inst',
                    '2017_prin_inst']
    file_columns_ch = ['资金方编号', '资金方', 'ref_id', '期数', '应还资金方日', '应还资金方本息', '2016年客户实还本息', '2017年客户实还本息']

    @classmethod
    def get_record(cls, fund_code):
        df_gen = pd.read_sql(sql=cls.sql_record_online, con=cls.engine_new_transaction, params=(
            fund_code, Params.deadline_start, Params.deadline_end, Params.repaid_at_start, Params.repaid_at_end),
                             chunksize=Params.step)
        df_record = pd.DataFrame()
        for tmp in df_gen:
            df_record = df_record.append(tmp)
        df_gen = pd.read_sql(sql=cls.sql_record_bank, con=cls.engine_new_transaction, params=(
            fund_code, Params.deadline_start, Params.deadline_end, Params.repaid_at_start, Params.repaid_at_end),
                             chunksize=Params.step)
        for tmp in df_gen:
            df_record = df_record.append(tmp)
        df_gen = pd.read_sql(sql=cls.sql_record_alipay, con=cls.engine_new_transaction, params=(
            fund_code, Params.deadline_start, Params.deadline_end, Params.repaid_at_start, Params.repaid_at_end),
                             chunksize=Params.step)
        for tmp in df_gen:
            df_record = df_record.append(tmp)
        df_record.fillna(0, inplace=True)
        return df_record


def keyi(fund_code, fund_name):
    """
    科易小贷，2017年的还款需要加入应还在 28-31 的提前还款
    应还本息+ 提前还款（28号之前）- 提前应还款
    :param fund_code:
    :param fund_name:
    :return:
    """
    # --------------应还------------------
    df_gen = pd.read_sql(sql=SqlStatement.sql_fund_record,
                         params=(fund_code, Params.deadline_start, Params.deadline_end),
                         con=SqlStatement.engine_new_transaction, chunksize=Params.step)
    df_plan = pd.DataFrame()
    for tmp in df_gen:
        df_plan = df_plan.append(tmp)
    if len(df_plan) <= 0:
        return
    df_plan.ref_id = df_plan.ref_id.astype(int)
    df_plan.fillna(0, inplace=True)
    df_plan['repay_channel'] = 2
    df_plan['fund_name'] = fund_name
    df_plan.drop(['plan_principle', 'plan_interest'], axis=1, inplace=True)
    # --------------实还------------------
    df_record = SqlStatement.get_record(fund_code=fund_code)
    df_record['real_prin_inst'] = df_record['real_principle'] - df_record['mitigate_principle'] + df_record[
        'real_interest'] - df_record['mitigate_interest']
    # todo: 部分得调整
    df_record_2016 = df_record.loc[df_record.repaid_at < datetime.date(2017, 1, 1)]
    df_record_2017 = df_record.loc[df_record.repaid_at >= datetime.date(2017, 1, 1)]

    df_record_gp_2016 = df_record_2016.groupby(['ref_id', 'term_no'])['real_prin_inst'].agg(
        ['sum']).reset_index().rename(columns={'sum': '2016_prin_inst'})
    df_record_gp_2017 = df_record_2017.groupby(['ref_id', 'term_no'])['real_prin_inst'].agg(
        ['sum']).reset_index().rename(columns={'sum': '2017_prin_inst'})
    df_all = df_plan.merge(df_record_gp_2016, on=['ref_id', 'term_no'], how='left').merge(df_record_gp_2017,
                                                                                          on=['ref_id', 'term_no'],
                                                                                          how='left')
    df_all.fillna(0, inplace=True)
    df_all = df_all[SqlStatement.file_columns]
    print fund_code, fund_name
    print df_all[['plan_prin_inst', '2016_prin_inst', '2017_prin_inst']].sum()
    df_all.columns = SqlStatement.file_columns_ch
    df_all.to_csv(Params.out_path_tmp + 'tmp_%s.csv' % (fund_code,), index=None, encoding='utf8')


def huarong(fund_code, fund_name):
    pass


def xinmashang(fund_code, fund_name):
    pass


def other(fund_code, fund_name):
    if fund_code == 210:
        df_gen = pd.read_sql(sql=SqlStatement.sql_plan, con=SqlStatement.engine_new_transaction,
                             params=(fund_code, Params.deadline_start, Params.deadline_end), chunksize=Params.step)
    else:
        df_gen = pd.read_sql(sql=SqlStatement.sql_fund_record, con=SqlStatement.engine_new_transaction,
                             params=(fund_code, Params.deadline_start, Params.deadline_end), chunksize=Params.step)
    df_plan = pd.DataFrame()
    for tmp in df_gen:
        df_plan = df_plan.append(tmp)
    if len(df_plan) <= 0:
        return
    df_plan.fillna(0, inplace=True)
    df_plan['repay_channel'] = 2
    df_plan['fund_name'] = fund_name

    df_record = SqlStatement.get_record(fund_code=fund_code)
    df_record['real_prin_inst'] = df_record['real_principle'] - df_record['mitigate_principle'] + df_record[
        'real_interest'] - df_record['mitigate_interest']

    df_record_2016 = df_record.loc[df_record.repaid_at < datetime.date(2017, 1, 1)]
    df_record_2017 = df_record.loc[df_record.repaid_at >= datetime.date(2017, 1, 1)]

    df_record_gp_2016 = df_record_2016.groupby(['ref_id', 'term_no'])['real_prin_inst'].agg(
        ['sum']).reset_index().rename(columns={'sum': '2016_prin_inst'})
    df_record_gp_2017 = df_record_2017.groupby(['ref_id', 'term_no'])['real_prin_inst'].agg(
        ['sum']).reset_index().rename(columns={'sum': '2017_prin_inst'})
    df_all = df_plan.merge(df_record_gp_2016, on=['ref_id', 'term_no'], how='left').merge(df_record_gp_2017,
                                                                                          on=['ref_id', 'term_no'],
                                                                                          how='left')
    df_all.fillna(0, inplace=True)
    df_all = df_all[SqlStatement.file_columns]
    print fund_code, fund_name
    print df_all[['plan_prin_inst', '2016_prin_inst', '2017_prin_inst']].sum()
    df_all.columns = SqlStatement.file_columns_ch
    df_all.to_csv(Params.out_path_tmp + 'tmp_%s.csv' % (fund_code,), index=None, encoding='utf8')


if __name__ == '__main__':
    df_fund = pd.read_sql(sql=SqlStatement.sql_fund, con=SqlStatement.engine_new_transaction)
    fund_items = df_fund.values.tolist()
    for (fund_code, fund_name) in fund_items:
        if fund_code in (200, 290):
            keyi(fund_code, fund_name)
