"""
Tool_OCR - Admin Service
Administrative functions and statistics
"""

import logging
from typing import List, Dict
from sqlalchemy.orm import Session
from sqlalchemy import func, and_
from datetime import datetime, timedelta

from app.models.user import User
from app.models.task import Task, TaskStatus
from app.models.session import Session as UserSession
from app.models.audit_log import AuditLog
from app.core.config import settings

logger = logging.getLogger(__name__)


class AdminService:
    """Service for administrative operations"""

    # Admin email addresses
    ADMIN_EMAILS = ["ymirliu@panjit.com.tw"]

    def is_admin(self, email: str) -> bool:
        """
        Check if user is an administrator

        Args:
            email: User email address

        Returns:
            True if user is admin
        """
        return email.lower() in [e.lower() for e in self.ADMIN_EMAILS]

    def get_system_statistics(self, db: Session) -> dict:
        """
        Get overall system statistics

        Args:
            db: Database session

        Returns:
            Dictionary with system stats
        """
        # User statistics
        total_users = db.query(User).count()
        active_users = db.query(User).filter(User.is_active == True).count()

        # Count users with logins in last 30 days
        date_30_days_ago = datetime.utcnow() - timedelta(days=30)
        active_users_30d = db.query(User).filter(
            and_(
                User.last_login >= date_30_days_ago,
                User.is_active == True
            )
        ).count()

        # Task statistics
        total_tasks = db.query(Task).count()
        tasks_by_status = {}
        for status in TaskStatus:
            count = db.query(Task).filter(Task.status == status).count()
            tasks_by_status[status.value] = count

        # Session statistics
        active_sessions = db.query(UserSession).filter(
            UserSession.expires_at > datetime.utcnow()
        ).count()

        # Recent activity (last 7 days)
        date_7_days_ago = datetime.utcnow() - timedelta(days=7)
        recent_tasks = db.query(Task).filter(
            Task.created_at >= date_7_days_ago
        ).count()

        recent_logins = db.query(AuditLog).filter(
            and_(
                AuditLog.event_type == "auth_login",
                AuditLog.created_at >= date_7_days_ago,
                AuditLog.success == 1
            )
        ).count()

        return {
            "total_users": total_users,
            "active_users": active_users,
            "total_tasks": total_tasks,
            "total_sessions": active_sessions,
            "recent_activity_count": recent_tasks,
            "task_stats": {
                "pending": tasks_by_status.get("pending", 0),
                "processing": tasks_by_status.get("processing", 0),
                "completed": tasks_by_status.get("completed", 0),
                "failed": tasks_by_status.get("failed", 0)
            }
        }

    def get_user_list(
        self,
        db: Session,
        skip: int = 0,
        limit: int = 50
    ) -> tuple[List[Dict], int]:
        """
        Get list of all users with statistics

        Args:
            db: Database session
            skip: Pagination offset
            limit: Pagination limit

        Returns:
            Tuple of (user list, total count)
        """
        # Get total count
        total = db.query(User).count()

        # Get users
        users = db.query(User).order_by(User.created_at.desc()).offset(skip).limit(limit).all()

        # Enhance with statistics
        user_list = []
        for user in users:
            # Count user's tasks
            task_count = db.query(Task).filter(Task.user_id == user.id).count()

            # Count completed tasks
            completed_tasks = db.query(Task).filter(
                and_(
                    Task.user_id == user.id,
                    Task.status == TaskStatus.COMPLETED
                )
            ).count()

            # Count failed tasks
            failed_tasks = db.query(Task).filter(
                and_(
                    Task.user_id == user.id,
                    Task.status == TaskStatus.FAILED
                )
            ).count()

            # Count active sessions
            active_sessions = db.query(UserSession).filter(
                and_(
                    UserSession.user_id == user.id,
                    UserSession.expires_at > datetime.utcnow()
                )
            ).count()

            user_list.append({
                **user.to_dict(),
                "task_count": task_count,
                "completed_tasks": completed_tasks,
                "failed_tasks": failed_tasks,
                "active_sessions": active_sessions,
                "is_admin": self.is_admin(user.email)
            })

        return user_list, total

    def get_top_users(
        self,
        db: Session,
        metric: str = "tasks",
        limit: int = 10
    ) -> List[Dict]:
        """
        Get top users by metric

        Args:
            db: Database session
            metric: Metric to rank by (tasks, completed_tasks)
            limit: Number of users to return

        Returns:
            List of top users with counts
        """
        # Get top users by total tasks
        results = db.query(
            User,
            func.count(Task.id).label("task_count")
        ).join(Task).group_by(User.id).order_by(
            func.count(Task.id).desc()
        ).limit(limit).all()

        # Build result list with both task_count and completed_tasks
        top_users = []
        for user, task_count in results:
            # Count completed tasks for this user
            completed_tasks = db.query(Task).filter(
                and_(
                    Task.user_id == user.id,
                    Task.status == TaskStatus.COMPLETED
                )
            ).count()

            top_users.append({
                "user_id": user.id,
                "email": user.email,
                "display_name": user.display_name,
                "task_count": task_count,
                "completed_tasks": completed_tasks
            })

        return top_users


# Singleton instance
admin_service = AdminService()
