import copy
import datetime
from typing import Any, Iterator, Literal, Optional, Union

from lseg_analytics.core.common._resource_base import ResourceBase
from lseg_analytics.core.exceptions import (
    LibraryException,
    ResourceNotFound,
    check_exception_and_raise,
    check_id,
)

from lseg_analytics.pricing._basic_client.models import (
    Amount,
    BachelierParameters,
    BasePricingParameters,
    BlackScholesEquityParameters,
    BlackScholesFxParameters,
    BlackScholesInterestRateFuture,
    CmdtyOptionVolSurfaceChoice,
    CmdtyVolSurfaceInput,
    ConvexityAdjustment,
    CreditCurveChoice,
    CreditCurveInput,
    CurveDataPoint,
    Dividend,
    DividendTypeEnum,
    EqOptionVolSurfaceChoice,
    EqVolSurfaceInput,
    FxCurveInput,
    FxForwardCurveChoice,
    FxOptionVolSurfaceChoice,
    FxPricingParameters,
    FxRateTypeEnum,
    FxVolSurfaceInput,
    Greeks,
    HestonEquityParameters,
    InnerError,
    IrCapVolSurfaceChoice,
    IrCurveChoice,
    IrMeasure,
    IrPricingParameters,
    IrSwapSolvingParameters,
    IrSwapSolvingTarget,
    IrSwapSolvingVariable,
    IrSwaptionVolCubeChoice,
    IrVolCubeInput,
    IrVolSurfaceInput,
    IrZcCurveInput,
    MarketData,
    MarketVolatility,
    Measure,
    ModelParameters,
    NumericalMethodEnum,
    OptionPricingParameters,
    OptionRiskFields,
    OptionSolvingParameters,
    OptionSolvingTarget,
    OptionSolvingVariable,
    OptionSolvingVariableEnum,
    PriceSideWithLastEnum,
    Rate,
    ServiceError,
    SolvingLegEnum,
    Spot,
    StrikeTypeEnum,
    StructuredNoteDefinition,
    StructuredNoteDefinitionInstrument,
    StructuredNoteInstrumentDescriptionFields,
    StructuredNoteInstrumentRiskFields,
    StructuredNoteInstrumentValuationFields,
    StructuredNotePricingParameters,
    StructuredNoteValuationResponseFieldsResponseData,
    StructuredNoteValuationResponseFieldsResponseWithError,
    SwapSolvingVariableEnum,
    TimeStampEnum,
    UnitEnum,
    VolatilityTypeEnum,
    VolCubePoint,
    VolModelTypeEnum,
    VolSurfacePoint,
    ZcTypeEnum,
)
from lseg_analytics.pricing._client.client import Client

from ._logger import logger

__all__ = [
    "Amount",
    "BachelierParameters",
    "BasePricingParameters",
    "BlackScholesEquityParameters",
    "BlackScholesFxParameters",
    "BlackScholesInterestRateFuture",
    "CmdtyOptionVolSurfaceChoice",
    "CmdtyVolSurfaceInput",
    "ConvexityAdjustment",
    "CreditCurveChoice",
    "CreditCurveInput",
    "CurveDataPoint",
    "Dividend",
    "DividendTypeEnum",
    "EqOptionVolSurfaceChoice",
    "EqVolSurfaceInput",
    "FxCurveInput",
    "FxForwardCurveChoice",
    "FxOptionVolSurfaceChoice",
    "FxPricingParameters",
    "FxRateTypeEnum",
    "FxVolSurfaceInput",
    "Greeks",
    "HestonEquityParameters",
    "IrCapVolSurfaceChoice",
    "IrCurveChoice",
    "IrMeasure",
    "IrPricingParameters",
    "IrSwapSolvingParameters",
    "IrSwapSolvingTarget",
    "IrSwapSolvingVariable",
    "IrSwaptionVolCubeChoice",
    "IrVolCubeInput",
    "IrVolSurfaceInput",
    "IrZcCurveInput",
    "MarketData",
    "MarketVolatility",
    "Measure",
    "ModelParameters",
    "NumericalMethodEnum",
    "OptionPricingParameters",
    "OptionRiskFields",
    "OptionSolvingParameters",
    "OptionSolvingTarget",
    "OptionSolvingVariable",
    "OptionSolvingVariableEnum",
    "PriceSideWithLastEnum",
    "Rate",
    "SolvingLegEnum",
    "Spot",
    "StrikeTypeEnum",
    "StructuredNoteDefinition",
    "StructuredNoteDefinitionInstrument",
    "StructuredNoteInstrumentDescriptionFields",
    "StructuredNoteInstrumentRiskFields",
    "StructuredNoteInstrumentValuationFields",
    "StructuredNotePricingParameters",
    "StructuredNoteValuationResponseFieldsResponseData",
    "StructuredNoteValuationResponseFieldsResponseWithError",
    "SwapSolvingVariableEnum",
    "TimeStampEnum",
    "UnitEnum",
    "VolCubePoint",
    "VolModelTypeEnum",
    "VolSurfacePoint",
    "VolatilityTypeEnum",
    "ZcTypeEnum",
    "value",
]


def value(
    *,
    definitions: list[StructuredNoteDefinitionInstrument],
    pricing_preferences: Optional[StructuredNotePricingParameters] = None,
    market_data: Optional[MarketData] = None,
    return_market_data: Optional[bool] = None,
    fields: Optional[str] = None,
) -> StructuredNoteValuationResponseFieldsResponseData:
    """
    Calculate the market value of a structured note provided in the request.

    Parameters
    ----------
    definitions : list[StructuredNoteDefinitionInstrument]
        Array (collection) of instrument definitions for the analytics computation.
    pricing_preferences : StructuredNotePricingParameters, optional
        Configuration parameters that control the analytics computation.
    market_data : MarketData, optional
        Market data inputs used for the analytics computation.
        Can include rates, curves, surfaces, quotes, and other relevant market data.
    return_market_data : bool, optional
        Controls whether market data used in computations should be included in the response.
        Set to true to include market data details in the response.
        Defaults to false.
    fields : str, optional
        A parameter used to select the fields to return in response. If not provided, all fields will be returned.
        Some usage examples:
        1. Simply enumerating the fields, separating them by ',', e.g. 'fields=//please insert the selected fields here, e.g., field1, field2 //'
        2. Using parentheses to indicate nesting, e.g. 'fields= //please insert the selected field and subfields here, e.g., field1(subfield1, subfield2), field2(subfield3)//’
        3. Using forward slash '/' to indicate nesting, e.g. 'fields=//please insert the selected field and subfields here, e.g.,  field1/subfield1, field1/subfield2, field2/subfield3//’ (same result as example above)
        4. Operators can even be combined (forward slashes in brackets, not the way around), e.g. 'fields=//please insert the selected field and subfields here, e.g.,  field1(subfield1/subsubfield1), field2/subfield2//'

    Returns
    --------
    StructuredNoteValuationResponseFieldsResponseData


    Examples
    --------


    """

    try:
        logger.info("Calling value")

        response = Client().structured_notes.value(
            fields=fields,
            definitions=definitions,
            pricing_preferences=pricing_preferences,
            market_data=market_data,
            return_market_data=return_market_data,
        )

        output = response.data
        logger.info("Called value")

        return output
    except Exception as err:
        logger.error("Error value.")
        check_exception_and_raise(err, logger)
