"""资产负债表数据接口 (VIP 版本)

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

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

使用方式:
    # 同步资产负债表数据
    from src.data.api_wrappers.financial_data.api_balance import BalanceQuarterSync, sync_balance

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

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

from typing import Any, override
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 BalanceQuarterSync(QuarterBasedSync):
    """资产负债表季度同步实现。

    使用 balancesheet_vip 接口按季度获取全部上市公司资产负债表数据。

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

    table_name: str = "financial_balance"
    api_name: str = "balancesheet_vip"

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

    # 表结构定义
    TABLE_SCHEMA: dict[str, str] = {
        # 基础字段
        "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)",
        # 股本及资本结构
        "total_share": "DOUBLE",  # 期末总股本
        "cap_rese": "DOUBLE",  # 资本公积金
        "undistr_porfit": "DOUBLE",  # 未分配利润
        "surplus_rese": "DOUBLE",  # 盈余公积金
        "special_rese": "DOUBLE",  # 专项储备
        # 流动资产
        "money_cap": "DOUBLE",  # 货币资金
        "trad_asset": "DOUBLE",  # 交易性金融资产
        "notes_receiv": "DOUBLE",  # 应收票据
        "accounts_receiv": "DOUBLE",  # 应收账款
        "oth_receiv": "DOUBLE",  # 其他应收款
        "prepayment": "DOUBLE",  # 预付款项
        "div_receiv": "DOUBLE",  # 应收股利
        "int_receiv": "DOUBLE",  # 应收利息
        "inventories": "DOUBLE",  # 存货
        "amor_exp": "DOUBLE",  # 待摊费用
        "nca_within_1y": "DOUBLE",  # 一年内到期的非流动资产
        "sett_rsrv": "DOUBLE",  # 结算备付金
        "loanto_oth_bank_fi": "DOUBLE",  # 拆出资金
        "premium_receiv": "DOUBLE",  # 应收保费
        "reinsur_receiv": "DOUBLE",  # 应收分保账款
        "reinsur_res_receiv": "DOUBLE",  # 应收分保合同准备金
        "pur_resale_fa": "DOUBLE",  # 买入返售金融资产
        "oth_cur_assets": "DOUBLE",  # 其他流动资产
        "total_cur_assets": "DOUBLE",  # 流动资产合计
        # 非流动资产
        "fa_avail_for_sale": "DOUBLE",  # 可供出售金融资产
        "htm_invest": "DOUBLE",  # 持有至到期投资
        "lt_eqt_invest": "DOUBLE",  # 长期股权投资
        "invest_real_estate": "DOUBLE",  # 投资性房地产
        "time_deposits": "DOUBLE",  # 定期存款
        "oth_assets": "DOUBLE",  # 其他资产
        "lt_rec": "DOUBLE",  # 长期应收款
        "fix_assets": "DOUBLE",  # 固定资产
        "cip": "DOUBLE",  # 在建工程
        "const_materials": "DOUBLE",  # 工程物资
        "fixed_assets_disp": "DOUBLE",  # 固定资产清理
        "produc_bio_assets": "DOUBLE",  # 生产性生物资产
        "oil_and_gas_assets": "DOUBLE",  # 油气资产
        "intan_assets": "DOUBLE",  # 无形资产
        "r_and_d": "DOUBLE",  # 研发支出
        "goodwill": "DOUBLE",  # 商誉
        "lt_amor_exp": "DOUBLE",  # 长期待摊费用
        "defer_tax_assets": "DOUBLE",  # 递延所得税资产
        "decr_in_disbur": "DOUBLE",  # 发放贷款及垫款
        "oth_nca": "DOUBLE",  # 其他非流动资产
        "total_nca": "DOUBLE",  # 非流动资产合计
        # 金融机构特有-资产
        "cash_reser_cb": "DOUBLE",  # 现金及存放中央银行款项
        "depos_in_oth_bfi": "DOUBLE",  # 存放同业和其它金融机构款项
        "prec_metals": "DOUBLE",  # 贵金属
        "deriv_assets": "DOUBLE",  # 衍生金融资产
        "rr_reins_une_prem": "DOUBLE",  # 应收分保未到期责任准备金
        "rr_reins_outstd_cla": "DOUBLE",  # 应收分保未决赔款准备金
        "rr_reins_lins_liab": "DOUBLE",  # 应收分保寿险责任准备金
        "rr_reins_lthins_liab": "DOUBLE",  # 应收分保长期健康险责任准备金
        "refund_depos": "DOUBLE",  # 存出保证金
        "ph_pledge_loans": "DOUBLE",  # 保户质押贷款
        "refund_cap_depos": "DOUBLE",  # 存出资本保证金
        "indep_acct_assets": "DOUBLE",  # 独立账户资产
        "client_depos": "DOUBLE",  # 其中：客户资金存款
        "client_prov": "DOUBLE",  # 其中：客户备付金
        "transac_seat_fee": "DOUBLE",  # 其中:交易席位费
        "invest_as_receiv": "DOUBLE",  # 应收款项类投资
        "total_assets": "DOUBLE",  # 资产总计
        # 流动负债
        "lt_borr": "DOUBLE",  # 长期借款
        "st_borr": "DOUBLE",  # 短期借款
        "cb_borr": "DOUBLE",  # 向中央银行借款
        "depos_ib_deposits": "DOUBLE",  # 吸收存款及同业存放
        "loan_oth_bank": "DOUBLE",  # 拆入资金
        "trading_fl": "DOUBLE",  # 交易性金融负债
        "notes_payable": "DOUBLE",  # 应付票据
        "acct_payable": "DOUBLE",  # 应付账款
        "adv_receipts": "DOUBLE",  # 预收款项
        "sold_for_repur_fa": "DOUBLE",  # 卖出回购金融资产款
        "comm_payable": "DOUBLE",  # 应付手续费及佣金
        "payroll_payable": "DOUBLE",  # 应付职工薪酬
        "taxes_payable": "DOUBLE",  # 应交税费
        "int_payable": "DOUBLE",  # 应付利息
        "div_payable": "DOUBLE",  # 应付股利
        "oth_payable": "DOUBLE",  # 其他应付款
        "acc_exp": "DOUBLE",  # 预提费用
        "deferred_inc": "DOUBLE",  # 递延收益
        "st_bonds_payable": "DOUBLE",  # 应付短期债券
        "payable_to_reinsurer": "DOUBLE",  # 应付分保账款
        "rsrv_insur_cont": "DOUBLE",  # 保险合同准备金
        "acting_trading_sec": "DOUBLE",  # 代理买卖证券款
        "acting_uw_sec": "DOUBLE",  # 代理承销证券款
        "non_cur_liab_due_1y": "DOUBLE",  # 一年内到期的非流动负债
        "oth_cur_liab": "DOUBLE",  # 其他流动负债
        "total_cur_liab": "DOUBLE",  # 流动负债合计
        # 非流动负债
        "bond_payable": "DOUBLE",  # 应付债券
        "lt_payable": "DOUBLE",  # 长期应付款
        "specific_payables": "DOUBLE",  # 专项应付款
        "estimated_liab": "DOUBLE",  # 预计负债
        "defer_tax_liab": "DOUBLE",  # 递延所得税负债
        "defer_inc_non_cur_liab": "DOUBLE",  # 递延收益-非流动负债
        "oth_ncl": "DOUBLE",  # 其他非流动负债
        "total_ncl": "DOUBLE",  # 非流动负债合计
        # 金融机构特有-负债
        "depos_oth_bfi": "DOUBLE",  # 同业和其它金融机构存放款项
        "deriv_liab": "DOUBLE",  # 衍生金融负债
        "depos": "DOUBLE",  # 吸收存款
        "agency_bus_liab": "DOUBLE",  # 代理业务负债
        "oth_liab": "DOUBLE",  # 其他负债
        "prem_receiv_adva": "DOUBLE",  # 预收保费
        "depos_received": "DOUBLE",  # 存入保证金
        "ph_invest": "DOUBLE",  # 保户储金及投资款
        "reser_une_prem": "DOUBLE",  # 未到期责任准备金
        "reser_outstd_claims": "DOUBLE",  # 未决赔款准备金
        "reser_lins_liab": "DOUBLE",  # 寿险责任准备金
        "reser_lthins_liab": "DOUBLE",  # 长期健康险责任准备金
        "indept_acc_liab": "DOUBLE",  # 独立账户负债
        "pledge_borr": "DOUBLE",  # 其中:质押借款
        "indem_payable": "DOUBLE",  # 应付赔付款
        "policy_div_payable": "DOUBLE",  # 应付保单红利
        "total_liab": "DOUBLE",  # 负债合计
        # 所有者权益
        "treasury_share": "DOUBLE",  # 减:库存股
        "ordin_risk_reser": "DOUBLE",  # 一般风险准备
        "forex_differ": "DOUBLE",  # 外币报表折算差额
        "invest_loss_unconf": "DOUBLE",  # 未确认的投资损失
        "minority_int": "DOUBLE",  # 少数股东权益
        "total_hldr_eqy_exc_min_int": "DOUBLE",  # 股东权益合计(不含少数股东权益)
        "total_hldr_eqy_inc_min_int": "DOUBLE",  # 股东权益合计(含少数股东权益)
        "total_liab_hldr_eqy": "DOUBLE",  # 负债及股东权益总计
        # 补充披露项目
        "lt_payroll_payable": "DOUBLE",  # 长期应付职工薪酬
        "oth_comp_income": "DOUBLE",  # 其他综合收益
        "oth_eqt_tools": "DOUBLE",  # 其他权益工具
        "oth_eqt_tools_p_shr": "DOUBLE",  # 其他权益工具(优先股)
        "lending_funds": "DOUBLE",  # 融出资金
        "acc_receivable": "DOUBLE",  # 应收款项
        "st_fin_payable": "DOUBLE",  # 应付短期融资款
        "payables": "DOUBLE",  # 应付款项
        "hfs_assets": "DOUBLE",  # 持有待售的资产
        "hfs_sales": "DOUBLE",  # 持有待售的负债
        "cost_fin_assets": "DOUBLE",  # 以摊余成本计量的金融资产
        "fair_value_fin_assets": "DOUBLE",  # 以公允价值计量且其变动计入其他综合收益的金融资产
        "cip_total": "DOUBLE",  # 在建工程(合计)(元)
        "oth_pay_total": "DOUBLE",  # 其他应付款(合计)(元)
        "long_pay_total": "DOUBLE",  # 长期应付款(合计)(元)
        "debt_invest": "DOUBLE",  # 债权投资(元)
        "oth_debt_invest": "DOUBLE",  # 其他债权投资(元)
        "oth_eq_invest": "DOUBLE",  # 其他权益工具投资(元)
        "oth_illiq_fin_assets": "DOUBLE",  # 其他非流动金融资产(元)
        "oth_eq_ppbond": "DOUBLE",  # 其他权益工具:永续债(元)
        "receiv_financing": "DOUBLE",  # 应收款项融资
        "use_right_assets": "DOUBLE",  # 使用权资产
        "lease_liab": "DOUBLE",  # 租赁负债
        "contract_assets": "DOUBLE",  # 合同资产
        "contract_liab": "DOUBLE",  # 合同负债
        "accounts_receiv_bill": "DOUBLE",  # 应收票据及应收账款
        "accounts_pay": "DOUBLE",  # 应付票据及应付账款
        "oth_rcv_total": "DOUBLE",  # 其他应收款(合计)（元）
        "fix_assets_total": "DOUBLE",  # 固定资产(合计)(元)
        "update_flag": "VARCHAR(1)",  # 更新标识
    }

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

    def __init__(self):
        """初始化资产负债表同步器。"""
        super().__init__()
        self._fields: str | None = None  # 默认返回全部字段

    @override
    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_balance(
    force_full: bool = False,
    dry_run: bool = False,
) -> list[dict[str, Any]]:
    """同步资产负债表数据（便捷函数）。

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

    Returns:
        同步结果列表

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


def preview_balance_sync() -> dict[str, Any]:
    """预览资产负债表同步信息。

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


def get_balance(period: str, fields: str | None = 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,"
            "total_share,cap_rese,undistr_porfit,surplus_rese,"
            "money_cap,trad_asset,notes_receiv,accounts_receiv,oth_receiv,prepayment,"
            "inventories,total_cur_assets,fa_avail_for_sale,htm_invest,"
            "lt_eqt_invest,fix_assets,intan_assets,goodwill,total_nca,"
            "total_assets,lt_borr,st_borr,notes_payable,acct_payable,"
            "adv_receipts,payroll_payable,taxes_payable,total_cur_liab,"
            "bond_payable,lt_payable,total_ncl,total_liab,"
            "treasury_share,minority_int,total_hldr_eqy_exc_min_int,"
            "total_hldr_eqy_inc_min_int,total_liab_hldr_eqy"
        )

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