"""User-facing view for the unified Sources & Destinations dashboard."""

import logging

from fastapi import HTTPException, Request, status
from sqlalchemy.orm import Session

from app.models import IntegrationDirection, IntegrationType, UserIntegration
from app.utils.subscription import get_tier, get_user_tier_id
from app.utils.user_scope import get_current_owner_id
from app.views.base import APIRouter, Depends, get_db, require_login, templates

logger = logging.getLogger(__name__)
router = APIRouter()

# Source types that consume the mailbox quota (mirrored from app.api.integrations)
_MAILBOX_SOURCE_TYPES = {IntegrationType.IMAP}
_FREE_TIER_ID = "free"


def _get_max_destinations(tier: dict) -> int | None:
    """Return the maximum number of storage destinations allowed by *tier*.

    Returns ``None`` for unlimited, or a positive int for the cap.
    """
    tier_id: str = tier.get("id", _FREE_TIER_ID)
    max_dest: int = tier.get("max_storage_destinations", 0)
    if tier_id == _FREE_TIER_ID:
        return max_dest if max_dest > 0 else 1
    if max_dest == 0:
        return None
    return max_dest


def _get_max_sources(tier: dict) -> int | None:
    """Return the maximum number of IMAP sources allowed by *tier*.

    Returns ``None`` for unlimited, ``0`` for no access, or a positive int.
    """
    tier_id: str = tier.get("id", _FREE_TIER_ID)
    max_mb: int = tier.get("max_mailboxes", 0)
    if tier_id == _FREE_TIER_ID:
        return 0
    if max_mb == 0:
        return None
    return max_mb


@router.get("/integrations")
@require_login
async def integrations_dashboard(request: Request, db: Session = Depends(get_db)):
    """Render the unified Sources & Destinations dashboard."""
    try:
        owner_id = get_current_owner_id(request)

        dest_count = 0
        src_count = 0
        max_destinations: int | None = 1
        max_sources: int | None = 0
        can_add_destination = False
        can_add_source = False
        tier_name = "Free"
        tier_id = "free"

        if owner_id:
            from sqlalchemy import func

            dest_count = (
                db.query(func.count())
                .select_from(UserIntegration)
                .filter(
                    UserIntegration.owner_id == owner_id,
                    UserIntegration.direction == IntegrationDirection.DESTINATION,
                )
                .scalar()
            ) or 0
            src_count = (
                db.query(func.count())
                .select_from(UserIntegration)
                .filter(
                    UserIntegration.owner_id == owner_id,
                    UserIntegration.direction == IntegrationDirection.SOURCE,
                    UserIntegration.integration_type.in_(list(_MAILBOX_SOURCE_TYPES)),
                )
                .scalar()
            ) or 0
            tier_id = get_user_tier_id(db, owner_id)
            tier = get_tier(tier_id, db)
            tier_name = tier.get("name", tier_id)
            max_destinations = _get_max_destinations(tier)
            max_sources = _get_max_sources(tier)
            can_add_destination = max_destinations is None or dest_count < max_destinations
            can_add_source = max_sources is None or (max_sources > 0 and src_count < max_sources)

        return templates.TemplateResponse(
            "integrations_dashboard.html",
            {
                "request": request,
                "dest_count": dest_count,
                "src_count": src_count,
                "max_destinations": max_destinations,
                "max_sources": max_sources,
                "can_add_destination": can_add_destination,
                "can_add_source": can_add_source,
                "tier_id": tier_id,
                "tier_name": tier_name,
            },
        )
    except HTTPException:
        raise
    except Exception as exc:
        logger.error(f"Error loading integrations dashboard: {exc}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to load integrations dashboard",
        )
