# -*- coding: utf-8 -*-
import datetime
import sys
import pandas as pd
import os
import datetime
import numpy as np

pd.options.mode.chained_assignment = None

path = '/home/quant_group/vpants/finance/table/'
sys.path.append('../../../finance_out_table')
from db_con.db_connect import sql_engine

engine_audit = sql_engine('audit', 'audit').get_engine()

sql_plan_2 = '''
SELECT t2.ref_id,fund_code,term_no,DATE(deadline) deadline,service_fee,interest ,t2.loan_id,t2.real_loan_amount,t2.contract_term,date(t2.loan_paid_at) loan_paid_at ,t2.monthly_interest_rate
FROM new_transaction.user_repayment_plan t1 
JOIN audit.`loan_manifest` t2 ON t1.ref_id = t2.ref_id 
WHERE t2.is_active IN (1,-2) AND t2.funding_code IN (270,310,320,390,410,490) 
'''
sql_rate = '''
select 
  contract_term,
  contract_loan_amount,
  monthly_interest_rate,
  per_service_fee,
  new_rate 
from
  basic.loan_rate
'''

sql_real = '''
SELECT plan.ref_id,plan.term_no,ref.bill_time bill_repaid_at,
ref.`service_fee`-ref.`mitigate_service_fee` real_service_fee,ref.`interest`-ref.`mitigate_interest` real_interest 
FROM new_transaction.`xjd_repay_plan_repay_record_ref` ref 
JOIN new_transaction.`user_repayment_plan` plan ON ref.plan_id= plan.id
WHERE plan.fund_code IN (270,310,320,390,410,490) 
'''


class age_of_account():
    def __init__(self):
        today = datetime.date.today()
        self.end = datetime.date(today.year, today.month, 1)
        self.last_day = self.end + datetime.timedelta(days=-1)
        self.start = datetime.date(self.last_day.year, self.last_day.month, 1)
        self.dir_path = path + self.start.strftime('%Y%m')
        if not os.path.exists(self.dir_path):
            os.makedirs(self.dir_path)

    def cal_debt_age(self, x):
        date_end = max(x['deadline'], self.end)
        date_start = x['loan_paid_at']
        return (date_end.year - date_start.year) * 12 + (date_end.month - date_start.month)

    def age_of_account_details(self):
        df_plan_2 = pd.read_sql(sql_plan_2, engine_audit)
        # === 提取观察时间点的数据
        df_plan_2_new = df_plan_2[
            ['ref_id', 'loan_id', 'fund_code', 'term_no', 'deadline', 'service_fee', 'interest', 'contract_term',
             'real_loan_amount', 'loan_paid_at', 'monthly_interest_rate']]
        df_plan_2_new['contract_loan_amount'] = np.abs(df_plan_2_new['real_loan_amount'])
        df_plan_2_new['per_service_fee'] = np.abs(df_plan_2_new['service_fee'])
        df_plan_2_new = df_plan_2_new.loc[df_plan_2_new.loan_paid_at < self.end]

        df_rate = pd.read_sql(sql_rate, engine_audit)
        df_plan_2_new_new = pd.merge(df_plan_2_new, df_rate)

        # == 对应每一期 新费率
        df_plan_2_new_new['service_fee'] = df_plan_2_new_new['service_fee'].apply(lambda x: round(x, 2))
        df_plan_2_new_new['interest'] = df_plan_2_new_new['interest'].apply(lambda x: round(x, 2))
        # == 按照等额本息生成 服务费利息
        df_plan_2_new_new['service_fee_inst_2'] = np.ipmt(df_plan_2_new_new['new_rate'], df_plan_2_new_new['term_no'],
                                                          df_plan_2_new_new['contract_term'],
                                                          -df_plan_2_new_new['real_loan_amount'])
        df_plan_2_new_new['service_fee_inst_2'] = df_plan_2_new_new['service_fee_inst_2'].apply(lambda x: round(x, 2))

        # == 以ref_id 为维度求和
        df_plan_2_new_new_gp = df_plan_2_new_new.groupby('ref_id')[
            'service_fee', 'interest', 'service_fee_inst_2'].sum().reset_index()
        df_plan_2_new_new_gp['diff'] = np.round(
            df_plan_2_new_new_gp.service_fee + df_plan_2_new_new_gp.interest - df_plan_2_new_new_gp.service_fee_inst_2,
            2)
        df_plan_2_new_new_gp['fee_ratio'] = np.round(df_plan_2_new_new_gp['service_fee'] / (
                df_plan_2_new_new_gp['service_fee'] + df_plan_2_new_new_gp['interest']), 4)

        # =消除差异，merge 服务费占比
        df_plan_2_new_new = pd.merge(df_plan_2_new_new, df_plan_2_new_new_gp[['ref_id', 'diff', 'fee_ratio']])
        con = df_plan_2_new_new.contract_term == df_plan_2_new_new.term_no
        df_plan_2_new_new.loc[con, 'service_fee_inst_2'] += df_plan_2_new_new.loc[con]['diff']
        del df_plan_2_new_new['diff']

        # == 应还款日在观察点之前的，应还本息 初始化
        # === 注意时间
        con = df_plan_2_new_new.deadline <= self.end
        df_plan_2_new_new['service_fee_inst_2_2'] = 0
        df_plan_2_new_new['service_fee_2_2'] = 0
        df_plan_2_new_new['inst_2_2'] = 0

        # === 这儿注意下！！！！！！，规定30天差异，每月月末
        # === 2018,2,28 2018,3,30
        df_plan_2_new_new['diff_days'] = np.maximum(
            (self.last_day - df_plan_2_new_new['deadline']).dt.days, 0) / 30

        # == 应还款日在观察点之前的，
        df_plan_2_new_new.loc[con, 'service_fee_inst_2_2'] = df_plan_2_new_new.loc[con]['service_fee_inst_2']
        df_plan_2_new_new.loc[con, 'service_fee_2_2'] = df_plan_2_new_new.loc[con]['per_service_fee']
        df_plan_2_new_new.loc[con, 'inst_2_2'] = df_plan_2_new_new.loc[con]['interest']
        # == 应还款日在观察点之后的，按照天数占比
        df_plan_2_new_new.loc[~con, 'service_fee_inst_2_2'] = df_plan_2_new_new.loc[~con, 'service_fee_inst_2'] * \
                                                              df_plan_2_new_new.loc[~con, 'diff_days']
        df_plan_2_new_new.loc[~con, 'service_fee_2_2'] = df_plan_2_new_new.loc[~con, 'per_service_fee'] * \
                                                         df_plan_2_new_new.loc[~con, 'diff_days']
        df_plan_2_new_new.loc[~con, 'inst_2_2'] = df_plan_2_new_new.loc[~con, 'interest'] * df_plan_2_new_new.loc[
            ~con, 'diff_days']

        df_plan_2_new_new['service_fee_inst_2_2'] = np.round(df_plan_2_new_new['service_fee_inst_2_2'], 2)
        df_plan_2_new_new['service_fee_2_2'] = np.round(df_plan_2_new_new['service_fee_2_2'], 2)
        df_plan_2_new_new['inst_2_2'] = np.round(df_plan_2_new_new['inst_2_2'], 2)
        del df_plan_2_new_new['diff_days']

        # == service_fee_inst_2_2 拆分为 服务费和利息
        df_plan_2_new_new['inst_21'] = 0
        df_plan_2_new_new['fee_21'] = 0
        df_plan_2_new_new['fee_21'] = np.round(
            df_plan_2_new_new['service_fee_inst_2_2'] * df_plan_2_new_new['fee_ratio'], 2)
        df_plan_2_new_new['inst_21'] = np.round(df_plan_2_new_new['service_fee_inst_2_2'] - df_plan_2_new_new['fee_21'],
                                                2)

        # ===实还时间====
        # === 这儿注意下，实还时间
        df_real = pd.read_sql(sql_real, engine_audit)
        df_real.bill_repaid_at = pd.to_datetime(df_real.bill_repaid_at).dt.date

        df_real_select = df_real.ix[df_real.bill_repaid_at < self.end]
        df_real_select = df_real_select.groupby('ref_id')['real_service_fee', 'real_interest'].sum().reset_index()

        df_plan_2_new_new_gp = df_plan_2_new_new.groupby(
            ['ref_id', 'loan_id', 'fund_code', 'real_loan_amount', 'contract_term', 'loan_paid_at'])[
            'service_fee', 'interest', 'service_fee_inst_2_2', 'inst_21', 'fee_21'].sum().reset_index()
        df_plan_2_new_new_gp = pd.merge(df_plan_2_new_new_gp, df_real_select, on='ref_id', how='left')
        df_plan_2_new_new_gp['real_service_fee'].fillna(0, inplace=True)
        df_plan_2_new_new_gp['real_interest'].fillna(0, inplace=True)
        df_plan_2_new_new_gp['real_service_fee_inst'] = np.round(
            df_plan_2_new_new_gp.real_service_fee + df_plan_2_new_new_gp.real_interest, 2)

        df_plan_2_new_new_gp[u'应收'] = np.round(
            np.maximum(df_plan_2_new_new_gp['service_fee_inst_2_2'] - df_plan_2_new_new_gp['real_service_fee_inst'], 0),
            2)
        df_plan_2_new_new_gp[u'预收'] = np.round(
            np.maximum(df_plan_2_new_new_gp['real_service_fee_inst'] - df_plan_2_new_new_gp['service_fee_inst_2_2'], 0),
            2)

        df_plan_2_new_new_gp[u'应收利息1'] = np.round(
            np.maximum(df_plan_2_new_new_gp['inst_21'] - df_plan_2_new_new_gp['real_interest'], 0), 2)
        df_plan_2_new_new_gp[u'应收服务费1'] = np.round(
            np.maximum(df_plan_2_new_new_gp['fee_21'] - df_plan_2_new_new_gp['real_service_fee'], 0), 2)
        df_plan_2_new_new_gp[u'预收利息1'] = np.round(
            np.maximum(df_plan_2_new_new_gp['real_interest'] - df_plan_2_new_new_gp['inst_21'], 0), 2)
        df_plan_2_new_new_gp[u'预收服务费1'] = np.round(
            np.maximum(df_plan_2_new_new_gp['real_service_fee'] - df_plan_2_new_new_gp['fee_21'], 0), 2)

        df_plan_2_new_new_gp_loan = df_plan_2_new_new_gp.groupby('loan_id')['real_loan_amount'].sum().reset_index()
        df_plan_2_new_new_gp_loan = df_plan_2_new_new_gp_loan.loc[df_plan_2_new_new_gp_loan.real_loan_amount != 0]

        df_plan_2_new_new_gp = df_plan_2_new_new_gp.loc[
            df_plan_2_new_new_gp.loan_id.isin(df_plan_2_new_new_gp_loan.loan_id)]

        df_plan_2_new_new_gp = df_plan_2_new_new_gp[
            ['ref_id', 'loan_id', 'fund_code', 'real_loan_amount', 'contract_term', 'loan_paid_at', 'service_fee',
             'interest', 'real_service_fee', 'real_interest', 'service_fee_inst_2_2', 'inst_21', 'fee_21', u'应收', u'预收',
             u'应收利息1', u'应收服务费1',
             u'预收利息1', u'预收服务费1']]
        df_plan_2_new_new_gp.columns = ['ref_id', 'loan_id', 'fund_code', u'放款金额', u'总期数', u'放款时间', u'总服务费', u'总利息',
                                        u'实还服务费', u'实还利息', u'应确认服务费利息', u'应确认利息1', u'应确认服务费1', u'应收', u'预收', u'应收利息1',
                                        u'应收服务费1',
                                        u'预收利息1', u'预收服务费1']

        # df_plan_2_new_new_gp.to_csv(u'收入确认表_渤海系_20180631.csv', index=None)

        # === 按照账龄 === ,朱朱要的是这块数据
        # === 考虑实还=====
        df_real_select = df_real.ix[df_real.bill_repaid_at < self.end]
        df_real_select = df_real_select.groupby(['ref_id', 'term_no']).agg(
            {'bill_repaid_at': max, 'real_service_fee': sum, 'real_interest': sum})
        df_real_select.reset_index(inplace=True)

        df_plan_2_new_new3 = df_plan_2_new_new.loc[
            ~df_plan_2_new_new.loan_id.isin(df_plan_2_new_new.loc[df_plan_2_new_new.real_loan_amount < 0, 'loan_id'])]
        df_plan_2_new_new3 = df_plan_2_new_new3[
            ['fund_code', 'ref_id', 'loan_id', 'term_no', 'loan_paid_at', 'deadline', 'service_fee', 'interest',
             'fee_21', 'inst_21', 'contract_term', 'service_fee_inst_2_2']]

        # === 收入确认表中 应收服务费1
        df_plan_2_new_new3 = pd.merge(df_plan_2_new_new3, df_real_select, on=['ref_id', 'term_no'], how='left')
        df_plan_2_new_new3 = df_plan_2_new_new3.loc[
            df_plan_2_new_new3.ref_id.isin(df_plan_2_new_new_gp.loc[df_plan_2_new_new_gp[u'应收服务费1'] > 0]['ref_id'])]
        df_plan_2_new_new3['real_interest'].fillna(0, inplace=True)
        df_plan_2_new_new3['real_service_fee'].fillna(0, inplace=True)
        df_plan_2_new_new3[u'应收服务费1'] = df_plan_2_new_new3['fee_21'] - df_plan_2_new_new3['real_service_fee']

        # ===== 提供给财务的按照实还计算的账龄=============
        df_plan_2_new_new3['loan_age'] = df_plan_2_new_new3.apply(lambda x: self.cal_debt_age(x), axis=1)
        df_plan_2_new_new3['deadline_month'] = df_plan_2_new_new3['deadline'].apply(lambda x: x.strftime('%Y-%m'))
        gp1 = df_plan_2_new_new3.groupby(['deadline_month', 'loan_age'])[
            'fee_21', 'inst_21', 'real_interest', 'real_service_fee', u'应收服务费1'].agg('sum').reset_index()
        gp1.to_excel(os.path.join(self.dir_path, u'渤海-应还年月-账龄-应收服务费1-{}.xlsx'.format(self.start.strftime('%Y%m'))),
                     index=None)

        df_1 = df_plan_2_new_new3.loc[df_plan_2_new_new3.loan_paid_at < datetime.date(2018, 2, 1)]
        gp2 = df_1.groupby(['deadline_month', 'loan_age'])[
            'fee_21', 'inst_21', 'real_interest', 'real_service_fee', u'应收服务费1'].agg('sum').reset_index()

        gp2.to_excel(
            os.path.join(self.dir_path, u'渤海-应还年月-账龄-应收服务费1-放款时间截止-{}.xlsx'.format(self.start.strftime('%Y%m'))),
            index=None)


if __name__ == '__main__':
    age_of_account().age_of_account_details()
    print('======================bohai collection_behalf done===================================')
