"""
PIT Enum Classes for IDE Autocomplete Support

Provides enum classes for DateTable parameters to enable IDE autocomplete
for valid parameter values. Generated from pit_constants.json.
"""

from enum import Enum
from typing import Union

__all__ = [
    "Frequency",
    "DayCount",
    "Calendar",
    "ResetTiming",
    "Stub",
    "DateRule",
    "PayTiming",
    "PayReceive",
    "RfrLag",
    "Index",
]


class Frequency(str, Enum):
    """Payment frequency enumeration"""

    # Special values
    DEFAULT_FREQ = "DefaultFreq"
    ZEROCOUPON = "Zerocoupon"
    NOT_SPECIFIED = "NotSpecified"
    DAILY = "Daily"
    BUSINESS_DAYS = "BusinessDays"

    # Year-based frequencies
    ANNUAL = "1Y"
    YEARLY = "1Y"
    Y_2Y = "2Y"
    Y_3Y = "3Y"
    Y_4Y = "4Y"
    Y_5Y = "5Y"
    Y_10Y = "10Y"
    Y_15Y = "15Y"
    Y_20Y = "20Y"
    Y_30Y = "30Y"

    # Month-based frequencies
    MONTHLY = "1M"
    M_2M = "2M"
    QUARTERLY = "3M"
    M_4M = "4M"
    SEMI_ANNUAL = "6M"
    M_18M = "18M"

    # Week-based frequencies
    WEEKLY = "1W"
    W_2W = "2W"
    W_3W = "3W"
    W_4W = "4W"

    # Day-based frequencies (calendar days)
    D_2D = "2D"
    TWO_DAYS = "2D"  # Alias
    D_3D = "3D"
    THREE_DAYS = "3D"  # Alias
    D_4D = "4D"
    FOUR_DAYS = "4D"  # Alias
    D_5D = "5D"
    FIVE_DAYS = "5D"  # Alias
    D_6D = "6D"
    SIX_DAYS = "6D"  # Alias
    D_8D = "8D"
    EIGHT_DAYS = "8D"  # Alias
    D_9D = "9D"
    NINE_DAYS = "9D"  # Alias
    D_10D = "10D"
    TEN_DAYS = "10D"  # Alias
    D_11D = "11D"
    ELEVEN_DAYS = "11D"  # Alias
    D_12D = "12D"
    TWELVE_DAYS = "12D"  # Alias
    D_13D = "13D"
    THIRTEEN_DAYS = "13D"  # Alias
    D_15D = "15D"
    FIFTEEN_DAYS = "15D"  # Alias
    D_16D = "16D"
    SIXTEEN_DAYS = "16D"  # Alias
    D_17D = "17D"
    SEVENTEEN_DAYS = "17D"  # Alias
    D_18D = "18D"
    EIGHTEEN_DAYS = "18D"  # Alias
    D_19D = "19D"
    NINETEEN_DAYS = "19D"  # Alias
    D_20D = "20D"
    TWENTY_DAYS = "20D"  # Alias
    D_22D = "22D"
    TWENTY_TWO_DAYS = "22D"  # Alias
    D_23D = "23D"
    TWENTY_THREE_DAYS = "23D"  # Alias
    D_24D = "24D"
    TWENTY_FOUR_DAYS = "24D"  # Alias
    D_25D = "25D"
    TWENTY_FIVE_DAYS = "25D"  # Alias
    D_26D = "26D"
    TWENTY_SIX_DAYS = "26D"  # Alias
    D_27D = "27D"
    TWENTY_SEVEN_DAYS = "27D"  # Alias
    D_28D = "28D"
    TWENTY_EIGHT_DAYS = "28D"  # Alias

    # Business day-based frequencies
    B_1B = "1B"
    B_2B = "2B"
    B_3B = "3B"
    B_4B = "4B"
    B_5B = "5B"
    B_6B = "6B"
    B_7B = "7B"
    B_8B = "8B"
    B_9B = "9B"
    B_10B = "10B"
    B_11B = "11B"
    B_12B = "12B"
    B_13B = "13B"
    B_14B = "14B"
    B_15B = "15B"
    B_16B = "16B"
    B_17B = "17B"
    B_18B = "18B"
    B_19B = "19B"
    B_20B = "20B"
    B_21B = "21B"
    B_22B = "22B"
    B_23B = "23B"

    def __str__(self):
        return self.value


class DayCount(str, Enum):
    """Day count convention enumeration"""

    ACTUAL_360 = "Actual/360"
    ACTUAL_365 = "Actual/365"
    ACTUAL_365_FIXED = "Actual/365 Fixed"
    ACTUAL_ACTUAL = "Actual/Actual"
    ACTUAL_ACTUAL_ISDA = "Actual/Actual (ISDA)"
    ACTUAL_ACTUAL_AFB = "Actual/Actual (AFB)"
    THIRTY_360 = "30/360"
    THIRTY_E_360 = "30E/360"
    THIRTY_E_360_ISDA = "30E/360 (ISDA)"
    THIRTY_360_US = "30/360 (US)"
    THIRTY_360_BOND_BASIS = "30/360 (Bond Basis)"
    BUSINESS_252 = "Business/252"
    ONE_ONE = "1/1"

    def __str__(self):
        return self.value


class Calendar(str, Enum):
    """Calendar enumeration - all supported calendars"""

    # Special values
    TARGET = "Target"
    TARGET_UPPER = "TARGET"
    NULL_CALENDAR = "nullCalendar"
    NULL = "NULL"
    WEEKEND = "Weekend"
    NO_WEEKEND = "NoWeekend"

    # Currency codes
    AED = "AED"
    ARS = "ARS"
    AUD = "AUD"
    AUME = "AUME"
    AUSY = "AUSY"
    BGN = "BGN"
    BHD = "BHD"
    BMD = "BMD"
    BOB = "BOB"
    BRL = "BRL"
    BSD = "BSD"
    CAD = "CAD"
    CATO = "CATO"
    CHF = "CHF"
    CHZU = "CHZU"
    CLP = "CLP"
    CNH = "CNH"
    CNY = "CNY"
    COP = "COP"
    CZK = "CZK"
    CZPR = "CZPR"
    DKCO = "DKCO"
    DKK = "DKK"
    EUR = "EUR"
    EUTA = "EUTA"
    GBLO = "GBLO"
    GBP = "GBP"
    HKD = "HKD"
    HKHK = "HKHK"
    HRK = "HRK"
    HUBU = "HUBU"
    HUF = "HUF"
    IDR = "IDR"
    ILS = "ILS"
    INR = "INR"
    ISK = "ISK"
    JPTO = "JPTO"
    JPY = "JPY"
    KES = "KES"
    KRW = "KRW"
    KRW_WL = "KRW_WL"
    KWD = "KWD"
    MAINL = "MAINL"
    MXMC = "MXMC"
    MXN = "MXN"
    MYR = "MYR"
    NOK = "NOK"
    NOOS = "NOOS"
    NYSE = "NYSE"
    NZAU = "NZAU"
    NZD = "NZD"
    NZWE = "NZWE"
    PHP = "PHP"
    PLN = "PLN"
    PLWA = "PLWA"
    QAR = "QAR"
    RON = "RON"
    RUB = "RUB"
    SAR = "SAR"
    SEK = "SEK"
    SEST = "SEST"
    SGD = "SGD"
    SGSI = "SGSI"
    SVK = "SVK"
    THB = "THB"
    TRY = "TRY"
    TWD = "TWD"
    UAH = "UAH"
    USD = "USD"
    USNY = "USNY"
    VND = "VND"
    ZAJO = "ZAJO"
    ZAR = "ZAR"

    # Cities
    ALGER = "Alger"
    AMSTERDAM = "Amsterdam"
    ATHENS = "Athens"
    BANGKOK = "Bangkok"
    BEIJING = "Beijing"
    BERMUDA = "Bermuda"
    BOGOTA = "Bogota"
    BOMBAY = "Bombay"
    BRUSSELS = "Brussels"
    BUCHAREST = "Bucharest"
    BUDAPEST = "Budapest"
    BUENOS_AERES = "BuenosAeres"
    COPENHAGEN = "Copenhagen"
    DOHA = "Doha"
    DUBAI = "Dubai"
    DUBLIN = "Dublin"
    FRANKFURT = "Frankfurt"
    HELSINKI = "Helsinki"
    HONG_KONG = "HongKong"
    JOHANNESBURG = "Johannesburg"
    KUALA_LUMPUR = "KualaLumpur"
    LISBON = "Lisbon"
    LONDON = "London"
    MADRID = "Madrid"
    MILAN = "Milan"
    MOSCOW = "Moscow"
    NAIROBI = "Nairobi"
    NEW_YORK = "NewYork"
    OSLO = "Oslo"
    PARIS = "Paris"
    PRAGUE = "Prague"
    REYKJAVIK = "Reykjavik"
    RIAD = "Riad"
    SAN_PAOLO = "SanPaolo"
    SANTIAGO = "Santiago"
    SINGAPORE = "Singapore"
    SOFIA = "Sofia"
    STOCKHOLM = "Stockholm"
    SYDNEY = "Sydney"
    TEL_AVIV = "TelAviv"
    TOKYO = "Tokyo"
    TORONTO = "Toronto"
    VIENNA = "Vienna"
    WARSAW = "Warsaw"
    WELLINGTON = "Wellington"
    ZURICH = "Zurich"
    ZAGREB = "Zagreb"

    # Countries and regions
    ALGERIA = "Algeria"
    ARGENTINA = "Argentina"
    AUSTRALIA = "Australia"
    AUSTRIA = "Austria"
    BAHAMAS = "Bahamas"
    BAHRAIN = "Bahrain"
    BELGIUM = "Belgium"
    BOLIVIA = "Bolivia"
    BRAZIL = "Brazil"
    BULGARIA = "Bulgaria"
    CANADA = "Canada"
    CHILE = "Chile"
    CHINA = "China"
    COLOMBIA = "Colombia"
    CROATIA = "Croatia"
    CZECH_REPUBLIC = "CzechRepublic"
    DENMARK = "Denmark"
    FINLAND = "Finland"
    FRANCE = "France"
    GERMANY = "Germany"
    GREECE = "Greece"
    HOLLAND = "Holland"
    HUNGARY = "Hungary"
    ICELAND = "Iceland"
    INDIA = "India"
    INDONESIA = "Indonesia"
    IRELAND = "Ireland"
    ISRAEL = "Israel"
    ITALY = "Italy"
    JAPAN = "Japan"
    KENYA = "Kenya"
    KUWAIT = "Kuwait"
    LUXEMBOURG = "Luxembourg"
    MAINLAND_CHINA = "MainlandChina"
    MALAYSIA = "Malaysia"
    MEXICO = "Mexico"
    NEW_ZEALAND = "NewZealand"
    NORWAY = "Norway"
    OFFSHORE_CHINA = "OffshoreChina"
    PHILIPPINES = "Philippines"
    POLAND = "Poland"
    PORTUGAL = "Portugal"
    QATAR = "Qatar"
    ROMANIA = "Romania"
    RUSSIA = "Russia"
    SAUDI_ARABIA = "SaudiArabia"
    SLOVAKIA = "Slovakia"
    SOUTH_AFRICA = "SouthAfrica"
    SOUTH_KOREA = "SouthKorea"
    SOUTH_KOREA_WL = "SouthKorea_WL"
    SPAIN = "Spain"
    SWEDEN = "Sweden"
    SWITZERLAND = "Switzerland"
    TAIWAN = "Taiwan"
    THAILAND = "Thailand"
    TURKEY = "Turkey"
    UK = "UK"
    UKRAINE = "Ukraine"
    UNITED_ARAB_EMIRATES = "UnitedArabEmirates"
    UNITED_KINGDOM = "UnitedKingdom"
    UNITED_STATES = "UnitedStates"
    US = "US"
    VIETNAM = "Vietnam"

    # Exchanges
    COPENHAGEN_STOCK_EXCHANGE = "CopenhagenStockExchange"
    EUREX = "Eurex"
    FAST = "FAST"
    ITALY_EXCHANGE = "ItalyExchange"
    LONDON_EXCHANGE = "LondonExchange"
    LONDON_METALS = "LondonMetals"
    US_BOND = "US_Bond"
    US_NERC = "US_NERC"
    XETRA = "Xetra"

    def __str__(self):
        return self.value


class ResetTiming(str, Enum):
    """Reset timing enumeration"""

    ADVANCE = "Advance"
    ARREARS = "Arrears"

    def __str__(self):
        return self.value


class Stub(str, Enum):
    """Stub rule enumeration"""

    SHORT_START = "ShortStart"
    LONG_START = "LongStart"
    SHORT_END = "ShortEnd"
    LONG_END = "LongEnd"
    SHORT_BOTH = "ShortBoth"
    LONG_BOTH = "LongBoth"
    NONE = "None"

    # Abbreviations
    SS = "SS"
    LS = "LS"
    SE = "SE"
    LE = "LE"

    def __str__(self):
        return self.value


class DateRule(str, Enum):
    """Date adjustment rule enumeration"""

    UNADJUSTED = "Unadjusted"
    FOLLOWING = "Following"
    MODIFIED_FOLLOWING = "ModifiedFollowing"
    PREVIOUS = "Previous"
    MODIFIED_PREVIOUS = "ModifiedPrevious"
    END_OF_MONTH = "EndOfMonth"
    FOLLOWING_UNADJUSTED = "FollowingUnadjusted"
    MODIFIED_FOLLOWING_UNADJUSTED = "ModifiedFollowingUnadjusted"
    UNADJUSTED_FOLLOWING = "UnadjustedFollowing"
    NONE = "None"

    def __str__(self):
        return self.value


class PayTiming(str, Enum):
    """Payment timing enumeration"""

    ADVANCE = "Advance"
    ARREARS = "Arrears"

    def __str__(self):
        return self.value


class PayReceive(Enum):
    """
    Pay/Receive direction enumeration.

    Used to indicate the direction of a leg in a swap or other structured product.

    Values:
        PAY: Pay leg (outflow)
        RECEIVE: Receive leg (inflow)
    """

    PAY = "Pay"
    RECEIVE = "Receive"


class RfrLag(Enum):
    """
    RFR (Risk-Free Rate) Lag Type enumeration.

    Used in IrIndex keyword for RFR calculations like SOFR, ESTR, etc.

    Values:
        LOOKBACK: Observation period shifted back
        SHIFT: Payment calculation shifted
        LOCKOUT: Rate frozen near end of period
        NONE: No lag adjustment

    Note: Additional values can be extracted from PIT C++ Lib if needed.
    """

    LOOKBACK = "LOOKBACK"
    SHIFT = "SHIFT"
    LOCKOUT = "LOCKOUT"
    NONE = "NONE"


class Index(str, Enum):
    """
    Interest Rate Index Type enumeration.

    Used in IrIndex keyword to specify the type of interest rate index.
    Extracted from PIT C_SI_IndexType constant.

    Values:
        FIXED: Fixed rate index
        RFR: Risk-Free Rate (e.g., SOFR, ESTR)
        EONIA: Euro OverNight Index Average
        OIS: Overnight Index Swap
        SONIA: Sterling Overnight Index Average
        OIS_ANNUAL: OIS Annual variant
        CDI: Brazilian CDI rate
        CDI_RATE: Brazilian CDI rate variant
        CASH: Cash rate
        LIBOR: London Interbank Offered Rate
        EURIBOR: Euro Interbank Offered Rate
        DEPOSIT: Deposit rate
        TAM: French TAM rate
        TAG: French TAG rate
        TMO: French TMO rate
        CMS: Constant Maturity Swap
        SWAPRATE: Swap rate
        CMT: Constant Maturity Treasury
        TEC10: French TEC10 rate
        KTB: Korean Treasury Bond
    """

    FIXED = "FIXED"
    RFR = "RFR"
    EONIA = "EONIA"
    OIS = "OIS"
    SONIA = "SONIA"
    OIS_ANNUAL = "OIS_ANNUAl"  # Note: Original has typo in C++ constant
    CDI = "CDI"
    CDI_RATE = "CDI_RATE"
    CASH = "CASH"
    LIBOR = "LIBOR"
    EURIBOR = "EURIBOR"
    DEPOSIT = "DEPOSIT"
    TAM = "TAM"
    TAG = "TAG"
    TMO = "TMO"
    CMS = "CMS"
    SWAPRATE = "SWAPRATE"
    CMT = "CMT"
    TEC10 = "TEC10"
    KTB = "KTB"

    def __str__(self):
        return self.value


# Alias: PaymentDateRule uses the same enum as DateRule
PaymentDateRule = DateRule

# Backward-compatible alias
Freq = Frequency
