from .cn_analyzer import CN_Analyzer
import pandas as pd

class HK_Analyzer(CN_Analyzer):
    def __init__(self):
        # We inherit from CN_Analyzer to share the core calculation logic
        super().__init__()
        self.market = 'HK'
        
        # Mapping aligned with HkFetcher (which uses standardized names from iFinD _oas indicators)
        self.mapping = {
            'income': {
                'revenue': 'revenue',
                'net_income': 'net_income',
                'gross_profit': 'gross_profit',
                'total_profit': 'total_profit',
                'sga_exp': 'sga_exp',
                'selling_marketing_exp': 'selling_exp',
                'ga_exp': 'admin_exp',
                'rd_exp': 'rd_exp',
                'income_tax': 'income_tax',
                'ebit': 'ebit',
                'depreciation': 'depreciation'
            },
            'balance': {
                'total_equity': 'total_equity',
                'total_assets': 'total_assets',
                'total_liabilities': 'total_liabilities',
                'cash': 'cash',
                'receivables': 'receivables',
                'inventory': 'inventory',
                'fixed_assets': 'fixed_assets',
                'goodwill': 'goodwill',
                'short_term_debt': 'short_term_debt',
                'long_term_debt': 'long_term_debt',
                'prepayment': 'prepayment',
                'long_term_investments': 'lt_invest'
            },
            'cashflow': {
                'ocf': 'ocf',
                'capex': 'capex',
                'dividends': 'dividends'
            }
        }

    def _post_process_columns(self, df, type):
        if market_type := self.mapping.get(type):
            for col in market_type.values():
                if col in df.columns:
                    df[col] = pd.to_numeric(df[col], errors='coerce')

        df = super()._post_process_columns(df, type)
        
        if type == 'balance':
            # Sum long_term_debt and long_term_borrowings if they exist separately
            if 'long_term_debt' not in df.columns: df['long_term_debt'] = 0
            if 'long_term_borrowings' in df.columns:
                df['long_term_debt'] = df['long_term_debt'].fillna(0) + df['long_term_borrowings'].fillna(0)
                
            if 'short_term_debt' not in df.columns: df['short_term_debt'] = 0
            if 'short_term_borrowings' in df.columns:
                df['short_term_debt'] = df['short_term_debt'].fillna(0) + df['short_term_borrowings'].fillna(0)

        return df

    def calculate_indicators(self, df_merged, market_metrics, historical_metrics):
        # EBIT fallback for ROIC (Operating Profit + Depreciation if available, or just Operating Profit)
        # We do this BEFORE super() so CN_Analyzer can use 'ebit' for ROIC
        if 'ebit' not in df_merged.columns or df_merged['ebit'].isna().all():
            if 'operating_profit' in df_merged.columns:
                dep = df_merged.get('depreciation', pd.Series(0.0, index=df_merged.index)).fillna(0)
                df_merged['ebit'] = df_merged['operating_profit'] + dep

        # COGS = Revenue - Gross Profit (fallback)
        if 'revenue' in df_merged.columns and 'gross_profit' in df_merged.columns:
            if 'cogs' not in df_merged.columns or df_merged['cogs'].isnull().all():
                df_merged['cogs'] = df_merged['revenue'] - df_merged['gross_profit']
        
        # Use CN_Analyzer's calculation
        # Filter market_metrics to avoid overwriting with 0 (e.g. on weekends)
        safe_metrics = {k: v for k, v in market_metrics.items() if v and v != 0}
        df_merged = super().calculate_indicators(df_merged, safe_metrics, historical_metrics)

        # Adjust Days and Turnover for interim reports
        if 'date_str' in df_merged.columns:
            for idx in df_merged.index:
                date_str = str(df_merged.at[idx, 'date_str'])
                factor = 1.0
                if date_str.endswith('0630'): factor = 2.0
                elif date_str.endswith('0331'): factor = 4.0
                elif date_str.endswith('0930'): factor = 4.0/3.0
                
                if factor != 1.0:
                    for col in ['InventoryDays', 'ReceivablesDays', 'PayablesDays']:
                        if col in df_merged.columns:
                             val = df_merged.at[idx, col]
                             if pd.notna(val): df_merged.at[idx, col] = val / factor
                    for col in ['FixedAssetsTurnover', 'TotalAssetTurnover']:
                        if col in df_merged.columns:
                             val = df_merged.at[idx, col]
                             if pd.notna(val): df_merged.at[idx, col] = val * factor
        
        # Override SG&A Ratio for HK (Similar to JP)
        has_sga = False
        if 'sga_exp' in df_merged.columns and 'revenue' in df_merged.columns:
            if df_merged['sga_exp'].notna().any() and (df_merged['sga_exp'] != 0).any():
                df_merged['SgaRatio'] = self._safe_div(df_merged['sga_exp'], df_merged['revenue'])
                has_sga = True
        
        if not has_sga:
             sga_sum = 0
             if 'selling_exp' in df_merged.columns: sga_sum = sga_sum + df_merged['selling_exp'].fillna(0)
             if 'admin_exp' in df_merged.columns: sga_sum = sga_sum + df_merged['admin_exp'].fillna(0)
             if 'revenue' in df_merged.columns:
                 df_merged['SgaRatio'] = self._safe_div(sga_sum, df_merged['revenue'])

        # Recalculate OtherExpenseRatio using fixed SgaRatio
        if 'GrossMargin' in df_merged.columns and 'NetMargin' in df_merged.columns:
            other_ratio = df_merged['GrossMargin'] - df_merged['NetMargin']
            if 'SgaRatio' in df_merged.columns:
                other_ratio = other_ratio - df_merged['SgaRatio'].fillna(0)
            if 'RDRatio' in df_merged.columns:
                other_ratio = other_ratio - df_merged['RDRatio'].fillna(0)
            df_merged['OtherExpenseRatio'] = other_ratio

        # HK Specific Tax Rate fallback if total_profit is weird
        if 'income_tax' in df_merged.columns and 'net_income' in df_merged.columns:
            if 'TaxRate' not in df_merged.columns or df_merged['TaxRate'].isnull().all():
                ebt_approx = df_merged['net_income'] + df_merged['income_tax']
                df_merged['TaxRate'] = self._safe_div(df_merged['income_tax'], ebt_approx)

        # Recalculate Market Metrics if needed
        if 'MarketCap' in df_merged.columns:
            dep = df_merged.get('depreciation', pd.Series(0.0, index=df_merged.index)).fillna(0)
            if 'operating_profit' in df_merged.columns:
                df_merged['ebit'] = df_merged['operating_profit'] + dep

            # PE = MarketCap / net_income
            if 'net_income' in df_merged.columns:
                # Annualize income for PE calculation
                adjusted_income = df_merged['net_income'].copy()
                if 'date_str' in df_merged.columns:
                    for idx in df_merged.index:
                        date_str = str(df_merged.at[idx, 'date_str'])
                        if date_str.endswith('0630'): adjusted_income.at[idx] *= 2.0
                        elif date_str.endswith('0331'): adjusted_income.at[idx] *= 4.0
                        elif date_str.endswith('0930'): adjusted_income.at[idx] *= (4.0/3.0)

                calc_pe = self._safe_div(df_merged['MarketCap'], adjusted_income)
                # Always trust calculation if current PE is 0 or missing
                pe_col = df_merged.get('PE', pd.Series(0.0, index=df_merged.index))
                cond = (pe_col == 0) | pe_col.isna()
                df_merged['PE'] = pe_col.where(~cond, calc_pe)

            # PB = MarketCap / total_equity
            if 'total_equity' in df_merged.columns:
                calc_pb = self._safe_div(df_merged['MarketCap'], df_merged['total_equity'])
                pb_col = df_merged.get('PB', pd.Series(0.0, index=df_merged.index))
                cond = (pb_col == 0) | pb_col.isna()
                df_merged['PB'] = pb_col.where(~cond, calc_pb)
            
            # Dividend Yield = (Dividends / MarketCap) * 100
            if 'dividends' in df_merged.columns:
                calc_yield = self._safe_div(df_merged['dividends'], df_merged['MarketCap']) * 100
                yield_col = df_merged.get('DividendYield', pd.Series(0.0, index=df_merged.index))
                cond = (yield_col == 0) | yield_col.isna()
                df_merged['DividendYield'] = yield_col.where(~cond, calc_yield)

        # Employees
        if 'employee_count' in df_merged.columns:
            df_merged['Employees'] = df_merged['employee_count']
            if 'revenue' in df_merged.columns:
                df_merged['RevenuePerEmp'] = self._safe_div(df_merged['revenue'], df_merged['employee_count'])
            if 'net_income' in df_merged.columns:
                df_merged['ProfitPerEmp'] = self._safe_div(df_merged['net_income'], df_merged['employee_count'])
        
        # Shareholders
        if 'shareholders' in df_merged.columns:
            df_merged['Shareholders'] = df_merged['shareholders']

        return df_merged
