import os
from datetime import datetime as dt
from typing import List

import pandas as pd
from py_jftech import component, autowired, get_config, get_instance_name, get_project_path, format_date

from api import RoboReportor, RoboExportor


def include_report():
    return get_config(__name__)['include-report']


@component(bean_name='backtest-export')
class BacktestExportor(RoboExportor):

    @autowired(includes={'reportors': include_report()})
    def __init__(self, reportors: List[RoboReportor] = None):
        reportors = {get_instance_name(x): x for x in reportors}
        self._reportors: List[RoboReportor] = [reportors[x] for x in include_report()]
        self._config = get_config(__name__)

    @property
    def save_path(self):
        save_path: str = self._config['save-path']
        if save_path.startswith('.'):
            return os.path.abspath(os.path.join(os.path.dirname(__file__), save_path))
        elif save_path.startswith('/'):
            return os.path.abspath(save_path)
        return os.path.abspath(os.path.join(get_project_path(), save_path))

    @property
    def exist_build(self):
        return self._config['exist-build']

    @property
    def file_name(self):
        return self._config['file-name'] if 'file-name' in self._config else 'backtest'

    def export(self, max_date=dt.today(), min_date=None):
        root = self.save_path
        os.makedirs(root, exist_ok=True)
        filename = f"{self.file_name}_{format_date(max_date)}.xlsx"
        if min_date:
            filename = f"{self.file_name}_{format_date(min_date)}_to_{format_date(max_date)}.xlsx"
        file = os.path.join(root, filename)
        if os.path.exists(file):
            if not self.exist_build:
                return file
            os.remove(file)
        with pd.ExcelWriter(file) as writer:
            for reportor in self._reportors:
                datas = pd.DataFrame(reportor.load_report(max_date=max_date, min_date=min_date))
                if not datas.empty:
                    datas.to_excel(writer, sheet_name=reportor.report_name, index=False)
        return file