""" Finnhub Model """
__docformat__ = "numpy"

import logging

from datetime import datetime, timedelta
from typing import List, Dict, Optional
import finnhub
import pandas as pd
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
from openbb_terminal import config_terminal as cfg
from openbb_terminal.decorators import check_api_key, log_start_end
from openbb_terminal.helper_funcs import similar
from openbb_terminal.rich_config import console

logger = logging.getLogger(__name__)


@log_start_end(log=logger)
@check_api_key(["API_FINNHUB_KEY"])
def get_company_news(
    symbol: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
) -> List[Dict]:
    """Get news from a company. [Source: Finnhub]

    Parameters
    ----------
    symbol : str
        company ticker to look for news articles
    start_date: Optional[str]
        date to start searching articles, with format YYYY-MM-DD
    end_date: Optional[str]
        date to end searching articles, with format YYYY-MM-DD

    Returns
    -------
    articles : List
        term to search on the news articles
    """

    if start_date is None:
        start_date = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d")

    if end_date is None:
        end_date = datetime.now().strftime("%Y-%m-%d")

    try:
        finnhub_client = finnhub.Client(api_key=cfg.API_FINNHUB_KEY)
        articles = finnhub_client.company_news(
            symbol.upper(), _from=start_date, to=end_date
        )
        return articles

    except Exception as e:
        console.print(f"[red]{e}\n[/red]")
        return [{}]


@log_start_end(log=logger)
def process_news_headlines_sentiment(
    articles: List[Dict],
) -> pd.DataFrame:
    """Process news headlines sentiment of a company using a VADER model.

    Parameters
    ----------
    articles : List[Dict]
        list of articles with `headline` and `datetime` keys

    Returns
    -------
    pd.DataFrame
        Headlines sentiment using VADER model over time
    """
    l_datetime = list()
    l_compound = list()

    if articles and len(articles) > 1:
        analyzer = SentimentIntensityAnalyzer()

        last_headline = ""
        for article in articles:
            # allows to discard news with similar headline
            if similar(last_headline, article["headline"].upper()) < 0.7:
                l_compound.append(
                    analyzer.polarity_scores(article["headline"])["compound"]
                )
                l_datetime.append(datetime.fromtimestamp(article["datetime"]))
                last_headline = article["headline"].upper()

    return pd.DataFrame(l_compound, index=l_datetime).sort_index()


@log_start_end(log=logger)
def get_headlines_sentiment(
    symbol: str,
) -> pd.DataFrame:
    """Get headlines sentiment using VADER model over time. [Source: Finnhub]

    Parameters
    ----------
    symbol : str
        Ticker of company

    Returns
    ----------
    pd.DataFrame
        The news article information
    """
    start = datetime.now() - timedelta(days=30)
    if not symbol:
        console.print("[red]Do not run this command without setting a ticker.[/red]\n")
        return pd.DataFrame()

    articles = get_company_news(
        symbol.upper(),
        start_date=start.strftime("%Y-%m-%d"),
        end_date=datetime.now().strftime("%Y-%m-%d"),
    )
    sentiment = process_news_headlines_sentiment(articles)

    return sentiment
