from datetime import datetime

from flask import Blueprint, abort, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required

from app.extensions import db
from app.models import Activity, ActivityRegistration, CauseCategory, City
from app.models.enums import ActivityStatus, RegistrationStatus
from .services import RegistrationError, RegistrationService

bp = Blueprint("seva_bhaav", __name__, url_prefix="/seva-bhaav")


@bp.route("/")
def list_activities():
    query = Activity.query.filter_by(status=ActivityStatus.PUBLISHED)
    city_id = request.args.get("city_id", type=int)
    category_id = request.args.get("category_id", type=int)
    q = request.args.get("q", "").strip()
    if city_id:
        query = query.filter(Activity.city_id == city_id)
    if category_id:
        query = query.filter(Activity.cause_category_id == category_id)
    if q:
        query = query.filter(Activity.title.ilike(f"%{q}%"))
    activities = query.order_by(Activity.start_datetime.asc()).all()
    return render_template(
        "seva_bhaav/list.html",
        activities=activities,
        cities=City.query.filter_by(is_active=True).order_by(City.name).all(),
        categories=CauseCategory.query.filter_by(is_active=True).order_by(CauseCategory.name).all(),
    )


@bp.route("/<int:activity_id>")
def detail(activity_id):
    activity = db.session.get(Activity, activity_id)
    if not activity or activity.status != ActivityStatus.PUBLISHED:
        abort(404)
    registered = None
    if current_user.is_authenticated and current_user.employee:
        registered = ActivityRegistration.query.filter_by(
            activity_id=activity.id,
            employee_id=current_user.employee.id,
        ).first()
    confirmed_count = ActivityRegistration.query.filter(
        ActivityRegistration.activity_id == activity.id,
        ActivityRegistration.status.in_([
            RegistrationStatus.REGISTERED,
            RegistrationStatus.CONFIRMED,
            RegistrationStatus.ATTENDED,
            RegistrationStatus.COMPLETED,
        ]),
    ).count()
    remaining = max(0, activity.capacity - confirmed_count) if activity.capacity else None
    return render_template("seva_bhaav/detail.html", activity=activity, registration=registered, remaining=remaining)


@bp.route("/<int:activity_id>/register", methods=["GET", "POST"])
@login_required
def register(activity_id):
    activity = db.session.get(Activity, activity_id)
    if not activity or activity.status != ActivityStatus.PUBLISHED:
        abort(404)
    employee = current_user.employee
    if not employee or not employee.eligible_for_portal:
        abort(403)

    if request.method == "POST":
        try:
            participation_id = f"PSS-{datetime.now().strftime('%Y%m%d')}-{ActivityRegistration.query.count() + 1:05d}"
            registration = RegistrationService.register_employee(
                activity,
                employee,
                participation_id,
                request.form,
            )
            if registration.status == RegistrationStatus.PENDING_APPROVAL:
                flash("Your nomination has been sent to your manager for approval.", "info")
            else:
                flash("You're in! Your participation is confirmed.", "success")
            return redirect(url_for("employee.my_seva"))
        except RegistrationError as exc:
            db.session.rollback()
            flash(str(exc), "danger")

    return render_template("seva_bhaav/register.html", activity=activity, employee=employee)
