from typing import Dict, Any, List from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func, and_ from app.models.user import User from app.models.team import Team, TeamMember from app.models.analytics import UsageLog from app.models.customer import Customer from app.models.quotation import Quotation from datetime import datetime, timedelta import logging logger = logging.getLogger(__name__) class AdminService: def __init__(self, db: AsyncSession): self.db = db async def get_dashboard(self) -> Dict[str, Any]: now = datetime.utcnow() today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) user_count = await self.db.execute(select(func.count(User.id))) team_count = await self.db.execute(select(func.count(Team.id))) customer_count = await self.db.execute(select(func.count(Customer.id))) quotation_count = await self.db.execute(select(func.count(Quotation.id))) today_logs = await self.db.execute( select(func.count(UsageLog.id)).where(UsageLog.created_at >= today_start) ) total_logs = await self.db.execute(select(func.count(UsageLog.id))) recent_users_result = await self.db.execute( select(User).order_by(User.created_at.desc()).limit(5) ) recent_users = recent_users_result.scalars().all() return { "users": { "total": user_count.scalar() or 0, }, "teams": { "total": team_count.scalar() or 0, }, "customers": { "total": customer_count.scalar() or 0, }, "quotations": { "total": quotation_count.scalar() or 0, }, "usage": { "today": today_logs.scalar() or 0, "total": total_logs.scalar() or 0, }, "recent_users": [ { "id": str(u.id), "username": u.username, "tier": u.tier, "is_active": u.is_active, "created_at": u.created_at.isoformat() if u.created_at else None, } for u in recent_users ], } async def list_users(self, page: int = 1, size: int = 20) -> Dict[str, Any]: query = select(User).order_by(User.created_at.desc()).offset((page - 1) * size).limit(size) count_query = select(func.count(User.id)) total = await self.db.execute(count_query) result = await self.db.execute(query) users = result.scalars().all() return { "items": [ { "id": str(u.id), "username": u.username, "phone": u.phone, "tier": u.tier, "is_active": u.is_active, "created_at": u.created_at.isoformat() if u.created_at else None, } for u in users ], "total": total.scalar(), "page": page, "size": size, } async def update_user_tier(self, user_id: str, tier: str) -> bool: result = await self.db.execute(select(User).where(User.id == user_id)) user = result.scalar_one_or_none() if not user: return False user.tier = tier await self.db.flush() return True async def toggle_user_active(self, user_id: str) -> bool: result = await self.db.execute(select(User).where(User.id == user_id)) user = result.scalar_one_or_none() if not user: return False user.is_active = not user.is_active await self.db.flush() return True async def get_system_health(self) -> Dict[str, Any]: return { "status": "healthy", "version": "1.0.0", "timestamp": datetime.utcnow().isoformat(), } async def log_usage(self, user_id: str, action: str, detail: Dict = None, ip: str = None, ua: str = None): try: log = UsageLog( user_id=user_id, action=action, detail=detail or {}, ip_address=ip, user_agent=ua, ) self.db.add(log) await self.db.flush() except Exception as e: logger.warning(f"Failed to log usage: {e}")