"""
Article routes for ScholarPress.
"""

from flask import Blueprint, render_template, request, current_app, send_from_directory, abort
from flask_login import login_required, current_user
from app.models import Article, Journal, Tag, SiteSettings
from app import db
import os

articles_bp = Blueprint('articles', __name__)


@articles_bp.route('/')
def list_articles():
    """List all published articles with search and filtering."""
    settings = SiteSettings.query.first()
    
    page = request.args.get('page', 1, type=int)
    per_page = current_app.config.get('ARTICLES_PER_PAGE', 10)
    
    # Search parameters
    query = request.args.get('q', '').strip()
    tag_filter = request.args.get('tag', '').strip()
    journal_filter = request.args.get('journal', '').strip()
    author_filter = request.args.get('author', '').strip()
    
    # Base query
    articles_query = Article.query.filter_by(is_published=True)
    
    # Apply search filters
    if query:
        search_term = f"%{query}%"
        articles_query = articles_query.filter(
            db.or_(
                Article.title.ilike(search_term),
                Article.abstract.ilike(search_term),
                Article.authors.ilike(search_term),
                Article.meta_keywords.ilike(search_term)
            )
        )
    
    if tag_filter:
        tag = Tag.query.filter_by(slug=tag_filter).first()
        if tag:
            articles_query = articles_query.filter(Article.tags.contains(tag))
    
    journal_name = ''
    if journal_filter:
        journal = Journal.query.filter_by(slug=journal_filter).first()
        if journal:
            articles_query = articles_query.filter_by(journal_id=journal.id)
            journal_name = journal.name
    
    if author_filter:
        articles_query = articles_query.filter(Article.authors.ilike(f"%{author_filter}%"))
    
    # Order and paginate
    articles = articles_query.order_by(Article.published_date.desc())\
        .paginate(page=page, per_page=per_page, error_out=False)
    
    # Get all tags and journals for filters
    all_tags = Tag.query.order_by(Tag.name).all()
    all_journals = Journal.query.filter_by(is_active=True).order_by(Journal.name).all()
    
    return render_template('public/articles.html',
                         settings=settings,
                         articles=articles,
                         all_tags=all_tags,
                         all_journals=all_journals,
                         query=query,
                         tag_filter=tag_filter,
                         journal_filter=journal_filter,
                         journal_name=journal_name,
                         author_filter=author_filter)


@articles_bp.route('/preview/<int:id>')
@login_required
def preview_article(id):
    """Preview an article (including drafts) - admin only."""
    if not current_user.is_admin():
        abort(403)
    settings = SiteSettings.query.first()
    article = Article.query.get_or_404(id)
    
    # Get related articles (same journal or shared tags)
    related_articles = Article.query.filter(
        Article.id != article.id,
        Article.is_published == True,
        db.or_(
            Article.journal_id == article.journal_id,
            Article.tags.any(Tag.id.in_([t.id for t in article.tags]))
        )
    ).order_by(Article.published_date.desc()).limit(5).all()
    
    return render_template('public/article_detail.html',
                         settings=settings,
                         article=article,
                         related_articles=related_articles,
                         is_preview=True)


@articles_bp.route('/<slug>')
def article_detail(slug):
    """Article detail page with SEO meta tags."""
    settings = SiteSettings.query.first()
    article = Article.query.filter_by(slug=slug, is_published=True).first_or_404()
    
    # Increment view count
    article.view_count += 1
    db.session.commit()
    
    # Get related articles (same journal or shared tags)
    related_articles = Article.query.filter(
        Article.id != article.id,
        Article.is_published == True,
        db.or_(
            Article.journal_id == article.journal_id,
            Article.tags.any(Tag.id.in_([t.id for t in article.tags]))
        )
    ).order_by(Article.published_date.desc()).limit(5).all()
    
    return render_template('public/article_detail.html',
                         settings=settings,
                         article=article,
                         related_articles=related_articles)


@articles_bp.route('/<slug>/download')
def download_article(slug):
    """Download article PDF."""
    article = Article.query.filter_by(slug=slug, is_published=True).first_or_404()
    
    if not article.pdf_file:
        abort(404, "PDF not available for this article.")
    
    # Increment download count
    article.download_count += 1
    db.session.commit()
    
    # Get the file path
    upload_folder = current_app.config['UPLOAD_FOLDER']
    file_path = os.path.dirname(article.pdf_file)
    filename = os.path.basename(article.pdf_file)
    
    return send_from_directory(
        os.path.join(upload_folder, file_path),
        filename,
        as_attachment=True,
        download_name=f"{article.slug}.pdf"
    )


@articles_bp.route('/tag/<slug>')
def articles_by_tag(slug):
    """List articles by tag."""
    settings = SiteSettings.query.first()
    tag = Tag.query.filter_by(slug=slug).first_or_404()
    
    page = request.args.get('page', 1, type=int)
    per_page = current_app.config.get('ARTICLES_PER_PAGE', 10)
    
    articles = Article.query.filter(
        Article.is_published == True,
        Article.tags.contains(tag)
    ).order_by(Article.published_date.desc())\
        .paginate(page=page, per_page=per_page, error_out=False)
    
    return render_template('public/articles_by_tag.html',
                         settings=settings,
                         tag=tag,
                         articles=articles)


@articles_bp.route('/search')
def search():
    """Advanced search page."""
    settings = SiteSettings.query.first()
    all_tags = Tag.query.order_by(Tag.name).all()
    all_journals = Journal.query.filter_by(is_active=True).order_by(Journal.name).all()
    
    return render_template('public/search.html',
                         settings=settings,
                         all_tags=all_tags,
                         all_journals=all_journals)
