"""
Announcements Routes - Public blueprint

Migrated from app.py as part of the blueprint refactoring.
Contains public-facing announcement routes for logged-in members.
"""

import logging
from datetime import datetime

from flask import flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required
from sqlalchemy import desc, func, or_
from sqlalchemy.dialects.postgresql import array as pg_array

from database import SessionLocal, Announcement, AnnouncementRead, User
from . import bp

logger = logging.getLogger(__name__)


# ============================================================
# PUBLIC ANNOUNCEMENTS PAGE
# ============================================================

@bp.route('/ogloszenia')
@login_required
def announcements_list():
    """Strona z listą ogłoszeń dla zalogowanych członków"""
    db = SessionLocal()
    try:
        page = request.args.get('page', 1, type=int)
        category = request.args.get('category', '')
        per_page = 12

        # Base query: published and not expired
        query = db.query(Announcement).filter(
            Announcement.status == 'published',
            or_(
                Announcement.expires_at.is_(None),
                Announcement.expires_at > datetime.now()
            )
        )

        # Filter by category (supports both single category and categories array)
        # Use PostgreSQL @> operator for array contains
        if category and category in Announcement.CATEGORIES:
            query = query.filter(Announcement.categories.op('@>')(pg_array([category])))

        # Sort: pinned first, then by published_at desc
        query = query.order_by(
            desc(Announcement.is_pinned),
            desc(Announcement.published_at)
        )

        # Pagination
        total = query.count()
        total_pages = (total + per_page - 1) // per_page
        announcements = query.offset((page - 1) * per_page).limit(per_page).all()

        return render_template('announcements/list.html',
                               announcements=announcements,
                               current_category=category,
                               categories=Announcement.CATEGORIES,
                               category_labels=Announcement.CATEGORY_LABELS,
                               page=page,
                               total_pages=total_pages,
                               total=total)

    finally:
        db.close()


@bp.route('/ogloszenia/<slug>')
@login_required
def announcement_detail(slug):
    """Szczegóły ogłoszenia dla zalogowanych członków"""
    db = SessionLocal()
    try:
        announcement = db.query(Announcement).filter(
            Announcement.slug == slug,
            Announcement.status == 'published',
            or_(
                Announcement.expires_at.is_(None),
                Announcement.expires_at > datetime.now()
            )
        ).first()

        if not announcement:
            flash('Nie znaleziono ogłoszenia lub zostało usunięte.', 'error')
            return redirect(url_for('announcements_list'))

        # Increment views counter
        announcement.views_count = (announcement.views_count or 0) + 1

        # Record read by current user (if not already recorded)
        existing_read = db.query(AnnouncementRead).filter(
            AnnouncementRead.announcement_id == announcement.id,
            AnnouncementRead.user_id == current_user.id
        ).first()

        if not existing_read:
            new_read = AnnouncementRead(
                announcement_id=announcement.id,
                user_id=current_user.id
            )
            db.add(new_read)

        db.commit()

        # Get readers (users who read this announcement)
        readers = db.query(AnnouncementRead).filter(
            AnnouncementRead.announcement_id == announcement.id
        ).order_by(desc(AnnouncementRead.read_at)).all()

        # Get total registered users count for percentage calculation
        total_users = db.query(func.count(User.id)).filter(
            User.is_active == True,
            User.is_verified == True
        ).scalar() or 1

        readers_count = len(readers)
        read_percentage = round((readers_count / total_users) * 100, 1) if total_users > 0 else 0

        # Get other recent announcements for sidebar
        other_announcements = db.query(Announcement).filter(
            Announcement.status == 'published',
            Announcement.id != announcement.id,
            or_(
                Announcement.expires_at.is_(None),
                Announcement.expires_at > datetime.now()
            )
        ).order_by(desc(Announcement.published_at)).limit(5).all()

        return render_template('announcements/detail.html',
                               announcement=announcement,
                               other_announcements=other_announcements,
                               category_labels=Announcement.CATEGORY_LABELS,
                               readers=readers,
                               readers_count=readers_count,
                               total_users=total_users,
                               read_percentage=read_percentage)

    finally:
        db.close()
