"""
Activity Log Report Service + write helper
"""
import logging
from datetime import date, datetime, timedelta, timezone
from typing import Optional, List

from sqlalchemy import select, and_, or_, func
from sqlalchemy.orm import Session

from src.apps.reports.schemas.activity_log import (
    ActivityLogEntry, ActivityLogDateGroup, ActivityLogResponse
)

logger = logging.getLogger(__name__)


async def write_activity(
    db: Session,
    merchant_id: int,
    event_type: str,
    event_category: str,
    description: str,
    actor_type: str = "system",
    actor_id: Optional[int] = None,
    actor_name: Optional[str] = None,
    reference_type: Optional[str] = None,
    reference_id: Optional[str] = None,
    metadata: Optional[dict] = None,
) -> None:
    """Fire-and-forget: swallows exceptions to avoid disrupting callers."""
    try:
        from src.apps.reports.models.system_activity_log import SystemActivityLog
        entry = SystemActivityLog(
            merchant_id=int(merchant_id),
            event_type=event_type,
            event_category=event_category,
            description=description,
            actor_type=actor_type,
            actor_id=actor_id,
            actor_name=actor_name or ("System" if actor_type == "system" else None),
            reference_type=reference_type,
            reference_id=reference_id,
            metadata_=metadata,
        )
        db.add(entry)
        db.flush()
    except Exception as exc:
        logger.debug(f"write_activity swallowed error: {exc}")


def get_activity_logs(
    db: Session,
    merchant_id: int,
    search: Optional[str] = None,
    date_from: Optional[date] = None,
    date_to: Optional[date] = None,
    event_category: Optional[List[str]] = None,
    page: int = 1,
    per_page: int = 50,
) -> ActivityLogResponse:
    """Get paginated activity logs grouped by calendar date."""
    from src.apps.reports.models.system_activity_log import SystemActivityLog

    now_utc = datetime.now(timezone.utc)
    if not date_from:
        date_from = (now_utc - timedelta(days=7)).date()
    if not date_to:
        date_to = now_utc.date()

    conditions = [
        SystemActivityLog.merchant_id == merchant_id,
        func.date(SystemActivityLog.created_at) >= date_from,
        func.date(SystemActivityLog.created_at) <= date_to,
    ]

    if search:
        conditions.append(SystemActivityLog.description.ilike(f"%{search}%"))
    if event_category:
        conditions.append(SystemActivityLog.event_category.in_(event_category))

    total_stmt = select(func.count(SystemActivityLog.id)).where(and_(*conditions))
    total = db.execute(total_stmt).scalar() or 0

    stmt = (
        select(SystemActivityLog)
        .where(and_(*conditions))
        .order_by(SystemActivityLog.created_at.desc())
        .offset((page - 1) * per_page)
        .limit(per_page)
    )
    entries = db.execute(stmt).scalars().all()

    # Group by calendar date
    date_groups: dict[str, list] = {}
    for entry in entries:
        entry_date = entry.created_at
        if hasattr(entry_date, 'date'):
            d = entry_date.date()
        else:
            d = entry_date
        # Format: "THURSDAY, 03/19/2026"
        day_label = d.strftime("%A, %m/%d/%Y").upper()
        if day_label not in date_groups:
            date_groups[day_label] = []
        date_groups[day_label].append(
            ActivityLogEntry(
                id=entry.id,
                event_type=entry.event_type,
                event_category=entry.event_category,
                description=entry.description,
                actor_type=entry.actor_type,
                actor_name=entry.actor_name,
                reference_type=entry.reference_type,
                reference_id=entry.reference_id,
                created_at=entry.created_at,
            )
        )

    groups = [ActivityLogDateGroup(date=day, entries=entries_list) for day, entries_list in date_groups.items()]

    return ActivityLogResponse(
        groups=groups,
        total=total,
        page=page,
        per_page=per_page,
    )
