import requests
import mysql.connector
from datetime import datetime

# --- Configurações (Ajuste conforme seu ambiente) ---
# Você DEVE substituir 'SUA_API_KEY_DA_NEWSAPI' pela sua chave real.
# É uma boa prática usar variáveis de ambiente para chaves sensíveis!
NEWSAPI_KEY = "e9613ba6255d4b74aa57716956f5f6cc"
NEWSAPI_BASE_URL = "https://newsapi.org/v2/"

# Configurações do Banco de Dados MySQL
DB_CONFIG = {
    "host": "localhost",
    "user": "root",
    "password": "G9h6j3K1#",
    "database": "blueupnews"
}

# --- Funções de Coleta e Armazenamento ---

def fetch_news_from_api(endpoint="top-headlines", query="", language="pt", page_size=100, category=""):
    """
    Busca notícias da News API.
    :param endpoint: 'top-headlines' para notícias principais, 'everything' para notícias gerais.
    :param query: Termo de busca (obrigatório para 'everything', opcional para 'top-headlines').
    :param language: Idioma das notícias (ex: 'pt' para português).
    :param page_size: Número de resultados por página (máx. 100 para a maioria dos planos).
    :param category: Categoria (somente para 'top-headlines'). Ex: 'technology', 'business'.
    :return: Lista de artigos de notícias.
    """
    params = {
        "apiKey": NEWSAPI_KEY,
        "language": language,
        "pageSize": page_size
    }

    if endpoint == "top-headlines":
        if query:
            params["q"] = query
        if category:
            params["category"] = category
    elif endpoint == "everything":
        if not query:
            print("Erro: 'query' é obrigatório para o endpoint 'everything'.")
            return []
        params["q"] = query
    else:
        print(f"Erro: Endpoint '{endpoint}' inválido.")
        return []

    url = f"{NEWSAPI_BASE_URL}{endpoint}"

    try:
        response = requests.get(url, params=params)
        response.raise_for_status()  # Levanta um HTTPError para códigos de status de erro
        data = response.json()
        if data.get("status") == "ok":
            return data.get("articles", [])
        else:
            print(f"Erro da News API: {data.get('message')}")
            return []
    except requests.exceptions.RequestException as e:
        print(f"Erro de conexão ou requisição para a News API: {e}")
        return []
    except ValueError as e:
        print(f"Erro ao decodificar JSON da News API: {e}")
        return []

def save_news_to_database(news_articles):
    """
    Salva os artigos de notícia no banco de dados MySQL.
    Usa ON DUPLICATE KEY UPDATE para evitar duplicatas baseadas na url_original.
    """
    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()

        # Usamos ON DUPLICATE KEY UPDATE na url_original para evitar duplicatas.
        # Se uma notícia com a mesma URL já existir, ela será atualizada (ou ignorada se não houver campos para update).
        # Aqui, estamos atualizando resumo, conteudo_completo, url_imagem, data_publicacao.
        insert_query = """
        INSERT INTO noticias (
            titulo, resumo, conteudo_completo, url_original, url_imagem,
            fonte_nome, fonte_id, data_publicacao
        ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
        ON DUPLICATE KEY UPDATE
            resumo = VALUES(resumo),
            conteudo_completo = VALUES(conteudo_completo),
            url_imagem = VALUES(url_imagem),
            data_publicacao = VALUES(data_publicacao);
        """

        articles_inserted_or_updated = 0
        for article in news_articles:
            # Extraindo e formatando dados do artigo
            title = article.get("title")
            description = article.get("description")
            content = article.get("content") # Conteúdo parcial, geralmente
            url = article.get("url")
            url_to_image = article.get("urlToImage")
            source_name = article.get("source", {}).get("name")
            source_id = article.get("source", {}).get("id")
            published_at = article.get("publishedAt")

            # Validação básica para dados essenciais
            if not all([title, url, source_name, published_at]):
                # print(f"Aviso: Artigo ignorado devido a dados incompletos: {article.get('title')}")
                continue

            # Converte a string de data/hora para o formato datetime do Python,
            # depois para string no formato do MySQL se necessário, ou passa o objeto datetime direto.
            try:
                # News API retorna no formato ISO 8601 (ex: "2024-07-01T10:30:00Z")
                published_date = datetime.fromisoformat(published_at.replace('Z', '+00:00'))
            except ValueError:
                print(f"Aviso: Data de publicação inválida para '{title}'. Usando data/hora atual.")
                published_date = datetime.now()

            try:
                cursor.execute(insert_query, (
                    title,
                    description,
                    content,
                    url,
                    url_to_image,
                    source_name,
                    source_id,
                    published_date
                ))
                articles_inserted_or_updated += 1
            except mysql.connector.Error as err:
                # Erros podem ocorrer, por exemplo, se o título ou URL for muito longo
                print(f"Erro ao inserir/atualizar notícia '{title}': {err}")
                # O ideal seria logar isso em um arquivo para depuração posterior

        conn.commit()
        print(f"Operação concluída. {articles_inserted_or_updated} notícias processadas (inseridas/atualizadas).")

    except mysql.connector.Error as err:
        print(f"Erro de conexão ou operação no banco de dados: {err}")
    finally:
        if 'conn' in locals() and conn.is_connected():
            cursor.close()
            conn.close()

# --- Lógica Principal de Execução ---
if __name__ == "__main__":
    print(f"Iniciando coleta de notícias em {datetime.now()}...")

    # Exemplos de como buscar notícias:
    # 1. Notícias de topo em português (geral)
    print("\nColetando notícias principais em português...")
    top_headlines = fetch_news_from_api(endpoint="top-headlines", language="pt", page_size=50)
    save_news_to_database(top_headlines)

    # 2. Notícias sobre "inteligencia artificial" em português (tudo)
    print("\nColetando notícias sobre 'inteligencia artificial'...")
    ai_news = fetch_news_from_api(endpoint="everything", query="inteligencia artificial", language="pt", page_size=50)
    save_news_to_database(ai_news)

    # 3. Notícias de tecnologia (top-headlines)
    print("\nColetando notícias de tecnologia...")
    tech_news = fetch_news_from_api(endpoint="top-headlines", language="pt", category="technology", page_size=50)
    save_news_to_database(tech_news)

    # Adicione mais chamadas 'fetch_news_from_api' com as queries/categorias que desejar.
    # Lembre-se do limite de requisições da News API (100 requisições/dia para o plano de desenvolvedor).

    print(f"\nColeta de notícias finalizada em {datetime.now()}.")
