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 (
    FinancialContractResponse,
    ForwardRateAgreementAnalyticsResponseData,
    ForwardRateAgreementAnalyticsResponseWithError,
    ForwardRateAgreementCalculationResponse,
    ForwardRateAgreementCashflows,
    ForwardRateAgreementDefinition,
    ForwardRateAgreementDefinitionInstrument,
    ForwardRateAgreementDescription,
    ForwardRateAgreementNominalMeasures,
    ForwardRateAgreementPricingAnalysis,
    ForwardRateAgreementPricingParameters,
    ForwardRateAgreementValuation,
    Header,
    InnerError,
    InterestCalculationMethodEnum,
    MarketDataQps,
    PaymentBusinessDayConventionEnum,
    PriceSideEnum,
    ServiceError,
    TenorReferenceDateEnum,
    TypeEnum,
)
from lseg_analytics.pricing._client.client import Client

from ._logger import logger

__all__ = [
    "FinancialContractResponse",
    "ForwardRateAgreementAnalyticsResponseData",
    "ForwardRateAgreementAnalyticsResponseWithError",
    "ForwardRateAgreementCalculationResponse",
    "ForwardRateAgreementCashflows",
    "ForwardRateAgreementDefinition",
    "ForwardRateAgreementDefinitionInstrument",
    "ForwardRateAgreementDescription",
    "ForwardRateAgreementNominalMeasures",
    "ForwardRateAgreementPricingAnalysis",
    "ForwardRateAgreementPricingParameters",
    "ForwardRateAgreementValuation",
    "Header",
    "InterestCalculationMethodEnum",
    "MarketDataQps",
    "PaymentBusinessDayConventionEnum",
    "PriceSideEnum",
    "TenorReferenceDateEnum",
    "TypeEnum",
    "price",
]


def price(
    *,
    definitions: list[ForwardRateAgreementDefinitionInstrument],
    pricing_preferences: Optional[ForwardRateAgreementPricingParameters] = None,
    market_data: Optional[MarketDataQps] = None,
    return_market_data: Optional[bool] = None,
    fields: Optional[str] = None,
) -> ForwardRateAgreementCalculationResponse:
    """
    Calculate ForwardRateAgreement analytics

    Parameters
    ----------
    definitions : list[ForwardRateAgreementDefinitionInstrument]
        Array (collection) of instrument definitions for the analytics computation.
    pricing_preferences : ForwardRateAgreementPricingParameters, optional
        Configuration parameters that control the analytics computation.
    market_data : MarketDataQps, 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
    --------
    ForwardRateAgreementCalculationResponse
        Describes the analytics response for operations performed with instruments not stored on the platform.
        Used to return calculation results for multiple instruments defined in the request body.

    Examples
    --------
    >>> # Create FRA defintion object
    >>> fra_definition = fra.ForwardRateAgreementDefinition(
    >>>     start_tenor="2M", # mandatory
    >>>     fixed_rate_percent=4,
    >>>     end_tenor="8M", # mandatory
    >>>     notional_ccy="USD", # mandatory
    >>>     index_name="LIBOR",
    >>>     notional_amount=1000000
    >>> )
    >>>
    >>> # Create FRA instrument defintion object
    >>> fra_instrument = fra.ForwardRateAgreementDefinitionInstrument(
    >>>     definition = fra_definition
    >>> )
    >>>
    >>> # Create FRA pricing parameters object - optional
    >>> fra_parameters = fra.ForwardRateAgreementPricingParameters(
    >>>     valuation_date  = dt.datetime.strptime("2025-07-21", "%Y-%m-%d"),
    >>> )


    >>> # Execute the calculation using the price() function
    >>> # The 'definitions' parameter accepts a list of instruments definitions for batch processing
    >>>
    >>> fra_response = fra.price(
    >>>     definitions = [fra_instrument],
    >>>     pricing_preferences = fra_parameters
    >>> )

    """

    try:
        logger.info("Calling price")

        response = Client().forward_rate_agreement.price(
            fields=fields,
            definitions=definitions,
            pricing_preferences=pricing_preferences,
            market_data=market_data,
            return_market_data=return_market_data,
        )

        output = response
        logger.info("Called price")

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