from typing import Any, Dict, List

from fastapi import APIRouter, HTTPException, Response, status

from src.core.db import SessionDep
from src.core.deps import CurrentUserDep
from src.group_settings.models import GroupConfig
from src.group_settings.repo import GroupConfigRepoDep
from src.services.logging_service import log_action
from src.services.api_service import fetch_event_tn_data
from src.services.campflow import get_campflow_client
from src.services.google_groups import check_user_in_group
from src.services.pdf_service import generate_event_pdfs
from src.services.stats_service import generate_statistics
from src.services.group_stats_service import get_group_event_stats, compute_cross_event_summary

router = APIRouter(tags=["events"])


async def _get_authorized_groups(
    user_email: str, group_config_repo: GroupConfigRepoDep
) -> List[GroupConfig]:
    """Return all GroupConfigs the user is a member of."""
    all_configs = await group_config_repo.get_all()
    authorized = []
    for config in all_configs:
        if check_user_in_group(user_email, config):
            authorized.append(config)
    return authorized


async def _get_group_for_event(
    lst_id: str,
    user_email: str,
    group_config_repo: GroupConfigRepoDep,
) -> GroupConfig:
    """Find the specific group that owns this event and that the user is a member of."""
    authorized_groups = await _get_authorized_groups(user_email, group_config_repo)
    if not authorized_groups:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="You must be a member of a registered Google Group to view events.",
        )

    for config in authorized_groups:
        client = get_campflow_client(config)
        event = await client.get_event_details(lst_id)
        if event:
            return config

    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail="You are not authorized to access this event.",
    )


@router.get("/events", response_model=List[Dict[str, Any]])
async def get_all_events(
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
) -> Any:
    """Fetch events from the Campflow API using all authorized group credentials."""
    authorized_groups = await _get_authorized_groups(current_user.email, group_config_repo)
    
    all_events = []
    for config in authorized_groups:
        client = get_campflow_client(config)
        events = await client.get_events()
        # Tag events with their group for better context in audit logs/UI
        for event in events:
            event["group_email"] = config.group_email
        all_events.extend(events)
    
    return all_events


@router.get("/events/{lst_id}/stats")
async def get_event_stats(
    lst_id: str,
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
):
    group_config = await _get_group_for_event(lst_id, current_user.email, group_config_repo)
    tn, gf, event_info = await fetch_event_tn_data(lst_id, group_config=group_config)
    if not event_info:
        raise HTTPException(status_code=404, detail="Event not found")
    stats = generate_statistics(tn, gf, event_info)
    return stats


@router.get("/events/{lst_id}/pdf/{pdf_type}")
async def download_event_pdf(
    lst_id: str,
    pdf_type: str,
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
    session: SessionDep,
):
    group_config = await _get_group_for_event(lst_id, current_user.email, group_config_repo)
    list_bytes, info_bytes, event_info = await generate_event_pdfs(lst_id, group_config=group_config)
    if not event_info:
        raise HTTPException(status_code=404, detail="Event not found")

    from src.services.pdf_service import make_filename_safe
    prefix = group_config.pdf_filename or "TN"
    safe_title = make_filename_safe(event_info.get("title", "Event"))

    if pdf_type == "list":
        content = list_bytes
        filename = f"{prefix}-Liste-{safe_title}.pdf"
    elif pdf_type == "info":
        content = info_bytes
        filename = f"{prefix}-Info-{safe_title}.pdf"
    else:
        raise HTTPException(status_code=400, detail="Invalid PDF type")

    if not content:
        raise HTTPException(status_code=500, detail="Failed to generate PDF")

    # Audit Log
    await log_action(
        session=session,
        group_email=group_config.group_email,
        user_email=current_user.email,
        action="DOWNLOAD_PDF",
        details=f"Downloaded {pdf_type} PDF for event: {event_info.get('title')} ({lst_id})"
    )

    return Response(
        content=content,
        media_type="application/pdf",
        headers={"Content-Disposition": f"attachment; filename={filename}"},
    )


@router.get("/groups/{group_email}/stats")
async def get_group_stats(
    group_email: str,
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
):
    """
    Return anonymous, cross-event aggregate stats for every event in the group.
    Data is cached server-side (permanent for non-published events, 4h TTL for
    published events) to minimise Campflow API calls.
    """
    # Verify the caller is actually a member of the requested group
    authorized_groups = await _get_authorized_groups(current_user.email, group_config_repo)
    group_config = next(
        (g for g in authorized_groups if g.group_email == group_email), None
    )
    if not group_config:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="You are not a member of this group.",
        )

    events_stats = await get_group_event_stats(group_config)
    summary = compute_cross_event_summary(events_stats)

    return {
        "group_email": group_email,
        "events": events_stats,
        "summary": summary,
    }
