import time

from jinja2 import PackageLoader, Environment

from app.service.portfolio_diagnose import portfolio_diagnose
from app.service.result_service import UserCustomerResultAdaptor
import numpy as np

# 准备数据
from app.utils.draw import draw_month_return_chart, draw_contribution_chart
from app.utils.radar_chart import gen_radar_chart


class DataIntegrate:
    def __init__(self, ifa_id='USER_INFO15914346866762', customer_id='202009281545001'):
        self.user_customer = UserCustomerResultAdaptor(ifa_id, customer_id)
        self.df = self.user_customer.calculate_total_data()
        self.d = self.user_customer.calculate_group_result_data()
        # 组合数据
        self.group_result = self.d["default"]
        # 几月综述部分
        self.get_summarize()
        # 月度回报
        self.get_month_return()
        # 旧持仓组合点评
        self.comments_on_position_portfolio()
        # 贡献分解
        self.contribution_deco()
        # 个基点评
        self.single_fund_comment()
        # 旧相关性
        self.get_old_correlation()
        # 新增基金
        self.propose_fund()
        # 目标与业绩
        self.objectives_performance(self.group_result)
        # 渲染模版
        self.render_data()

    def get_summarize(self):
        """几月综述部分."""
        self.total_cost = self.df["total_cost"]/10000
        self.now_yield = round((self.df['cumulative_return']-1)*100,2)
        self.index_yield = round((self.df["index_result"]["return_ratio"]-1)*100, 2)
        self.now_withdrawal = round(self.df["max_drawdown"][0]*100,2)
        self.index_withdrawal = round(self.df["index_result"]["max_drawdown"][0]*100, 2)

    def get_month_return(self):
        """月度回报."""
        xlabels, product_list, cumulative = self.user_customer.get_month_return_chart()
        self.monthly_return_performance_pic = draw_month_return_chart(xlabels, product_list, cumulative)

    def comments_on_position_portfolio(self):
        """旧持仓组合点评."""
        self.old_evaluation = portfolio_diagnose.old_evaluation('default', self.d, self.user_customer)

    def contribution_deco(self):
        """贡献分解."""
        g_data = self.group_result["contribution_decomposition"]
        self.contribution_decomposition = draw_contribution_chart(g_data['xlabels'], g_data['product_list'], g_data['cumulative'])

    def single_fund_comment(self):
        """个基点评."""
        self.single_fund_data_list = []
        portfolio_evaluation = portfolio_diagnose.old_portfolio_evaluation()
        radar_chart_data = portfolio_diagnose.single_fund_radar()
        for i in range(len(portfolio_evaluation)):
            self.single_fund_data_list.append({
                'fund_name': portfolio_evaluation[i]['name'],
                'status': '保留',
                'evaluation': portfolio_evaluation[i]['data'],
                'radar_chart_path': gen_radar_chart(radar_chart_data[i])
            })

# 调仓建议

# 收益比较


    def get_old_correlation(self):
        """旧相关性分析."""
        old_correlation = portfolio_diagnose.old_correlation
        old_correlation_columns = old_correlation.columns.tolist()
        old_correlation_values = old_correlation.values.tolist()
        self.old_correlation = list(zip(range(1, len(old_correlation_columns)+1), old_correlation_columns, old_correlation_values))


    def propose_fund(self):
        """新增基金"""
        # 优化组合建议1 -- 新增基金
        self.propose_fund_data_list = []
        propose_fund_evaluation = portfolio_diagnose.propose_fund_evaluation()
        propose_radar_chart_data = portfolio_diagnose.propose_fund_radar()
        for i in range(len(propose_fund_evaluation)):
            self.propose_fund_data_list.append({
                'fund_name': propose_fund_evaluation[i]['name'],
                'status': '保留',
                'evaluation': propose_fund_evaluation[i]['data'],
                'radar_chart_path': gen_radar_chart(propose_radar_chart_data[i])
            })

    def objectives_performance(self, group_result):
        """目标与业绩"""
        self.now_month_income = int(group_result["cur_month_profit"])   # 本月收益
        self.now_year_income = int(group_result["cur_year_profit"])   # 今年累计收益
        self.totoal_rate_of_return = round((group_result['cumulative_return']-1)*100, 2)       # 累计收益率
        self.month_rise = round(group_result["cur_month_profit_ratio"]*100, 2)       # 本月涨幅
        self.year_totoal_rate_of_return = round(group_result["cur_year_profit_ratio"]*100, 2)        # 今年累计收益率
        self.annualised_return = round(group_result["return_ratio_year"]*100, 2)     # 年化收益率
        self.volatility = round(group_result["volatility"]*100, 2)
        self.max_withdrawal = round(group_result["max_drawdown"][0]*100, 2)
        self.sharpe_ratio = round(group_result["sharpe"], 2)
        self.cost_of_investment = int(group_result["total_cost"])    # 投资成本
        self.final_balance = int(group_result["total_cost"] + group_result["cumulative_profit"])    # 期末资产
        self.total_profit = int(group_result["cumulative_profit"])  # 累计盈利

        self.index_section_return = round((group_result["index_result"]["return_ratio"]-1)*100, 2)
        self.index_annualised_return = round(group_result["index_result"]["return_ratio_year"]*100, 2)     # 年化收益率
        self.index_volatility = round(group_result["index_result"]["volatility"]*100, 2)
        self.index_max_withdrawal = round(group_result["index_result"]["max_drawdown"][0]*100, 2)
        self.index_sharpe_ratio = round(group_result["index_result"]["sharpe"], 2)

        self.group_nav_info = group_result["group_nav_info"]
        self.group_hoding_info = group_result["group_hoding_info"]


    def render_data(self):
        # 全部数据
        data = {'customer_name': '成龙', 'customer_gender': '女',
                'year_month': '2020年10月', 'ifa_company': '飞度工作室',
                'title': '10月综述', 'brand_name': '飞度工作室',
                'customer_old': 42, 'customer_level': '平衡型',
                'position_years': '5年', 'planned_allocation_amount': 2000.00,
                'now_allocation_amount': self.total_cost, 'now_yield': self.now_yield, 'index_yield': self.index_yield,
                'expected_yield': 20,
                'now_withdrawal': self.now_withdrawal, 'index_withdrawal': self.index_withdrawal, 'expected_withdrawal': 20,
                'now_year_income': self.now_year_income, 'now_month_income': self.now_month_income,
                'totoal_rate_of_return': self.totoal_rate_of_return,
                'month_rise': self.month_rise, 'year_totoal_rate_of_return': self.year_totoal_rate_of_return,
                'annualised_return': self.annualised_return, 'cost_of_investment': self.cost_of_investment,
                'final_balance': self.final_balance, 'total_profit': self.total_profit,
                'latest_worth_day': '2020-11-05',

                'index_comparison': {'section_return': self.totoal_rate_of_return, 'annualized_returns': self.annualised_return,
                                     'volatility': self.volatility, 'max_withdrawal': self.max_withdrawal,
                                     'sharpe_ratio': self.sharpe_ratio},
                'index_comparison_500': {'section_return': self.index_section_return,
                                         'annualized_returns': self.index_annualised_return,
                                         'volatility': self.index_volatility, 'max_withdrawal': self.index_max_withdrawal,
                                         'sharpe_ratio': self.index_sharpe_ratio},
                'monthly_return_performance_pic': self.monthly_return_performance_pic,
                'group_nav_info': self.group_nav_info,
                'group_hoding_info': self.group_hoding_info,
                'old_evaluation': self.old_evaluation,
                'contribution_decomposition': self.contribution_decomposition,
                'single_fund_data_list': self.single_fund_data_list,
                'old_correlation': self.old_correlation,
                'propose_fund_data_list': self.propose_fund_data_list
                }
        # 开始渲染html模板
        env = Environment(loader=PackageLoader('app', 'templates'))  # 创建一个包加载器对象
        template = env.get_template('monthReport.html')  # 获取一个模板文件
        monthReport_html = template.render(data)  # 渲染

        # 保存 monthReport_html
        save_file = "app/html/monthReport.html"
        with open(save_file, 'w', encoding="utf-8") as f:
            f.write(monthReport_html)

if __name__ == '__main__':
    start = time.time()
    DataIntegrate()
    print('耗时{}秒'.format(round(time.time()-start, 2)))
