from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from openai import OpenAI
import os
from dotenv import load_dotenv
import threading
import time
import requests
from bs4 import BeautifulSoup

# Load env
load_dotenv()

app = Flask(__name__)

# ✅ DB (same as your Laravel connection)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:@localhost/dre'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# ✅ OpenAI key
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

# ✅ MODEL
class ScrapedArticle(db.Model):
    __tablename__ = 'scraped_article'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.Text)
    description = db.Column(db.Text)
    ai_summary = db.Column(db.Text)
    ai_category = db.Column(db.String(100)) 
    ai_tags = db.Column(db.Text)
    is_ticker = db.Column(db.Boolean)
    is_breaking = db.Column(db.Boolean)
    ticker_priority = db.Column(db.Integer)
     
# =========================
# 📰 SCRAPER (SIMPLE EXAMPLE)
# =========================
def fetch_news_cio():
    url = 'https://cioafrica.co/'
    headers = {'User-Agent': 'Mozilla/5.0'}
    response = requests.get(url, headers=headers)

    soup = BeautifulSoup(response.text, 'html.parser')

    articles = []
    items = soup.find_all('h4')[:5]

    for item in items:
        title = item.text.strip()
        link_tag = item.find('a')
        link = link_tag['href'] if link_tag else ''

        articles.append({
            'title': title,
            'description': title,
        })

    return articles

# =========================
# 💾 SAVE TO DB
# =========================
def save_articles(articles):
    for art in articles:
        exists = ScrapedArticle.query.filter_by(title=art['title']).first()

        # ✅ Generate BOTH
        ai_category = categorize_article(art['title'], art['description'])
        ai_tags = generate_ai_tags(art['title'], art['description'])

        if not exists:
            new_article = ScrapedArticle(
                title=art['title'],
                description=art['description'],
                ai_summary=None,
                ai_category=ai_category,
                ai_tags=ai_tags,   # 🔥 THIS WAS MISSING
                is_ticker=True,
                is_breaking=False,
                ticker_priority=10
            )

            db.session.add(new_article)

        else:
            # ✅ Update existing
            if not exists.ai_category:
                exists.ai_category = ai_category

            if not exists.ai_tags:
                exists.ai_tags = ai_tags

    db.session.commit()

# =========================
# 🤖 AI FUNCTION
# =========================
def generate_ai_summary(title, description):
    prompt = f"""
    Summarize this tech news in EXACTLY 30 words.

    Make it clear, informative, and engaging.

    Title: {title}
    Description: {description}
    """

    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=80   # 🔥 increased from 50
        )
        return response.choices[0].message.content.strip()

    except Exception as e:
        print(f"[❌ AI error]: {e}")
        return "Summary unavailable"


def generate_ai_tags(title, description):
    prompt = f"""
    Extract 3 to 6 short keywords (tags) from this tech news.

    Return as comma-separated values ONLY.

    Example:
    AI, Fintech, Kenya, Startups

    Title: {title}
    Description: {description}
    """

    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=30
        )

        tags = response.choices[0].message.content.strip()
        return tags

    except Exception as e:
        print(f"[❌ TAG ERROR]: {e}")
        return None
    
def categorize_article(title, description):
    prompt = f"""
    Categorize this tech news into ONE category:

    AI, Fintech, Startups, Cybersecurity, Telecom, Policy, Other

    Title: {title}
    Description: {description}

    Return ONLY the category name.
    """

    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=10
        )
        return response.choices[0].message.content.strip()
    except Exception as e:
        print(f"[❌ Category AI error]: {e}")
        return "Other"
# =========================
# 🤖 UPDATE AI
# =========================
def update_ai(limit=15):
    articles = ScrapedArticle.query.filter(
        ScrapedArticle.ai_summary == None
    ).order_by(ScrapedArticle.is_breaking.desc()).limit(limit).all()

    for article in articles:
        summary = generate_ai_summary(article.title, article.description)
        article.ai_summary = summary
        print(f"✅ AI Updated: {article.title[:40]}")

    db.session.commit()
def update_ai_category(limit=5):
    articles = ScrapedArticle.query.filter(
        (ScrapedArticle.ai_category == None) | (ScrapedArticle.ai_category == "Other")
    ).limit(limit).all()

    for article in articles:
        article.ai_category = categorize_article(article.title, article.description)
        print(f"✅ Category Updated: {article.title[:40]}")

    db.session.commit()


def update_ai_tags(limit=10):
    articles = ScrapedArticle.query.filter(
        ScrapedArticle.ai_tags == None
    ).limit(limit).all()

    for article in articles:
        article.ai_tags = generate_ai_tags(article.title, article.description)
        print(f"🏷 Tags Updated: {article.title[:40]}")

    db.session.commit()
# =========================
# 🧵 BACKGROUND AI
# =========================
def run_ai_background():
    with app.app_context():
        update_ai(limit=15)

# =========================
# 🔗 ROUTES
# =========================

# 👉 SCRAPE + AUTO AI
@app.route('/scrape')
def scrape_and_populate():
    with app.app_context():
        articles = fetch_news_cio()
        save_articles(articles)

    # Run AI in background
    threading.Thread(target=run_ai_background, daemon=True).start()

    return "Scraping done + AI running automatically"

# 👉 MANUAL AI
@app.route('/run-ai')
def run_ai():
    threading.Thread(target=run_ai_background, daemon=True).start()
    return "AI is running in background"


@app.route('/run-tags')
def run_tags():
    threading.Thread(target=update_ai_tags, daemon=True).start()
    return "AI Tags running"

# =========================
# 🔄 AUTO PIPELINE (FULL AUTO)
# =========================
def auto_pipeline():
    while True:
        print("🔄 Scraping...")
        with app.app_context():
            articles = fetch_news_cio()
            save_articles(articles)

        print("🤖 Running AI...")
        with app.app_context():
            update_ai(limit=5)

        print("✅ Done. Waiting 5 minutes...\n")
        time.sleep(300)  # 5 minutes

def run_category_background():
    with app.app_context():
        update_ai_category(limit=5)

@app.route('/run-category')
def run_category():
    threading.Thread(target=run_category_background, daemon=True).start()
    return "Category AI running"

if __name__ == "__main__":
    app.run(debug=True)