from abc import ABC, abstractmethod
import pandas as pd
import numpy as np
import datetime

class BaseReporter(ABC):
    def __init__(self):
        self.indicators = {}

    @abstractmethod
    def generate_report(self, df_analysis, symbol, market, metrics, output_dir):
        """
        Generates and saves financial reports in different formats (e.g., Markdown, HTML).
        This method must be implemented by subclasses.
        """
        pass

    def _generate_markdown_content(self, df: pd.DataFrame, market: str, symbol: str, metrics: dict = {}) -> str:
        if df.empty:
            return f"No breakdown data available for {market} {symbol}"

        df = self._preprocess_data(df, market)
        headers = self._get_headers(df)
        
        md = []
        md.append(self._generate_md_company_info(symbol, metrics, market))
        md.append("\n")

        for group_name, items in self.indicators.items():
            md.append(f"## {group_name}")
            
            header_line = "| 指标 | " + " | ".join(headers) + " |"
            md.append(header_line)
            separator_line = "|" + "|".join([":---"] + ["--:"] * len(headers)) + "|"
            md.append(separator_line)

            for key, label, fmt_type in items:
                row_data = [label]
                for _, row_series in df.iterrows():
                    val = row_series.get(key)
                    row_data.append(self._format_value(val, fmt_type))
                md.append("| " + " | ".join(row_data) + " |")
            md.append("\n")

        return "\n".join(md)

    def _format_value(self, val, fmt_type):
        if pd.isna(val) or val is None:
            return "-"
        
        disp_val = ""
        if fmt_type == 'percent' or fmt_type.startswith('percent_'):
            disp_val = f"{val:.2%}"
        elif fmt_type == 'currency_yi_market':
            val_yi = val / 100000000
            if abs(val_yi) > 1000:
                disp_val = f"{val_yi:,.0f}"
            else:
                disp_val = f"{val_yi:,.2f}"
        elif fmt_type.startswith('currency_yi'):
            disp_val = f"{val/100000000:,.2f}"
        elif fmt_type == 'currency_wan':
            disp_val = f"{val/10000:,.2f}"
        elif fmt_type == 'int' or fmt_type.startswith('int_'):
            disp_val = f"{int(val):,}"
        elif fmt_type == 'float' or fmt_type.startswith('float_'):
            disp_val = f"{val:.2f}"
        else:
            disp_val = f"{val}"
        return disp_val

    def _generate_md_company_info(self, symbol, metrics, market):
        return "" # Implemented in subclasses

    def _preprocess_data(self, df, market):
        # Default behavior: sort by date
        df = df.sort_values('date_str', ascending=False)
        return df

    def _get_headers(self, df):
        headers = []
        for d in df['date_str']:
            s = str(d)
            if len(s) == 8:
                headers.append(f"{s[:4]}-{s[4:6]}-{s[6:]}")
            else:
                headers.append(s)
        return headers
