"""现金流量表数据接口 (VIP 版本)

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

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

使用方式:
    # 同步现金流量表数据
    from src.data.api_wrappers.financial_data.api_cashflow import CashflowQuarterSync, sync_cashflow

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

    # 方式2: 使用便捷函数
    sync_cashflow()  # 增量同步
    sync_cashflow(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 CashflowQuarterSync(QuarterBasedSync):
    """现金流量表季度同步实现。

    使用 cashflow_vip 接口按季度获取全部上市公司现金流量表数据。

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

    table_name: str = "financial_cashflow"
    api_name: str = "cashflow_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",
        "comp_type": "INTEGER",
        "report_type": "INTEGER",
        "end_type": "VARCHAR(10)",
        "net_profit": "DOUBLE",
        "finan_exp": "DOUBLE",
        "c_fr_sale_sg": "DOUBLE",
        "recp_tax_rends": "DOUBLE",
        "n_depos_incr_fi": "DOUBLE",
        "n_incr_loans_cb": "DOUBLE",
        "n_inc_borr_oth_fi": "DOUBLE",
        "prem_fr_orig_contr": "DOUBLE",
        "n_incr_insured_dep": "DOUBLE",
        "n_reinsur_prem": "DOUBLE",
        "n_incr_disp_tfa": "DOUBLE",
        "ifc_cash_incr": "DOUBLE",
        "n_incr_disp_faas": "DOUBLE",
        "n_incr_loans_oth_bank": "DOUBLE",
        "n_cap_incr_repur": "DOUBLE",
        "c_fr_oth_operate_a": "DOUBLE",
        "c_inf_fr_operate_a": "DOUBLE",
        "c_paid_goods_s": "DOUBLE",
        "c_paid_to_for_empl": "DOUBLE",
        "c_paid_for_taxes": "DOUBLE",
        "n_incr_clt_loan_adv": "DOUBLE",
        "n_incr_dep_cbob": "DOUBLE",
        "c_pay_claims_orig_inco": "DOUBLE",
        "pay_handling_chrg": "DOUBLE",
        "pay_comm_insur_plcy": "DOUBLE",
        "oth_cash_pay_oper_act": "DOUBLE",
        "st_cash_out_act": "DOUBLE",
        "n_cashflow_act": "DOUBLE",
        "oth_recp_ral_inv_act": "DOUBLE",
        "c_disp_withdrwl_invest": "DOUBLE",
        "c_recp_return_invest": "DOUBLE",
        "n_recp_disp_fiolta": "DOUBLE",
        "n_recp_disp_sobu": "DOUBLE",
        "stot_inflows_inv_act": "DOUBLE",
        "c_pay_acq_const_fiolta": "DOUBLE",
        "c_paid_invest": "DOUBLE",
        "n_disp_subs_oth_biz": "DOUBLE",
        "oth_pay_ral_inv_act": "DOUBLE",
        "n_incr_pledge_loan": "DOUBLE",
        "stot_out_inv_act": "DOUBLE",
        "n_cashflow_inv_act": "DOUBLE",
        "c_recp_borrow": "DOUBLE",
        "proc_issue_bonds": "DOUBLE",
        "oth_cash_recp_ral_fnc_act": "DOUBLE",
        "stot_cash_in_fnc_act": "DOUBLE",
        "free_cashflow": "DOUBLE",
        "c_prepay_amt_borr": "DOUBLE",
        "c_pay_dist_dpcp_int_exp": "DOUBLE",
        "incl_dvd_profit_paid_sc_ms": "DOUBLE",
        "oth_cashpay_ral_fnc_act": "DOUBLE",
        "stot_cashout_fnc_act": "DOUBLE",
        "n_cash_flows_fnc_act": "DOUBLE",
        "eff_fx_flu_cash": "DOUBLE",
        "n_incr_cash_cash_equ": "DOUBLE",
        "c_cash_equ_beg_period": "DOUBLE",
        "c_cash_equ_end_period": "DOUBLE",
        "c_recp_cap_contrib": "DOUBLE",
        "incl_cash_rec_saims": "DOUBLE",
        "uncon_invest_loss": "DOUBLE",
        "prov_depr_assets": "DOUBLE",
        "depr_fa_coga_dpba": "DOUBLE",
        "amort_intang_assets": "DOUBLE",
        "lt_amort_deferred_exp": "DOUBLE",
        "decr_deferred_exp": "DOUBLE",
        "incr_acc_exp": "DOUBLE",
        "loss_disp_fiolta": "DOUBLE",
        "loss_scr_fa": "DOUBLE",
        "loss_fv_chg": "DOUBLE",
        "invest_loss": "DOUBLE",
        "decr_def_inc_tax_assets": "DOUBLE",
        "incr_def_inc_tax_liab": "DOUBLE",
        "decr_inventories": "DOUBLE",
        "decr_oper_payable": "DOUBLE",
        "incr_oper_payable": "DOUBLE",
        "others": "DOUBLE",
        "im_net_cashflow_oper_act": "DOUBLE",
        "conv_debt_into_cap": "DOUBLE",
        "conv_copbonds_due_within_1y": "DOUBLE",
        "fa_fnc_leases": "DOUBLE",
        "im_n_incr_cash_equ": "DOUBLE",
        "net_dism_capital_add": "DOUBLE",
        "net_cash_rece_sec": "DOUBLE",
        "credit_impa_loss": "DOUBLE",
        "use_right_asset_dep": "DOUBLE",
        "oth_loss_asset": "DOUBLE",
        "end_bal_cash": "DOUBLE",
        "beg_bal_cash": "DOUBLE",
        "end_bal_cash_equ": "DOUBLE",
        "beg_bal_cash_equ": "DOUBLE",
        "update_flag": "VARCHAR(1)",
    }

    # 索引定义（不要创建唯一索引）
    # 注意：财务数据可能发生多次修正，不设置主键和唯一索引
    TABLE_INDEXES: list[tuple[str, list[str]]] = [
        ("idx_financial_cashflow_ts_code", ["ts_code"]),
        ("idx_financial_cashflow_end_date", ["end_date"]),
        ("idx_financial_cashflow_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_cashflow(
    force_full: bool = False,
    dry_run: bool = False,
) -> list[dict[str, Any]]:
    """同步现金流量表数据（便捷函数）。

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

    Returns:
        同步结果列表

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


def preview_cashflow_sync() -> dict[str, Any]:
    """预览现金流量表同步信息。

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


def get_cashflow(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,comp_type,report_type,end_type,"
            "net_profit,finan_exp,c_fr_sale_sg,recp_tax_rends,n_depos_incr_fi,"
            "n_incr_loans_cb,n_inc_borr_oth_fi,prem_fr_orig_contr,n_incr_insured_dep,"
            "n_reinsur_prem,n_incr_disp_tfa,ifc_cash_incr,n_incr_disp_faas,"
            "n_incr_loans_oth_bank,n_cap_incr_repur,c_fr_oth_operate_a,c_inf_fr_operate_a,"
            "c_paid_goods_s,c_paid_to_for_empl,c_paid_for_taxes,n_incr_clt_loan_adv,"
            "n_incr_dep_cbob,c_pay_claims_orig_inco,pay_handling_chrg,pay_comm_insur_plcy,"
            "oth_cash_pay_oper_act,st_cash_out_act,n_cashflow_act,oth_recp_ral_inv_act,"
            "c_disp_withdrwl_invest,c_recp_return_invest,n_recp_disp_fiolta,"
            "n_recp_disp_sobu,stot_inflows_inv_act,c_pay_acq_const_fiolta,c_paid_invest,"
            "n_disp_subs_oth_biz,oth_pay_ral_inv_act,n_incr_pledge_loan,stot_out_inv_act,"
            "n_cashflow_inv_act,c_recp_borrow,proc_issue_bonds,oth_cash_recp_ral_fnc_act,"
            "stot_cash_in_fnc_act,free_cashflow,c_prepay_amt_borr,c_pay_dist_dpcp_int_exp,"
            "incl_dvd_profit_paid_sc_ms,oth_cashpay_ral_fnc_act,stot_cashout_fnc_act,"
            "n_cash_flows_fnc_act,eff_fx_flu_cash,n_incr_cash_cash_equ,c_cash_equ_beg_period,"
            "c_cash_equ_end_period,c_recp_cap_contrib,incl_cash_rec_saims,uncon_invest_loss,"
            "prov_depr_assets,depr_fa_coga_dpba,amort_intang_assets,lt_amort_deferred_exp,"
            "decr_deferred_exp,incr_acc_exp,loss_disp_fiolta,loss_scr_fa,loss_fv_chg,"
            "invest_loss,decr_def_inc_tax_assets,incr_def_inc_tax_liab,decr_inventories,"
            "decr_oper_payable,incr_oper_payable,others,im_net_cashflow_oper_act,"
            "conv_debt_into_cap,conv_copbonds_due_within_1y,fa_fnc_leases,"
            "im_n_incr_cash_equ,net_dism_capital_add,net_cash_rece_sec,credit_impa_loss,"
            "use_right_asset_dep,oth_loss_asset,end_bal_cash,beg_bal_cash,"
            "end_bal_cash_equ,beg_bal_cash_equ,update_flag"
        )

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