"""Constant definitions for the empirical asset pricing toolkit.

Factor model specifications and characteristic lists used across eap modules.
"""

# ---------------------------------------------------------------------------
# Factor model specifications
# ---------------------------------------------------------------------------

FF3_FACTORS: list[str] = ["mkt_rf", "smb", "hml"]
"""Fama-French 3 factors (Fama and French, 1993)."""

FF5_FACTORS: list[str] = ["mkt_rf", "smb", "hml", "rmw", "cma"]
"""Fama-French 5 factors (Fama and French, 2015)."""

HXZ4_FACTORS: list[str] = ["mkt_rf", "me", "ia", "roe"]
"""Hou-Xue-Zhang q-factor model (Hou, Xue, and Zhang, 2015)."""

SY4_FACTORS: list[str] = ["mkt_rf", "smb", "mgmt", "perf"]
"""Stambaugh-Yuan mispricing factors (Stambaugh and Yuan, 2017)."""

# ---------------------------------------------------------------------------
# JKP 153 characteristics
# Jensen, Kelly, and Pedersen (2023, JF) "Is There a Replication Crisis
# in Finance?" — canonical set of 153 firm characteristics spanning:
# size, value, momentum, profitability, investment, trading frictions,
# intangibles, and quality categories.
#
# Names follow the JKP/Open Source Asset Pricing (OSAP) convention.
# ---------------------------------------------------------------------------

JKP_153: list[str] = [
    # -- Size (3) --
    "size",                     # log market equity
    "at",                       # total assets (book)
    "sale",                     # total sales

    # -- Value (10) --
    "bm",                       # book-to-market
    "bm_ia",                    # industry-adjusted book-to-market
    "am",                       # assets-to-market
    "cfp",                      # cash flow-to-price
    "cfp_ia",                   # industry-adjusted cash flow-to-price
    "ep",                       # earnings-to-price
    "sp",                       # sales-to-price
    "dp",                       # dividend-to-price (dividend yield)
    "ebitda_mev",               # EBITDA-to-market enterprise value
    "ocf_me",                   # operating cash flow-to-market equity

    # -- Momentum / Reversal (14) --
    "ret_1_0",                  # short-term reversal (1-month)
    "ret_2_1",                  # 1-month lagged return
    "ret_3_1",                  # 2-month momentum
    "ret_6_1",                  # 5-month momentum
    "ret_9_1",                  # 8-month momentum
    "ret_12_1",                 # 11-month momentum (standard)
    "ret_12_7",                 # intermediate momentum
    "ret_36_13",                # long-term reversal (Bondt-Thaler)
    "ret_60_13",                # 4-year reversal
    "resff3_6_1",               # residual momentum (FF3, 6m)
    "resff3_12_1",              # residual momentum (FF3, 12m)
    "mom_rev",                  # momentum change
    "seas_1_1an",               # seasonality (1-yr, annual)
    "seas_2_5an",               # seasonality (2-5 yr, annual)

    # -- Profitability (18) --
    "gp_at",                    # gross profitability (Novy-Marx)
    "ope_be",                   # operating profitability / BE
    "ope_bel1",                 # operating profitability / lagged BE
    "op_at",                    # operating profits / assets
    "cop_at",                   # cash operating profitability / assets
    "ni_be",                    # net income / book equity (ROE)
    "ni_at",                    # net income / assets (ROA)
    "ni_me",                    # net income / market equity
    "niq_at",                   # quarterly net income / assets
    "niq_be",                   # quarterly net income / book equity
    "niq_su",                   # standardized unexpected quarterly NI
    "roe",                      # return on equity
    "roa",                      # return on assets
    "f_score",                  # Piotroski F-score
    "o_score",                  # Ohlson O-score
    "z_score",                  # Altman Z-score
    "ebit_sale",                # EBIT / sales (operating margin)
    "sale_gr1",                 # 1-year sales growth

    # -- Investment (14) --
    "inv",                      # inventory changes
    "inv_gr1",                  # 1-year inventory growth
    "inv_gr1a",                 # 1-year inventory growth (alt)
    "oacc",                     # operating accruals
    "taccruals",                # total accruals
    "pct_acc",                  # percent accruals
    "acc",                      # accruals (working capital)
    "ag",                       # asset growth (Cooper, Gulen, Schill)
    "grcapx",                   # capex growth
    "capx_gr1",                 # 1-year capex growth
    "capx_gr2",                 # 2-year capex growth
    "capx_gr3",                 # 3-year capex growth
    "chcsho",                   # change in shares outstanding
    "eqnpo",                    # equity net payout

    # -- Leverage / Financial Constraints (8) --
    "debt_me",                  # debt-to-market equity
    "debt_at",                  # debt-to-assets (leverage)
    "be_me",                    # book equity-to-market equity
    "netdebt_me",               # net debt-to-market equity
    "fcf_me",                   # free cash flow-to-market equity
    "kz_index",                 # Kaplan-Zingales index
    "ww_index",                 # Whited-Wu index
    "hp_index",                 # Hadlock-Pierce index

    # -- Trading Frictions / Liquidity (18) --
    "beta",                     # CAPM beta
    "betasq",                   # beta squared
    "betabab",                  # betting-against-beta
    "ivol_capm_21d",            # idiosyncratic volatility (CAPM, 21d)
    "ivol_ff3_21d",             # idiosyncratic volatility (FF3, 21d)
    "tvol",                     # total volatility
    "iskew_capm_21d",           # idiosyncratic skewness (CAPM, 21d)
    "iskew_ff3_21d",            # idiosyncratic skewness (FF3, 21d)
    "coskew",                   # coskewness
    "dbnetis",                  # net issuance (debt)
    "bidaskhl_21d",             # bid-ask spread (Corwin-Schultz, 21d)
    "turnover_d",               # daily turnover
    "turnover_var_d",           # turnover variability (daily)
    "dolvol",                   # dollar volume
    "zero_trades_21d",          # zero-trading days (21d)
    "zero_trades_126d",         # zero-trading days (126d)
    "zero_trades_252d",         # zero-trading days (252d)
    "ami_126d",                 # Amihud illiquidity (126d)

    # -- Intangibles / Innovation (14) --
    "rd_me",                    # R&D-to-market equity
    "rd_sale",                  # R&D-to-sales
    "rdq",                      # R&D quarterly
    "adv_sale",                 # advertising-to-sales
    "staff_sale",               # staff expense-to-sales
    "emp_gr1",                  # employee growth
    "cowc_gr1a",                # change in net operating working capital
    "lnoa",                     # net operating assets
    "noa",                      # net operating assets (alt)
    "sti_gr1a",                 # short-term investment growth
    "tax_gr1a",                 # tax growth
    "dbe_gr1a",                 # debt growth
    "dgp_dsale",                # change in GP minus change in sales
    "dsale_dinv",               # change in sales minus change in inventory

    # -- Quality / Earnings Quality (14) --
    "dsale_drec",               # change in sales minus change in receivables
    "dsale_dsga",               # change in sales minus change in SGA
    "sale_emp_gr1",             # sales per employee growth
    "age",                      # firm age
    "div_d_me",                 # dividends / market equity (dummy)
    "eqpo_me",                  # equity payout / market equity
    "eqnetis",                  # equity net issuance
    "eqis",                     # equity issuance
    "dbnetis_at",               # net debt issuance / assets
    "eqnetis_at",               # net equity issuance / assets
    "netis_at",                 # net total issuance / assets
    "at_gr1",                   # 1-year asset growth
    "ppeg_gr1a",                # change in PP&E and inventory
    "lti_gr1a",                 # long-term investment growth

    # -- Analyst / Earnings Surprises (10) --
    "nanalyst",                 # number of analysts
    "sue",                      # standardized unexpected earnings
    "re_gr1",                   # revisions in earnings forecasts
    "rec",                      # analyst recommendation
    "lturnover",                # log turnover
    "prc",                      # price per share
    "market_equity",            # market equity
    "be",                       # book equity
    "at_me",                    # assets-to-market equity
    "cash_at",                  # cash-to-assets

    # -- Macro / Risk (12) --
    "mispricing_perf",          # mispricing: performance
    "mispricing_mgmt",          # mispricing: management
    "qmj",                      # quality minus junk
    "qmj_prof",                 # QMJ: profitability
    "qmj_growth",               # QMJ: growth
    "qmj_safety",               # QMJ: safety
    "rmax1_21d",                # max daily return (21d)
    "rmax5_21d",                # max 5-day return (21d)
    "rmax5_rvol_21d",           # rmax5 scaled by realized vol
    "rskew_21d",                # return skewness (21d)
    "rvol_21d",                 # realized volatility (21d)
    "corr_1260d",               # correlation with market (1260d)

    # -- Additional characteristics to reach 153 --
    "seas_1_1na",               # seasonality (1-yr, not annual)
    "seas_2_5na",               # seasonality (2-5 yr, not annual)
    "seas_6_10an",              # seasonality (6-10 yr, annual)
    "seas_6_10na",              # seasonality (6-10 yr, not annual)
    "seas_11_15an",             # seasonality (11-15 yr, annual)
    "seas_11_15na",             # seasonality (11-15 yr, not annual)
    "seas_16_20an",             # seasonality (16-20 yr, annual)
    "seas_16_20na",             # seasonality (16-20 yr, not annual)
    "dolvol_var_126d",          # dollar volume variability (126d)
    "prc_highprc_252d",         # price relative to 252-day high
    "ret_exc_12m",              # excess return (12-month)
    "ni_inc8q",                 # income increase (8 quarters)
    "ni_ar1",                   # AR(1) of net income
    "sale_me",                  # sales-to-market equity
    "lme",                      # log market equity (alt)
    "rvol_252d",                # realized volatility (252d)
    "beta_60m",                 # 60-month beta
    "iskew_hxz4_21d",           # idiosyncratic skewness (HXZ4, 21d)
]

# Validate length at import time
assert len(JKP_153) == 153, f"JKP_153 has {len(JKP_153)} elements, expected 153"


# ---------------------------------------------------------------------------
# GFD column name mapping
# ---------------------------------------------------------------------------
# Maps JKP_153 canonical names → actual column names in wrds.wrds_global_factor
# (Global Factor Data / Chen-Zimmerman convention).
#
# Only entries that differ from the JKP name are listed.
# Direct matches (e.g. ni_be, gp_at, ivol_capm_21d, ...) are NOT listed here.
#
# Approximations are noted inline; some windows/definitions differ slightly.
#
# References
# ----------
# Chen, A., & Zimmermann, T. (2022). Open Source Cross-Sectional Asset Pricing.
#     Critical Finance Review, 11, 207-264.
# Jensen, T., Kelly, B., & Pedersen, L. H. (2023). Is There a Replication
#     Crisis in Finance? Journal of Finance, 78(5), 2465-2518.
# ---------------------------------------------------------------------------

GFD_CHAR_MAP: dict[str, str] = {
    # Size
    "size": "me",               # me = market equity (level); log must be taken
    "at": "assets",             # total assets (book)
    "sale": "sales",            # total sales

    # Value (aliases; JKP_153 also has the GFD names separately)
    "bm": "be_me",              # book-to-market ≈ be_me
    "am": "at_me",              # assets-to-market ≈ at_me
    "cfp": "ocf_me",            # cash flow-to-price ≈ ocf_me
    "ep": "ni_me",              # earnings-to-price ≈ ni_me
    "sp": "sale_me",            # sales-to-price ≈ sale_me
    "dp": "div12m_me",          # dividend yield ≈ div12m_me (trailing 12m)

    # Momentum (closest available; exact windows may differ)
    "ret_2_1": "ret_3_1",       # 1m lagged return; GFD has ret_3_1 (2m skip-1)
    "ret_36_13": "ret_36_12",   # long-term reversal; GFD ends at t-12 not t-13
    "ret_60_13": "ret_60_12",   # 4-year reversal; GFD ends at t-12 not t-13

    # Profitability (aliases)
    "roe": "ni_be",             # return on equity = ni_be
    "roa": "ni_at",             # return on assets = ni_at

    # Investment
    "inv": "inv_gr1",           # inventory changes ≈ annual inventory growth
    "oacc": "oaccruals_at",     # operating accruals / assets
    "taccruals": "taccruals_at",  # total accruals / assets
    "ag": "at_gr1",             # asset growth (Cooper, Gulen, Schill)
    "grcapx": "capx_gr1",       # capex growth ≈ capx_gr1 (1-year)
    "chcsho": "chcsho_12m",     # change in shares outstanding (12-month)
    "eqnpo": "eqnpo_12m",       # equity net payout (12-month)

    # Trading frictions
    "beta": "beta_21d",         # CAPM beta (21-day rolling)
    "betabab": "betabab_1260d", # betting-against-beta (1260-day)
    "coskew": "coskew_21d",     # coskewness (21-day)
    "dbnetis": "dbnetis_at",    # net debt issuance / assets
    "turnover_d": "turnover_126d",      # daily turnover ≈ 126d turnover
    "turnover_var_d": "turnover_var_126d",  # turnover variability

    # Intangibles / leverage
    "lnoa": "noa_at",           # log NOA ≈ noa_at (NOA/assets; log to be taken)
    "noa": "noa_at",            # net operating assets / assets
    "dbe_gr1a": "be_gr1a",      # change in book equity (annual growth)

    # Quality / issuance
    "eqnetis": "eqnetis_at",    # equity net issuance / assets
    "eqis": "eqis_at",          # equity issuance / assets
    "sue": "niq_su",            # standardized unexpected earnings ≈ niq_su
    "be": "book_equity",        # book equity (level)

    # Additional
    "ret_exc_12m": "ret_12_1",  # 12m excess return ≈ ret_12_1 (skip-1)
    "lme": "me",                # log market equity; log must be taken from me
}

GFD_CHAR_UNAVAILABLE: list[str] = [
    # Industry-adjusted characteristics (not pre-computed in GFD)
    "bm_ia",
    "cfp_ia",
    # Momentum: specific window constructions not in GFD
    "mom_rev",
    # Accruals (specific JKP definition)
    "pct_acc",
    "acc",
    # Financial constraints indices (not in GFD)
    "ww_index",
    "hp_index",
    # Beta squared (must be computed from beta_21d)
    "betasq",
    # Quarterly R&D (only annual versions in GFD)
    "rdq",
    # Dividend dummy (GFD has continuous div_me, not dummy)
    "div_d_me",
    # Analyst data (not in GFD)
    "nanalyst",
    "re_gr1",
    "rec",
    # Log turnover (must be computed from turnover_126d)
    "lturnover",
]
