"""利润表数据接口 (VIP 版本)

使用 Tushare VIP 接口 (income_vip) 获取利润表数据。
按季度同步，一次请求获取一个季度的全部上市公司数据。

接口说明:
- income_vip: 获取某一季度全部上市公司利润表数据
- 需要 5000 积分才能调用
- period 参数为报告期（季度最后一天，如 20231231）

使用方式:
    # 同步利润表数据
    from src.data.api_wrappers.financial_data.api_income import IncomeQuarterSync, sync_income

    # 方式1: 使用类
    syncer = IncomeQuarterSync()
    syncer.sync_incremental()  # 增量同步
    syncer.sync_full()  # 全量同步

    # 方式2: 使用便捷函数
    sync_income()  # 增量同步
    sync_income(force_full=True)  # 全量同步
"""

from typing import Optional
import pandas as pd

from src.data.client import TushareClient
from src.data.api_wrappers.base_financial_sync import (
    QuarterBasedSync,
    sync_financial_data,
    preview_financial_sync,
)


class IncomeQuarterSync(QuarterBasedSync):
    """利润表季度同步实现。

    使用 income_vip 接口按季度获取全部上市公司利润表数据。

    表结构: financial_income
    主键: (ts_code, end_date)
    """

    table_name = "financial_income"
    api_name = "income_vip"

    # 目标报表类型：默认只同步合并报表
    TARGET_REPORT_TYPE = "1"

    # 表结构定义
    TABLE_SCHEMA = {
        "ts_code": "VARCHAR(16) NOT NULL",
        "ann_date": "DATE",
        "f_ann_date": "DATE",
        "end_date": "DATE NOT NULL",
        "report_type": "INTEGER",
        "comp_type": "INTEGER",
        "end_type": "VARCHAR(10)",
        "basic_eps": "DOUBLE",
        "diluted_eps": "DOUBLE",
        "total_revenue": "DOUBLE",
        "revenue": "DOUBLE",
        "int_income": "DOUBLE",
        "prem_earned": "DOUBLE",
        "comm_income": "DOUBLE",
        "n_commis_income": "DOUBLE",
        "n_oth_income": "DOUBLE",
        "n_oth_b_income": "DOUBLE",
        "prem_income": "DOUBLE",
        "out_prem": "DOUBLE",
        "une_prem_reser": "DOUBLE",
        "reins_income": "DOUBLE",
        "n_sec_tb_income": "DOUBLE",
        "n_sec_uw_income": "DOUBLE",
        "n_asset_mg_income": "DOUBLE",
        "oth_b_income": "DOUBLE",
        "fv_value_chg_gain": "DOUBLE",
        "invest_income": "DOUBLE",
        "ass_invest_income": "DOUBLE",
        "forex_gain": "DOUBLE",
        "total_cogs": "DOUBLE",
        "oper_cost": "DOUBLE",
        "int_exp": "DOUBLE",
        "comm_exp": "DOUBLE",
        "biz_tax_surchg": "DOUBLE",
        "sell_exp": "DOUBLE",
        "admin_exp": "DOUBLE",
        "fin_exp": "DOUBLE",
        "assets_impair_loss": "DOUBLE",
        "prem_refund": "DOUBLE",
        "compens_payout": "DOUBLE",
        "reser_insur_liab": "DOUBLE",
        "div_payt": "DOUBLE",
        "reins_exp": "DOUBLE",
        "oper_exp": "DOUBLE",
        "compens_payout_refu": "DOUBLE",
        "insur_reser_refu": "DOUBLE",
        "reins_cost_refund": "DOUBLE",
        "other_bus_cost": "DOUBLE",
        "operate_profit": "DOUBLE",
        "non_oper_income": "DOUBLE",
        "non_oper_exp": "DOUBLE",
        "nca_disploss": "DOUBLE",
        "total_profit": "DOUBLE",
        "income_tax": "DOUBLE",
        "n_income": "DOUBLE",
        "n_income_attr_p": "DOUBLE",
        "minority_gain": "DOUBLE",
        "oth_compr_income": "DOUBLE",
        "t_compr_income": "DOUBLE",
        "compr_inc_attr_p": "DOUBLE",
        "compr_inc_attr_m_s": "DOUBLE",
        "ebit": "DOUBLE",
        "ebitda": "DOUBLE",
        "insurance_exp": "DOUBLE",
        "undist_profit": "DOUBLE",
        "distable_profit": "DOUBLE",
        "rd_exp": "DOUBLE",
        "fin_exp_int_exp": "DOUBLE",
        "fin_exp_int_inc": "DOUBLE",
        "transfer_surplus_rese": "DOUBLE",
        "transfer_housing_imprest": "DOUBLE",
        "transfer_oth": "DOUBLE",
        "adj_lossgain": "DOUBLE",
        "withdra_legal_surplus": "DOUBLE",
        "withdra_legal_pubfund": "DOUBLE",
        "withdra_biz_devfund": "DOUBLE",
        "withdra_rese_fund": "DOUBLE",
        "withdra_oth_ersu": "DOUBLE",
        "workers_welfare": "DOUBLE",
        "distr_profit_shrhder": "DOUBLE",
        "prfshare_payable_dvd": "DOUBLE",
        "comshare_payable_dvd": "DOUBLE",
        "capit_comstock_div": "DOUBLE",
        "net_after_nr_lp_correct": "DOUBLE",
        "credit_impa_loss": "DOUBLE",
        "net_expo_hedging_benefits": "DOUBLE",
        "oth_impair_loss_assets": "DOUBLE",
        "total_opcost": "DOUBLE",
        "amodcost_fin_assets": "DOUBLE",
        "oth_income": "DOUBLE",
        "asset_disp_income": "DOUBLE",
        "continued_net_profit": "DOUBLE",
        "end_net_profit": "DOUBLE",
        "update_flag": "VARCHAR(1)",
    }

    # 索引定义（不要创建唯一索引）
    # 注意：财务数据可能发生多次修正，不设置主键和唯一索引
    TABLE_INDEXES = [
        ("idx_financial_income_ts_code", ["ts_code"]),
        ("idx_financial_income_end_date", ["end_date"]),
        ("idx_financial_income_ts_period", ["ts_code", "end_date", "report_type"]),
    ]

    def __init__(self):
        """初始化利润表同步器。"""
        super().__init__()
        self._fields = None  # 默认返回全部字段

    def fetch_single_quarter(self, period: str) -> pd.DataFrame:
        """获取单季度的全部上市公司利润表数据。

        Args:
            period: 报告期，季度最后一天日期（如 '20231231'）

        Returns:
            包含该季度全部上市公司利润表数据的 DataFrame
        """
        params = {"period": period}

        if self._fields:
            params["fields"] = self._fields

        return self.client.query(self.api_name, **params)


# =============================================================================
# 便捷函数
# =============================================================================


def sync_income(
    force_full: bool = False,
    dry_run: bool = False,
) -> list:
    """同步利润表数据（便捷函数）。

    Args:
        force_full: 若为 True，强制全量同步
        dry_run: 若为 True，仅预览不写入

    Returns:
        同步结果列表

    Example:
        >>> # 增量同步
        >>> sync_income()
        >>>
        >>> # 全量同步
        >>> sync_income(force_full=True)
        >>>
        >>> # 预览
        >>> sync_income(dry_run=True)
    """
    return sync_financial_data(IncomeQuarterSync, force_full, dry_run)


def preview_income_sync() -> dict:
    """预览利润表同步信息。

    Returns:
        预览信息字典
    """
    return preview_financial_sync(IncomeQuarterSync)


def get_income(period: str, fields: Optional[str] = None) -> pd.DataFrame:
    """获取利润表数据（原始接口，单季度）。

    用于直接获取某个季度的数据，不进行同步管理。

    Args:
        period: 报告期，季度最后一天日期（如 '20231231'）
        fields: 指定返回字段，默认返回全部字段

    Returns:
        包含利润表数据的 DataFrame
    """
    client = TushareClient()

    if fields is None:
        fields = (
            "ts_code,ann_date,f_ann_date,end_date,report_type,comp_type,end_type,"
            "basic_eps,diluted_eps,total_revenue,revenue,int_income,prem_earned,"
            "comm_income,n_commis_income,n_oth_income,n_oth_b_income,prem_income,"
            "out_prem,une_prem_reser,reins_income,n_sec_tb_income,n_sec_uw_income,"
            "n_asset_mg_income,oth_b_income,fv_value_chg_gain,invest_income,"
            "ass_invest_income,forex_gain,total_cogs,oper_cost,int_exp,comm_exp,"
            "biz_tax_surchg,sell_exp,admin_exp,fin_exp,assets_impair_loss,prem_refund,"
            "compens_payout,reser_insur_liab,div_payt,reins_exp,oper_exp,"
            "compens_payout_refu,insur_reser_refu,reins_cost_refund,other_bus_cost,"
            "operate_profit,non_oper_income,non_oper_exp,nca_disploss,total_profit,"
            "income_tax,n_income,n_income_attr_p,minority_gain,oth_compr_income,"
            "t_compr_income,compr_inc_attr_p,compr_inc_attr_m_s,ebit,ebitda,"
            "insurance_exp,undist_profit,distable_profit,rd_exp,fin_exp_int_exp,"
            "fin_exp_int_inc,transfer_surplus_rese,transfer_housing_imprest,"
            "transfer_oth,adj_lossgain,withdra_legal_surplus,withdra_legal_pubfund,"
            "withdra_biz_devfund,withdra_rese_fund,withdra_oth_ersu,workers_welfare,"
            "distr_profit_shrhder,prfshare_payable_dvd,comshare_payable_dvd,"
            "capit_comstock_div,net_after_nr_lp_correct,credit_impa_loss,"
            "net_expo_hedging_benefits,oth_impair_loss_assets,total_opcost,"
            "amodcost_fin_assets,oth_income,asset_disp_income,continued_net_profit,"
            "end_net_profit,update_flag"
        )

    return client.query("income_vip", period=period, fields=fields)
