import math
from datetime import datetime as dt
from typing import List

import pandas as pd
from py_jftech import component, autowired

from api import RoboReportor


@component(bean_name='month-div-rate-report')
class MonthDivRateReportor(RoboReportor):

    @autowired(names={'hold_reportor': 'hold-report', 'benchmark': 'benckmark-report'})
    def __init__(self, hold_reportor: RoboReportor = None, benchmark: RoboReportor = None):
        self._hold_reportor = hold_reportor
        self._benchmark = benchmark

    @property
    def report_name(self) -> str:
        return '月度配息率比较'

    def load_report(self, max_date=dt.today(), min_date=None) -> List[dict]:
        holds = pd.DataFrame(self._hold_reportor.load_report(max_date=max_date, min_date=min_date))
        benchmark = pd.DataFrame(self._benchmark.load_report(max_date=max_date, min_date=min_date))
        if not holds.empty and not benchmark.empty:
            holds['divrobo'] = round(holds['port_div'] * 12 / holds['real_av'].shift() * 100, 2)
            holds = holds[['date', 'divrobo']]
            holds.replace(0, math.nan, inplace=True)
            holds.dropna(inplace=True)
            holds['date'] = holds['date'].dt.to_period('m')
            holds.set_index('date', inplace=True)

            benchmark['alligam'] = round(benchmark['alligam_div'] * 12 / benchmark['alligam_av'].shift() * 100, 2)
            benchmark = benchmark[['date', 'alligam']]
            benchmark.replace(0, math.nan, inplace=True)
            benchmark.dropna(inplace=True)
            benchmark['date'] = benchmark['date'].dt.to_period('m')
            benchmark.set_index('date', inplace=True)

            result = holds.join(benchmark)
            result.reset_index(inplace=True)
            return result.to_dict('records')
        return []


@component(bean_name='year-div-rate-report')
class YearDivRateReportor(RoboReportor):

    @autowired(names={'month_div_rate': 'month-div-rate-report'})
    def __init__(self, month_div_rate: RoboReportor = None):
        self._month_div_rate = month_div_rate

    @property
    def report_name(self) -> str:
        return '年度配息率比较'

    def load_report(self, max_date=dt.today(), min_date=None) -> List[dict]:
        month_datas = pd.DataFrame(self._month_div_rate.load_report(max_date=max_date, min_date=min_date))
        if not month_datas.empty:
            result = pd.DataFrame(columns=month_datas.columns)
            month_datas['year'] = month_datas['date'].dt.year
            month_datas.set_index('date', inplace=True)
            result = round(month_datas.groupby(by='year').mean(), 2)
            result.loc['平均'] = round(month_datas.drop(columns='year').mean(), 2)
            result.reset_index(inplace=True)
            return result.to_dict('records')
        return []