def handle_response(response):
    if response.status_code == 200:
        return response.json()
    else:
        return {"error": f"Failed to fetch data. Status code: {response.status_code}"}

def get_income_statement(ticker, period='annual', limit=5):
    """
    Fetches the income statement for a given company (ticker) over a specified period and with a limit on the number of records returned.

    Parameters:
    -----------
    ticker : str
        The stock symbol or CIK (Central Index Key) for the company (e.g., 'AAPL' for Apple or '0000320193' for its CIK).

    period : str, optional
        The reporting period for the income statement. Allowable values are:
        - 'annual'  : Retrieves the annual income statement (default).
        - 'quarter' : Retrieves the quarterly income statement.

    limit : int, optional
        Limits the number of records returned. The default value is 5.

    Returns:
    --------
    dict or list of dict
        The income statement data, including fields like date, symbol, reported currency, filing date, etc.

    Example:
    --------
    get_income_statement('AAPL', period='annual', limit=5)

    Response format:
    ----------------
    [
        {
            "date": "2022-09-24",
            "symbol": "AAPL",
            "reportedCurrency": "USD",
            "cik": "0000320193",
            "fillingDate": "2022-10-28",
            "acceptedDate": "2022-10-27 18:01:14",
            ...
        },
        ...
    ]
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    params = {
        "period": period,   # Accepts 'annual' or 'quarter'
        "limit": limit,     # Limits the number of records returned
        "apikey": os.environ['FMP_API_KEY']   # API Key for authentication
    }

    # Construct the full URL with query parameters
    endpoint = f"{BASE_URL}/income-statement/{ticker}?{urlencode(params)}"

    response = requests.get(endpoint)
    return handle_response(response)

def ticker_search(query, limit=10, exchange='NYSE'):
    """
    Searches for ticker symbols and exchanges for both equity securities and exchange-traded funds (ETFs)
    by searching with the company name or ticker symbol.

    Parameters:
    -----------
    query : str
        The name or ticker symbol to search for (e.g., 'AA' for Alcoa).

    limit : int, optional
        Limits the number of records returned. The default is 10.

    exchange : str, optional
        Specifies the exchange to filter results by. Allowable values include:
        - 'NYSE'   : New York Stock Exchange (default).
        - 'NASDAQ' : NASDAQ Exchange.
        - Other exchange codes supported by the API.

    Returns:
    --------
    dict or list of dict
        The search results, including the symbol, name, currency, stock exchange, and exchange short name.

    Example:
    --------
    ticker_search('AA', limit=10, exchange='NASDAQ')

    Response format:
    ----------------
    [
        {
            "symbol": "PRAA",
            "name": "PRA Group, Inc.",
            "currency": "USD",
            "stockExchange": "NasdaqGS",
            "exchangeShortName": "NASDAQ"
        },
        {
            "symbol": "PAAS",
            "name": "Pan American Silver Corp.",
            "currency": "USD",
            "stockExchange": "NasdaqGS",
            "exchangeShortName": "NASDAQ"
        },
        ...
    ]
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    
    params = {
        "limit": limit,
        "exchange": exchange,
        "apikey": os.environ['FMP_API_KEY']
    }

    endpoint = f"{BASE_URL}/search?query={query}&{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def company_profile(symbol):
    """
    Fetches a company's profile, including key stats such as price, market capitalization, beta, and other essential details.

    Parameters:
    -----------
    symbol : str
        The stock ticker symbol or CIK (Central Index Key) for the company (e.g., 'AAPL' for Apple).

    Returns:
    --------
    dict or list of dict
        The company's profile data, including fields such as symbol, price, beta, market cap, industry, CEO, and description.

    Example:
    --------
    company_profile('AAPL')

    Response format:
    ----------------
    [
        {
            "symbol": "AAPL",
            "price": 145.30,
            "beta": 1.25,
            "volAvg": 98364732,
            "mktCap": 2423446000000,
            "lastDiv": 0.88,
            "range": "122.25-157.33",
            "changes": -2.00,
            "companyName": "Apple Inc.",
            "currency": "USD",
            "cik": "0000320193",
            "isin": "US0378331005",
            "cusip": "037833100",
            "exchange": "NasdaqGS",
            "exchangeShortName": "NASDAQ",
            "industry": "Consumer Electronics",
            "website": "https://www.apple.com",
            "description": "Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories worldwide."
        }
    ]
    """

    BASE_URL = "https://financialmodelingprep.com/api/v3"
    
    params = {
        'apikey': os.environ['FMP_API_KEY']
    }

    endpoint = f"{BASE_URL}/profile/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def stock_grade(symbol, limit = 500):

  BASE_URL = "https://financialmodelingprep.com/api/v3"

  params = {
      'apikey':os.environ['FMP_API_KEY'],
      'limit':limit
  }

  endpoint = f"{BASE_URL}/grade/{symbol}?{urlencode(params)}"
  response = requests.get(endpoint)
  return handle_response(response)

def current_market_cap(symbol):
    """
    Fetches the current market capitalization of a given company based on its stock symbol.

    Parameters:
    -----------
    symbol : str
        The stock ticker symbol for the company (e.g., 'AAPL' for Apple).

    Returns:
    --------
    dict or list of dict
        The market capitalization data, including fields such as symbol, date, and market cap.

    Example:
    --------
    current_market_cap('AAPL')

    Response format:
    ----------------
    [
        {
            "symbol": "AAPL",
            "date": "2023-03-02",
            "marketCap": 2309048053309
        }
    ]
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    params = {
        'apikey': os.environ['FMP_API_KEY']
    }

    endpoint = f"{BASE_URL}/market-capitalization/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def historical_market_cap(symbol, from_date=None, to_date=None, limit=None):
    """
    Fetches the historical market capitalization of a given company within a specified date range.

    Parameters:
    -----------
    symbol : str
        The stock ticker symbol for the company (e.g., 'AAPL' for Apple).

    from_date : str, optional
        The start date for the historical data in 'YYYY-MM-DD' format (e.g., '2023-10-10').
        Default is None, which fetches data from the earliest available date.

    to_date : str, optional
        The end date for the historical data in 'YYYY-MM-DD' format (e.g., '2023-12-10').
        Default is None, which fetches data up to the latest available date.

    limit : int, optional
        Limits the number of records returned. Default is None, which fetches all available records.

    Returns:
    --------
    dict or list of dict
        The historical market cap data, including fields such as symbol, date, and market capitalization.

    Example:
    --------
    historical_market_cap('AAPL', from_date='2023-10-10', to_date='2023-12-10', limit=100)

    Response format:
    ----------------
    [
        {
            "symbol": "AAPL",
            "date": "2023-03-02",
            "marketCap": 2313794623242
        }
    ]
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    params = {
        'apikey': os.environ['FMP_API_KEY'],
        'from': from_date,
        'to': to_date,
        'limit': limit
    }

    endpoint = f"{BASE_URL}/historical-market-capitalization/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def analyst_recommendations(symbol):
    """
    Fetches the analyst recommendations for a given company based on its stock symbol.
    This includes buy, hold, and sell ratings.

    Parameters:
    -----------
    symbol : str
        The stock ticker symbol for the company (e.g., 'AAPL' for Apple).

    Returns:
    --------
    dict or list of dict
        The analyst recommendation data, including fields such as buy, hold, sell, and strong buy ratings.

    Example:
    --------
    analyst_recommendations('AAPL')

    Response format:
    ----------------
    [
        {
            "symbol": "AAPL",
            "date": "2023-08-01",
            "analystRatingsBuy": 21,
            "analystRatingsHold": 6,
            "analystRatingsSell": 0,
            "analystRatingsStrongSell": 0,
            "analystRatingsStrongBuy": 11
        }
    ]
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    params = {
        'apikey': os.environ['FMP_API_KEY']
    }

    endpoint = f"{BASE_URL}/analyst-stock-recommendations/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def stock_peers(symbol):
    """
    Fetches a list of companies that are considered peers of the given company.
    These peers are companies that trade on the same exchange, are in the same sector,
    and have a similar market capitalization.

    Parameters:
    -----------
    symbol : str
        The stock ticker symbol for the company (e.g., 'AAPL' for Apple).

    Returns:
    --------
    dict or list of dict
        The peers data, including a list of peer company ticker symbols.

    Example:
    --------
    stock_peers('AAPL')

    Response format:
    ----------------
    [
        {
            "symbol": "AAPL",
            "peersList": [
                "LPL",
                "SNEJF",
                "PCRFY",
                "SONO",
                "VZIO",
                ...
            ]
        }
    ]
    """
    params = {
        'apikey': os.environ['FMP_API_KEY'],
        'symbol': symbol
    }

    BASE_URL = "https://financialmodelingprep.com/api/v4"
    endpoint = f"{BASE_URL}/stock_peers?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def earnings_historical_and_upcoming(symbol, limit=100):
    """
    Fetches historical and upcoming earnings announcements for a given company.
    The response includes the date, EPS (earnings per share), estimated EPS, revenue, and estimated revenue.

    Parameters:
    -----------
    symbol : str
        The stock ticker symbol for the company (e.g., 'AAPL' for Apple).

    limit : int, optional
        Limits the number of records returned. The default is 100.

    Returns:
    --------
    dict or list of dict
        The earnings data, including fields such as date, EPS, estimated EPS, revenue, and estimated revenue.

    Example:
    --------
    earnings_historical_and_upcoming('AAPL', limit=100)

    Response format:
    ----------------
    [
        {
            "date": "1998-10-14",
            "symbol": "AAPL",
            "eps": 0.0055,
            "epsEstimated": 0.00393,
            "time": "amc",
            "revenue": 1556000000,
            "revenueEstimated": 2450700000,
            "updatedFromDate": "2023-12-04",
            "fiscalDateEnding": "1998-09-25"
        }
    ]
    """
    params = {
        'apikey': os.environ['FMP_API_KEY'],
        'limit': limit
    }

    endpoint = f"{BASE_URL}/historical/earning_calendar/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)

def intraday_stock_prices(timeframe, symbol, from_date=None, to_date=None, extended='false'):
    """
    Fetches the historical intraday stock price for a given company over a specified timeframe.

    Parameters:
    -----------
    timeframe : str
        The time interval for the stock data. Allowable values are:
        - '1min'  : 1 minute interval
        - '5min'  : 5 minute interval
        - '15min' : 15 minute interval
        - '30min' : 30 minute interval
        - '1hour' : 1 hour interval
        - '4hour' : 4 hour interval

    symbol : str
        The stock symbol for which to retrieve the data (e.g., 'AAPL' for Apple).

    from_date : str, optional
        The start date for the historical data in 'YYYY-MM-DD' format (e.g., '2023-08-10').
        Default is None, which fetches all available data up to the present.

    to_date : str, optional
        The end date for the historical data in 'YYYY-MM-DD' format (e.g., '2023-09-10').
        Default is None, which fetches data from the beginning up to the current date.

    extended : str, optional
        Whether to fetch extended market data (pre-market and after-hours).
        Allowable values:
        - 'true'  : Fetch extended market data
        - 'false' : Fetch only regular market hours data (default).

    Returns:
    --------
    dict or list of dict
        The historical intraday stock data, including open, high, low, close, and volume for each time interval.

    Example:
    --------
    intraday_stock_price('5min', 'AAPL', from_date='2023-08-10', to_date='2023-09-10', extended='false')

    Response format:
    ----------------
    [
        {
            "date": "2023-03-02 16:00:00",
            "open": 145.92,
            "low": 145.72,
            "high": 146.00,
            "close": 145.79,
            "volume": 1492644
        },
        ...
    ]
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    params = {
        'apikey': os.environ['FMP_API_KEY'],
        'from': from_date,
        'to': to_date,
        'extended': extended
    }

    endpoint = f"{BASE_URL}/historical-chart/{timeframe}/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)



def daily_stock_prices(symbol, from_date=None, to_date=None, serietype='line'):
    """
    Fetches the daily End-Of-Day (EOD) stock price for a given company over a specified date range.

    Parameters:
    -----------
    symbol : str
        The stock symbol for which to retrieve the data (e.g., 'AAPL' for Apple).

    from_date : str, optional
        The start date for the historical data in 'YYYY-MM-DD' format (e.g., '1990-10-10').
        Default is None, which fetches the earliest available data.

    to_date : str, optional
        The end date for the historical data in 'YYYY-MM-DD' format (e.g., '2023-10-10').
        Default is None, which fetches data up to the most recent date.

    serietype : str, optional
        The type of data series to return. Allowable values are:
        - 'line'  : Line chart data (default).
        - 'other types' can be specified if supported by the API in the future.

    Returns:
    --------
    dict or list of dict
        The daily stock data, including open, high, low, close, volume, adjusted close, etc.

    Example:
    --------
    daily_stock_price('AAPL', from_date='1990-10-10', to_date='2023-10-10', serietype='line')

    Response format:
    ----------------
    {
        "symbol": "AAPL",
        "historical": [
            {
                "date": "2023-10-06",
                "open": 173.8,
                "high": 176.61,
                "low": 173.18,
                "close": 176.53,
                "adjClose": 176.53,
                "volume": 21712747,
                "unadjustedVolume": 21712747,
                "change": 2.73,
                "changePercent": 1.57077,
                "vwap": 175.44,
                "label": "October 06, 23",
                "changeOverTime": 0.0157077
            },
            ...
        ]
    }
    """
    BASE_URL = "https://financialmodelingprep.com/api/v3"
    params = {
        'apikey': os.environ['FMP_API_KEY'],
        'from': from_date,
        'to': to_date,
        'serietype': serietype
    }

    endpoint = f"{BASE_URL}/historical-price-full/{symbol}?{urlencode(params)}"
    response = requests.get(endpoint)
    return handle_response(response)