# app/modules/hosting/services/stats_service.py
"""
Statistics service for the hosting dashboard.
"""

import logging
from datetime import UTC, datetime, timedelta

from sqlalchemy import func
from sqlalchemy.orm import Session

from app.modules.hosting.models import (
    ClientService,
    ClientServiceStatus,
    HostedSite,
)

logger = logging.getLogger(__name__)


class StatsService:
    """Service for dashboard statistics and reporting."""

    def get_dashboard_stats(self, db: Session) -> dict:
        """Get overview statistics for the hosting dashboard."""
        total = db.query(func.count(HostedSite.id)).scalar() or 0

        # Sites by status
        status_results = (
            db.query(HostedSite.status, func.count(HostedSite.id))
            .group_by(HostedSite.status)
            .all()
        )
        sites_by_status = {
            status.value if hasattr(status, "value") else str(status): count
            for status, count in status_results
        }

        live_count = sites_by_status.get("live", 0)
        poc_count = (
            sites_by_status.get("draft", 0)
            + sites_by_status.get("poc_ready", 0)
            + sites_by_status.get("proposal_sent", 0)
        )

        # Active services
        active_services = (
            db.query(func.count(ClientService.id))
            .filter(ClientService.status == ClientServiceStatus.ACTIVE)
            .scalar()
            or 0
        )

        # Monthly revenue (sum of price_cents for active services with monthly billing)
        monthly_revenue = (
            db.query(func.sum(ClientService.price_cents))
            .filter(
                ClientService.status == ClientServiceStatus.ACTIVE,
            )
            .scalar()
            or 0
        )

        # Upcoming renewals (next 30 days)
        cutoff = datetime.now(UTC) + timedelta(days=30)
        upcoming_renewals = (
            db.query(func.count(ClientService.id))
            .filter(
                ClientService.expires_at.isnot(None),
                ClientService.expires_at <= cutoff,
                ClientService.status == ClientServiceStatus.ACTIVE,
            )
            .scalar()
            or 0
        )

        # Services by type
        type_results = (
            db.query(ClientService.service_type, func.count(ClientService.id))
            .filter(ClientService.status == ClientServiceStatus.ACTIVE)
            .group_by(ClientService.service_type)
            .all()
        )
        services_by_type = {
            stype.value if hasattr(stype, "value") else str(stype): count
            for stype, count in type_results
        }

        return {
            "total_sites": total,
            "live_sites": live_count,
            "poc_sites": poc_count,
            "sites_by_status": sites_by_status,
            "active_services": active_services,
            "monthly_revenue_cents": monthly_revenue,
            "upcoming_renewals": upcoming_renewals,
            "services_by_type": services_by_type,
        }


stats_service = StatsService()
