from datetime import datetime

from sqlalchemy import func, select
from sqlalchemy.orm import Session

from app.core.models import EmailLog, EmailLogStatus, Tenant


class MessagingBlocked(Exception):
    pass


def _month_start(now: datetime) -> datetime:
    return now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)


def _sent_count(db: Session, tenant_id: int, started_at: datetime) -> int:
    return db.scalar(
        select(func.count(EmailLog.id)).where(
            EmailLog.tenant_id == tenant_id,
            EmailLog.status == EmailLogStatus.sent,
            EmailLog.sent_at >= started_at,
        )
    ) or 0


def ensure_email_allowed(db: Session | None, tenant_id: int | None) -> None:
    if db is None or tenant_id is None:
        return
    tenant = db.get(Tenant, tenant_id)
    if tenant is None or not tenant.email_enabled:
        raise MessagingBlocked("email is disabled for this tenant")
    now = datetime.now()
    if tenant.daily_email_limit and _sent_count(db, tenant_id, now.replace(hour=0, minute=0, second=0, microsecond=0)) >= tenant.daily_email_limit:
        raise MessagingBlocked("daily email limit reached")
    if tenant.monthly_email_limit and _sent_count(db, tenant_id, _month_start(now)) >= tenant.monthly_email_limit:
        raise MessagingBlocked("monthly email limit reached")


def ensure_telegram_allowed(db: Session | None, tenant_id: int | None) -> None:
    if db is None or tenant_id is None:
        return
    tenant = db.get(Tenant, tenant_id)
    if tenant is None or not tenant.telegram_enabled:
        raise MessagingBlocked("Telegram is disabled for this tenant")
