import copy
import datetime
from typing import Any, Dict, Iterator, List, 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)
