"""
Admin Portal API Routes
User Management, Permissions, Settings, Audit Logs, Impersonation
"""
from fastapi import APIRouter, HTTPException, Depends, Query, Request, BackgroundTasks
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, or_, func, desc
from typing import Optional, List, Dict, Any
from datetime import datetime, timedelta
from pydantic import BaseModel, Field, EmailStr
from enum import Enum
import secrets
import json
import logging

from app.database import get_db
from app.models.user import User, UserRole, UserSession, AuditLog
from app.models.client import Client
from app.services.email_service import email_service

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


# ============================================================
# SCHEMAS
# ============================================================

class UserCreateRequest(BaseModel):
    """Create user request"""
    email: EmailStr
    password: str = Field(..., min_length=8)
    first_name: str = Field(..., min_length=1, max_length=100)
    last_name: Optional[str] = Field(None, max_length=100)
    phone: Optional[str] = None
    role: UserRole = UserRole.CLIENT_USER
    client_id: Optional[int] = None
    is_active: bool = True
    send_welcome_email: bool = True


class UserUpdateRequest(BaseModel):
    """Update user request"""
    email: Optional[EmailStr] = None
    first_name: Optional[str] = Field(None, max_length=100)
    last_name: Optional[str] = Field(None, max_length=100)
    phone: Optional[str] = None
    role: Optional[UserRole] = None
    is_active: Optional[bool] = None
    timezone: Optional[str] = None
    language: Optional[str] = None
    notification_email: Optional[bool] = None
    notification_sms: Optional[bool] = None


class UserResponse(BaseModel):
    """User response"""
    id: int
    email: str
    first_name: str
    last_name: Optional[str]
    full_name: str
    phone: Optional[str]
    avatar_url: Optional[str]
    role: str
    is_active: bool
    is_verified: bool
    client_id: Optional[int]
    client_name: Optional[str] = None
    last_login_at: Optional[datetime]
    created_at: datetime

    class Config:
        from_attributes = True


class UserListResponse(BaseModel):
    """Paginated user list"""
    users: List[UserResponse]
    total: int
    page: int
    page_size: int
    total_pages: int


class PasswordChangeRequest(BaseModel):
    """Password change by admin"""
    new_password: str = Field(..., min_length=8)
    send_notification: bool = True


class BulkUserAction(BaseModel):
    """Bulk action on users"""
    user_ids: List[int]
    action: str  # activate, deactivate, delete, send_email


class RolePermission(BaseModel):
    """Role permission definition"""
    role: str
    permissions: List[str]
    description: str


class SystemSettingUpdate(BaseModel):
    """System setting update"""
    key: str
    value: Any
    description: Optional[str] = None


class AuditLogResponse(BaseModel):
    """Audit log entry"""
    id: int
    user_id: Optional[int]
    user_email: Optional[str] = None
    client_id: Optional[int]
    action: str
    resource_type: Optional[str]
    resource_id: Optional[int]
    old_values: Optional[Dict] = None
    new_values: Optional[Dict] = None
    ip_address: Optional[str]
    created_at: datetime


class ImpersonateRequest(BaseModel):
    """Impersonation request"""
    client_id: int
    reason: str = Field(..., min_length=10, max_length=500)


class BulkEmailRequest(BaseModel):
    """Bulk email request"""
    recipient_type: str = "all"  # all, active, inactive, role_based
    role_filter: Optional[List[str]] = None
    client_ids: Optional[List[int]] = None
    subject: str = Field(..., min_length=1, max_length=200)
    html_content: str = Field(..., min_length=1)
    text_content: Optional[str] = None


# ============================================================
# PERMISSION DEFINITIONS
# ============================================================

ROLE_PERMISSIONS = {
    UserRole.SUPER_ADMIN: [
        "users.*", "clients.*", "settings.*", "audit.*",
        "billing.*", "impersonate", "bulk_email", "system.*"
    ],
    UserRole.ADMIN: [
        "users.read", "users.create", "users.update",
        "clients.read", "clients.update",
        "audit.read", "billing.read"
    ],
    UserRole.CLIENT_OWNER: [
        "client_users.*", "client_settings.*",
        "conversations.*", "analytics.*", "billing.read"
    ],
    UserRole.CLIENT_ADMIN: [
        "client_users.read", "client_users.create", "client_users.update",
        "conversations.*", "analytics.*"
    ],
    UserRole.CLIENT_USER: [
        "conversations.read", "conversations.create",
        "profile.*"
    ]
}


def has_permission(user_role: UserRole, permission: str) -> bool:
    """Check if role has specific permission"""
    permissions = ROLE_PERMISSIONS.get(user_role, [])

    # Check exact match
    if permission in permissions:
        return True

    # Check wildcard permissions
    permission_parts = permission.split('.')
    if len(permission_parts) >= 1:
        wildcard = f"{permission_parts[0]}.*"
        if wildcard in permissions:
            return True

    return False


def require_permission(permission: str):
    """Dependency to require specific permission"""
    async def check_permission(
        # In real app, get user from JWT token
        # current_user: User = Depends(get_current_user)
    ):
        # Placeholder - implement actual auth check
        pass
    return check_permission


# ============================================================
# AUDIT LOGGING HELPER
# ============================================================

async def log_audit(
    db: AsyncSession,
    action: str,
    user_id: Optional[int] = None,
    client_id: Optional[int] = None,
    resource_type: Optional[str] = None,
    resource_id: Optional[int] = None,
    old_values: Optional[Dict] = None,
    new_values: Optional[Dict] = None,
    ip_address: Optional[str] = None,
    user_agent: Optional[str] = None
):
    """Create audit log entry"""
    audit = AuditLog(
        user_id=user_id,
        client_id=client_id,
        action=action,
        resource_type=resource_type,
        resource_id=resource_id,
        old_values=json.dumps(old_values) if old_values else None,
        new_values=json.dumps(new_values) if new_values else None,
        ip_address=ip_address,
        user_agent=user_agent
    )
    db.add(audit)
    await db.commit()


# ============================================================
# USER MANAGEMENT CRUD
# ============================================================

@router.get("/users", response_model=UserListResponse)
async def list_users(
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    search: Optional[str] = Query(None),
    role: Optional[str] = Query(None),
    client_id: Optional[int] = Query(None),
    is_active: Optional[bool] = Query(None),
    sort_by: str = Query("created_at"),
    sort_order: str = Query("desc"),
    db: AsyncSession = Depends(get_db)
):
    """
    List all users with filtering and pagination

    - **search**: Search by email, name
    - **role**: Filter by role
    - **client_id**: Filter by client
    - **is_active**: Filter by status
    """
    # Build query
    conditions = [User.deleted_at.is_(None)]

    if search:
        search_filter = or_(
            User.email.ilike(f"%{search}%"),
            User.first_name.ilike(f"%{search}%"),
            User.last_name.ilike(f"%{search}%")
        )
        conditions.append(search_filter)

    if role:
        try:
            role_enum = UserRole(role)
            conditions.append(User.role == role_enum)
        except ValueError:
            pass

    if client_id is not None:
        conditions.append(User.client_id == client_id)

    if is_active is not None:
        conditions.append(User.is_active == is_active)

    # Count total
    count_query = select(func.count(User.id)).where(and_(*conditions))
    result = await db.execute(count_query)
    total = result.scalar()

    # Get users with sorting
    query = select(User).where(and_(*conditions))

    if sort_order == "desc":
        query = query.order_by(desc(getattr(User, sort_by, User.created_at)))
    else:
        query = query.order_by(getattr(User, sort_by, User.created_at))

    query = query.offset((page - 1) * page_size).limit(page_size)

    result = await db.execute(query)
    users = result.scalars().all()

    # Get client names
    client_ids = [u.client_id for u in users if u.client_id]
    client_names = {}
    if client_ids:
        client_result = await db.execute(
            select(Client.id, Client.company_name).where(Client.id.in_(client_ids))
        )
        client_names = {row[0]: row[1] for row in client_result.fetchall()}

    return UserListResponse(
        users=[
            UserResponse(
                id=u.id,
                email=u.email,
                first_name=u.first_name,
                last_name=u.last_name,
                full_name=u.full_name,
                phone=u.phone,
                avatar_url=u.avatar_url,
                role=u.role.value,
                is_active=u.is_active,
                is_verified=u.is_verified,
                client_id=u.client_id,
                client_name=client_names.get(u.client_id),
                last_login_at=u.last_login_at,
                created_at=u.created_at
            )
            for u in users
        ],
        total=total,
        page=page,
        page_size=page_size,
        total_pages=(total + page_size - 1) // page_size
    )


@router.post("/users", response_model=UserResponse, status_code=201)
async def create_user(
    request: UserCreateRequest,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_db)
):
    """Create a new user"""
    # Check if email exists
    existing = await db.execute(
        select(User).where(User.email == request.email)
    )
    if existing.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="Email already registered")

    # Validate client_id for non-platform users
    if request.role not in [UserRole.SUPER_ADMIN, UserRole.ADMIN]:
        if not request.client_id:
            raise HTTPException(
                status_code=400,
                detail="client_id required for non-platform users"
            )

    # Hash password (use proper hashing in production)
    import hashlib
    password_hash = hashlib.sha256(request.password.encode()).hexdigest()

    # Create user
    user = User(
        email=request.email,
        password_hash=password_hash,
        first_name=request.first_name,
        last_name=request.last_name,
        phone=request.phone,
        role=request.role,
        client_id=request.client_id,
        is_active=request.is_active,
        email_verification_token=secrets.token_urlsafe(32)
    )

    db.add(user)
    await db.commit()
    await db.refresh(user)

    # Log audit
    await log_audit(
        db=db,
        action="user.create",
        resource_type="user",
        resource_id=user.id,
        new_values={"email": user.email, "role": user.role.value}
    )

    # Send welcome email
    if request.send_welcome_email:
        background_tasks.add_task(
            email_service.send_welcome_email,
            to_email=user.email,
            user_name=user.first_name
        )

    return UserResponse(
        id=user.id,
        email=user.email,
        first_name=user.first_name,
        last_name=user.last_name,
        full_name=user.full_name,
        phone=user.phone,
        avatar_url=user.avatar_url,
        role=user.role.value,
        is_active=user.is_active,
        is_verified=user.is_verified,
        client_id=user.client_id,
        last_login_at=user.last_login_at,
        created_at=user.created_at
    )


@router.get("/users/{user_id}", response_model=UserResponse)
async def get_user(
    user_id: int,
    db: AsyncSession = Depends(get_db)
):
    """Get user by ID"""
    result = await db.execute(
        select(User).where(and_(User.id == user_id, User.deleted_at.is_(None)))
    )
    user = result.scalar_one_or_none()

    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    # Get client name
    client_name = None
    if user.client_id:
        client_result = await db.execute(
            select(Client.company_name).where(Client.id == user.client_id)
        )
        client_name = client_result.scalar_one_or_none()

    return UserResponse(
        id=user.id,
        email=user.email,
        first_name=user.first_name,
        last_name=user.last_name,
        full_name=user.full_name,
        phone=user.phone,
        avatar_url=user.avatar_url,
        role=user.role.value,
        is_active=user.is_active,
        is_verified=user.is_verified,
        client_id=user.client_id,
        client_name=client_name,
        last_login_at=user.last_login_at,
        created_at=user.created_at
    )


@router.put("/users/{user_id}", response_model=UserResponse)
async def update_user(
    user_id: int,
    request: UserUpdateRequest,
    db: AsyncSession = Depends(get_db)
):
    """Update user"""
    result = await db.execute(
        select(User).where(and_(User.id == user_id, User.deleted_at.is_(None)))
    )
    user = result.scalar_one_or_none()

    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    # Store old values for audit
    old_values = {
        "email": user.email,
        "role": user.role.value,
        "is_active": user.is_active
    }

    # Update fields
    update_data = request.model_dump(exclude_unset=True)

    # Check email uniqueness if changing
    if "email" in update_data and update_data["email"] != user.email:
        existing = await db.execute(
            select(User).where(User.email == update_data["email"])
        )
        if existing.scalar_one_or_none():
            raise HTTPException(status_code=400, detail="Email already registered")

    for field, value in update_data.items():
        setattr(user, field, value)

    user.updated_at = datetime.utcnow()
    await db.commit()
    await db.refresh(user)

    # Log audit
    await log_audit(
        db=db,
        action="user.update",
        resource_type="user",
        resource_id=user.id,
        old_values=old_values,
        new_values=update_data
    )

    return UserResponse(
        id=user.id,
        email=user.email,
        first_name=user.first_name,
        last_name=user.last_name,
        full_name=user.full_name,
        phone=user.phone,
        avatar_url=user.avatar_url,
        role=user.role.value,
        is_active=user.is_active,
        is_verified=user.is_verified,
        client_id=user.client_id,
        last_login_at=user.last_login_at,
        created_at=user.created_at
    )


@router.delete("/users/{user_id}")
async def delete_user(
    user_id: int,
    permanent: bool = Query(False),
    db: AsyncSession = Depends(get_db)
):
    """Delete user (soft delete by default)"""
    result = await db.execute(
        select(User).where(User.id == user_id)
    )
    user = result.scalar_one_or_none()

    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    if permanent:
        await db.delete(user)
    else:
        user.deleted_at = datetime.utcnow()
        user.is_active = False

    await db.commit()

    # Log audit
    await log_audit(
        db=db,
        action="user.delete",
        resource_type="user",
        resource_id=user_id,
        old_values={"email": user.email, "permanent": permanent}
    )

    return {"success": True, "message": "User deleted"}


@router.post("/users/{user_id}/change-password")
async def change_user_password(
    user_id: int,
    request: PasswordChangeRequest,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_db)
):
    """Admin change user password"""
    result = await db.execute(
        select(User).where(and_(User.id == user_id, User.deleted_at.is_(None)))
    )
    user = result.scalar_one_or_none()

    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    # Hash new password
    import hashlib
    user.password_hash = hashlib.sha256(request.new_password.encode()).hexdigest()
    user.updated_at = datetime.utcnow()

    await db.commit()

    # Log audit
    await log_audit(
        db=db,
        action="user.password_change",
        resource_type="user",
        resource_id=user_id
    )

    # Send notification
    if request.send_notification:
        background_tasks.add_task(
            email_service.send_password_changed_email,
            to_email=user.email,
            user_name=user.first_name
        )

    return {"success": True, "message": "Password changed"}


@router.post("/users/bulk-action")
async def bulk_user_action(
    request: BulkUserAction,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_db)
):
    """Perform bulk action on users"""
    if len(request.user_ids) > 100:
        raise HTTPException(status_code=400, detail="Maximum 100 users per action")

    # Get users
    result = await db.execute(
        select(User).where(User.id.in_(request.user_ids))
    )
    users = result.scalars().all()

    if not users:
        raise HTTPException(status_code=404, detail="No users found")

    results = {"success": 0, "failed": 0, "errors": []}

    for user in users:
        try:
            if request.action == "activate":
                user.is_active = True
            elif request.action == "deactivate":
                user.is_active = False
            elif request.action == "delete":
                user.deleted_at = datetime.utcnow()
                user.is_active = False
            elif request.action == "send_email":
                # Would send email in background
                pass
            else:
                raise ValueError(f"Unknown action: {request.action}")

            results["success"] += 1

        except Exception as e:
            results["failed"] += 1
            results["errors"].append({"user_id": user.id, "error": str(e)})

    await db.commit()

    # Log audit
    await log_audit(
        db=db,
        action=f"user.bulk_{request.action}",
        new_values={"user_ids": request.user_ids, "results": results}
    )

    return results


# ============================================================
# ROLE-BASED PERMISSIONS
# ============================================================

@router.get("/permissions/roles")
async def list_roles():
    """List all roles with their permissions"""
    return {
        "roles": [
            RolePermission(
                role=role.value,
                permissions=perms,
                description=_get_role_description(role)
            )
            for role, perms in ROLE_PERMISSIONS.items()
        ]
    }


def _get_role_description(role: UserRole) -> str:
    descriptions = {
        UserRole.SUPER_ADMIN: "Full platform access with all permissions",
        UserRole.ADMIN: "Platform staff with limited admin access",
        UserRole.CLIENT_OWNER: "Client account owner with full client access",
        UserRole.CLIENT_ADMIN: "Client administrator with team management",
        UserRole.CLIENT_USER: "Regular client team member"
    }
    return descriptions.get(role, "")


@router.get("/permissions/check")
async def check_permission(
    role: str,
    permission: str
):
    """Check if a role has a specific permission"""
    try:
        role_enum = UserRole(role)
        has_perm = has_permission(role_enum, permission)
        return {
            "role": role,
            "permission": permission,
            "has_permission": has_perm
        }
    except ValueError:
        raise HTTPException(status_code=400, detail="Invalid role")


@router.put("/users/{user_id}/role")
async def update_user_role(
    user_id: int,
    role: str,
    db: AsyncSession = Depends(get_db)
):
    """Update user role"""
    result = await db.execute(
        select(User).where(and_(User.id == user_id, User.deleted_at.is_(None)))
    )
    user = result.scalar_one_or_none()

    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    try:
        new_role = UserRole(role)
    except ValueError:
        raise HTTPException(status_code=400, detail="Invalid role")

    old_role = user.role.value
    user.role = new_role
    user.updated_at = datetime.utcnow()

    await db.commit()

    # Log audit
    await log_audit(
        db=db,
        action="user.role_change",
        resource_type="user",
        resource_id=user_id,
        old_values={"role": old_role},
        new_values={"role": new_role.value}
    )

    return {
        "success": True,
        "user_id": user_id,
        "old_role": old_role,
        "new_role": new_role.value
    }


# ============================================================
# SYSTEM SETTINGS
# ============================================================

# In-memory settings (use database in production)
SYSTEM_SETTINGS = {
    "site_name": {"value": "AI360 Solutions", "description": "Platform name"},
    "support_email": {"value": "support@ai360.com", "description": "Support email"},
    "max_file_size_mb": {"value": 10, "description": "Max file upload size in MB"},
    "session_timeout_minutes": {"value": 60, "description": "Session timeout"},
    "allow_registration": {"value": True, "description": "Allow new registrations"},
    "require_email_verification": {"value": True, "description": "Require email verification"},
    "enable_2fa": {"value": True, "description": "Enable 2FA option"},
    "maintenance_mode": {"value": False, "description": "Maintenance mode"},
    "maintenance_message": {"value": "", "description": "Maintenance message"},
    "default_timezone": {"value": "Asia/Kolkata", "description": "Default timezone"},
    "default_language": {"value": "en", "description": "Default language"},
    "trial_days": {"value": 14, "description": "Trial period in days"},
    "smtp_enabled": {"value": True, "description": "SMTP enabled"},
    "rate_limit_enabled": {"value": True, "description": "Rate limiting enabled"}
}


@router.get("/settings")
async def get_system_settings():
    """Get all system settings"""
    return {
        "settings": [
            {
                "key": key,
                "value": data["value"],
                "description": data["description"]
            }
            for key, data in SYSTEM_SETTINGS.items()
        ]
    }


@router.get("/settings/{key}")
async def get_setting(key: str):
    """Get specific setting"""
    if key not in SYSTEM_SETTINGS:
        raise HTTPException(status_code=404, detail="Setting not found")

    return {
        "key": key,
        "value": SYSTEM_SETTINGS[key]["value"],
        "description": SYSTEM_SETTINGS[key]["description"]
    }


@router.put("/settings/{key}")
async def update_setting(
    key: str,
    request: SystemSettingUpdate,
    db: AsyncSession = Depends(get_db)
):
    """Update system setting"""
    if key not in SYSTEM_SETTINGS:
        raise HTTPException(status_code=404, detail="Setting not found")

    old_value = SYSTEM_SETTINGS[key]["value"]
    SYSTEM_SETTINGS[key]["value"] = request.value

    if request.description:
        SYSTEM_SETTINGS[key]["description"] = request.description

    # Log audit
    await log_audit(
        db=db,
        action="settings.update",
        resource_type="setting",
        old_values={key: old_value},
        new_values={key: request.value}
    )

    return {
        "success": True,
        "key": key,
        "old_value": old_value,
        "new_value": request.value
    }


@router.put("/settings")
async def update_settings_bulk(
    settings: List[SystemSettingUpdate],
    db: AsyncSession = Depends(get_db)
):
    """Update multiple settings at once"""
    updated = []
    errors = []

    for setting in settings:
        if setting.key not in SYSTEM_SETTINGS:
            errors.append({"key": setting.key, "error": "Setting not found"})
            continue

        old_value = SYSTEM_SETTINGS[setting.key]["value"]
        SYSTEM_SETTINGS[setting.key]["value"] = setting.value
        updated.append({
            "key": setting.key,
            "old_value": old_value,
            "new_value": setting.value
        })

    # Log audit
    await log_audit(
        db=db,
        action="settings.bulk_update",
        new_values={"updated": updated}
    )

    return {
        "updated": updated,
        "errors": errors
    }


# ============================================================
# AUDIT LOGS
# ============================================================

@router.get("/audit-logs")
async def list_audit_logs(
    page: int = Query(1, ge=1),
    page_size: int = Query(50, ge=1, le=100),
    user_id: Optional[int] = Query(None),
    client_id: Optional[int] = Query(None),
    action: Optional[str] = Query(None),
    resource_type: Optional[str] = Query(None),
    start_date: Optional[datetime] = Query(None),
    end_date: Optional[datetime] = Query(None),
    db: AsyncSession = Depends(get_db)
):
    """
    List audit logs with filtering

    - **user_id**: Filter by user
    - **client_id**: Filter by client
    - **action**: Filter by action (e.g., user.login, client.update)
    - **resource_type**: Filter by resource type
    - **start_date**: Filter from date
    - **end_date**: Filter to date
    """
    conditions = []

    if user_id:
        conditions.append(AuditLog.user_id == user_id)
    if client_id:
        conditions.append(AuditLog.client_id == client_id)
    if action:
        conditions.append(AuditLog.action.ilike(f"%{action}%"))
    if resource_type:
        conditions.append(AuditLog.resource_type == resource_type)
    if start_date:
        conditions.append(AuditLog.created_at >= start_date)
    if end_date:
        conditions.append(AuditLog.created_at <= end_date)

    # Count total
    count_query = select(func.count(AuditLog.id))
    if conditions:
        count_query = count_query.where(and_(*conditions))
    result = await db.execute(count_query)
    total = result.scalar()

    # Get logs
    query = select(AuditLog)
    if conditions:
        query = query.where(and_(*conditions))
    query = query.order_by(desc(AuditLog.created_at))
    query = query.offset((page - 1) * page_size).limit(page_size)

    result = await db.execute(query)
    logs = result.scalars().all()

    # Get user emails
    user_ids = [log.user_id for log in logs if log.user_id]
    user_emails = {}
    if user_ids:
        user_result = await db.execute(
            select(User.id, User.email).where(User.id.in_(user_ids))
        )
        user_emails = {row[0]: row[1] for row in user_result.fetchall()}

    return {
        "logs": [
            AuditLogResponse(
                id=log.id,
                user_id=log.user_id,
                user_email=user_emails.get(log.user_id),
                client_id=log.client_id,
                action=log.action,
                resource_type=log.resource_type,
                resource_id=log.resource_id,
                old_values=json.loads(log.old_values) if log.old_values else None,
                new_values=json.loads(log.new_values) if log.new_values else None,
                ip_address=log.ip_address,
                created_at=log.created_at
            )
            for log in logs
        ],
        "total": total,
        "page": page,
        "page_size": page_size,
        "total_pages": (total + page_size - 1) // page_size
    }


@router.get("/audit-logs/{log_id}")
async def get_audit_log(
    log_id: int,
    db: AsyncSession = Depends(get_db)
):
    """Get specific audit log entry"""
    result = await db.execute(
        select(AuditLog).where(AuditLog.id == log_id)
    )
    log = result.scalar_one_or_none()

    if not log:
        raise HTTPException(status_code=404, detail="Audit log not found")

    # Get user email
    user_email = None
    if log.user_id:
        user_result = await db.execute(
            select(User.email).where(User.id == log.user_id)
        )
        user_email = user_result.scalar_one_or_none()

    return AuditLogResponse(
        id=log.id,
        user_id=log.user_id,
        user_email=user_email,
        client_id=log.client_id,
        action=log.action,
        resource_type=log.resource_type,
        resource_id=log.resource_id,
        old_values=json.loads(log.old_values) if log.old_values else None,
        new_values=json.loads(log.new_values) if log.new_values else None,
        ip_address=log.ip_address,
        created_at=log.created_at
    )


@router.get("/audit-logs/actions")
async def get_audit_actions(db: AsyncSession = Depends(get_db)):
    """Get list of unique audit actions"""
    result = await db.execute(
        select(AuditLog.action).distinct()
    )
    actions = [row[0] for row in result.fetchall()]
    return {"actions": sorted(actions)}


@router.get("/audit-logs/stats")
async def get_audit_stats(
    days: int = Query(30, ge=1, le=365),
    db: AsyncSession = Depends(get_db)
):
    """Get audit log statistics"""
    start_date = datetime.utcnow() - timedelta(days=days)

    # Total logs in period
    total_result = await db.execute(
        select(func.count(AuditLog.id)).where(
            AuditLog.created_at >= start_date
        )
    )
    total = total_result.scalar()

    # Logs by action
    action_result = await db.execute(
        select(AuditLog.action, func.count(AuditLog.id))
        .where(AuditLog.created_at >= start_date)
        .group_by(AuditLog.action)
        .order_by(desc(func.count(AuditLog.id)))
        .limit(10)
    )
    by_action = [{"action": row[0], "count": row[1]} for row in action_result.fetchall()]

    # Logs by user
    user_result = await db.execute(
        select(AuditLog.user_id, func.count(AuditLog.id))
        .where(and_(
            AuditLog.created_at >= start_date,
            AuditLog.user_id.isnot(None)
        ))
        .group_by(AuditLog.user_id)
        .order_by(desc(func.count(AuditLog.id)))
        .limit(10)
    )
    by_user = [{"user_id": row[0], "count": row[1]} for row in user_result.fetchall()]

    return {
        "period_days": days,
        "total_logs": total,
        "by_action": by_action,
        "by_user": by_user
    }


# ============================================================
# CLIENT IMPERSONATION
# ============================================================

# Active impersonation sessions (use Redis in production)
IMPERSONATION_SESSIONS: Dict[str, Dict] = {}


@router.post("/impersonate")
async def start_impersonation(
    request: ImpersonateRequest,
    http_request: Request,
    db: AsyncSession = Depends(get_db)
):
    """
    Start impersonating a client

    **Requires SUPER_ADMIN role**

    This allows admins to view the platform as a specific client
    for debugging and support purposes.
    """
    # Verify client exists
    result = await db.execute(
        select(Client).where(Client.id == request.client_id)
    )
    client = result.scalar_one_or_none()

    if not client:
        raise HTTPException(status_code=404, detail="Client not found")

    # Generate impersonation token
    impersonation_token = secrets.token_urlsafe(32)

    # Store session (use Redis in production)
    IMPERSONATION_SESSIONS[impersonation_token] = {
        "client_id": request.client_id,
        "client_name": client.company_name,
        "reason": request.reason,
        "started_at": datetime.utcnow().isoformat(),
        "expires_at": (datetime.utcnow() + timedelta(hours=1)).isoformat(),
        "admin_ip": http_request.client.host if http_request.client else None
    }

    # Log audit
    await log_audit(
        db=db,
        action="admin.impersonate_start",
        client_id=request.client_id,
        new_values={
            "client_id": request.client_id,
            "reason": request.reason
        },
        ip_address=http_request.client.host if http_request.client else None
    )

    return {
        "success": True,
        "impersonation_token": impersonation_token,
        "client_id": request.client_id,
        "client_name": client.company_name,
        "expires_in_seconds": 3600,
        "message": f"Now impersonating {client.company_name}"
    }


@router.post("/impersonate/end")
async def end_impersonation(
    token: str,
    db: AsyncSession = Depends(get_db)
):
    """End impersonation session"""
    if token not in IMPERSONATION_SESSIONS:
        raise HTTPException(status_code=404, detail="Impersonation session not found")

    session = IMPERSONATION_SESSIONS.pop(token)

    # Log audit
    await log_audit(
        db=db,
        action="admin.impersonate_end",
        client_id=session["client_id"],
        old_values=session
    )

    return {
        "success": True,
        "message": "Impersonation ended"
    }


@router.get("/impersonate/active")
async def get_active_impersonations():
    """Get all active impersonation sessions"""
    now = datetime.utcnow()
    active = []

    for token, session in list(IMPERSONATION_SESSIONS.items()):
        expires_at = datetime.fromisoformat(session["expires_at"])
        if expires_at > now:
            active.append({
                "token_prefix": token[:8] + "...",
                "client_id": session["client_id"],
                "client_name": session["client_name"],
                "reason": session["reason"],
                "started_at": session["started_at"],
                "expires_at": session["expires_at"]
            })
        else:
            # Clean up expired session
            del IMPERSONATION_SESSIONS[token]

    return {"active_sessions": active}


# ============================================================
# BULK EMAIL TO CLIENTS
# ============================================================

@router.post("/bulk-email")
async def send_bulk_email(
    request: BulkEmailRequest,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_db)
):
    """
    Send bulk email to clients

    **Requires SUPER_ADMIN role**

    - **recipient_type**: all, active, inactive, role_based
    - **role_filter**: List of roles to include (if role_based)
    - **client_ids**: Specific client IDs (optional)
    """
    # Build recipient query
    conditions = [User.deleted_at.is_(None)]

    if request.recipient_type == "active":
        conditions.append(User.is_active == True)
    elif request.recipient_type == "inactive":
        conditions.append(User.is_active == False)

    if request.role_filter:
        role_conditions = []
        for role_str in request.role_filter:
            try:
                role_enum = UserRole(role_str)
                role_conditions.append(User.role == role_enum)
            except ValueError:
                pass
        if role_conditions:
            conditions.append(or_(*role_conditions))

    if request.client_ids:
        conditions.append(User.client_id.in_(request.client_ids))

    # Get recipients
    result = await db.execute(
        select(User.id, User.email, User.first_name)
        .where(and_(*conditions))
        .limit(1000)  # Safety limit
    )
    recipients = result.fetchall()

    if not recipients:
        raise HTTPException(status_code=404, detail="No recipients found")

    # Queue emails in background
    async def send_emails():
        sent = 0
        failed = 0

        for user_id, email, first_name in recipients:
            try:
                # Personalize content
                personalized_html = request.html_content.replace(
                    "{user_name}", first_name or "User"
                ).replace(
                    "{email}", email
                )

                await email_service.send_email(
                    to_email=email,
                    subject=request.subject,
                    html_content=personalized_html,
                    text_content=request.text_content,
                    categories=["bulk-email", "admin"]
                )
                sent += 1
            except Exception as e:
                logger.error(f"Bulk email failed for {email}: {e}")
                failed += 1

        # Log completion
        logger.info(f"Bulk email completed: {sent} sent, {failed} failed")

    background_tasks.add_task(send_emails)

    # Log audit
    await log_audit(
        db=db,
        action="admin.bulk_email",
        new_values={
            "recipient_count": len(recipients),
            "subject": request.subject,
            "recipient_type": request.recipient_type
        }
    )

    return {
        "success": True,
        "message": "Bulk email queued",
        "recipient_count": len(recipients),
        "status": "processing"
    }


@router.get("/bulk-email/preview")
async def preview_bulk_email(
    recipient_type: str = Query("all"),
    role_filter: Optional[str] = Query(None),
    client_ids: Optional[str] = Query(None),
    db: AsyncSession = Depends(get_db)
):
    """Preview bulk email recipients without sending"""
    conditions = [User.deleted_at.is_(None)]

    if recipient_type == "active":
        conditions.append(User.is_active == True)
    elif recipient_type == "inactive":
        conditions.append(User.is_active == False)

    if role_filter:
        role_list = role_filter.split(",")
        role_conditions = []
        for role_str in role_list:
            try:
                role_enum = UserRole(role_str.strip())
                role_conditions.append(User.role == role_enum)
            except ValueError:
                pass
        if role_conditions:
            conditions.append(or_(*role_conditions))

    if client_ids:
        ids = [int(x.strip()) for x in client_ids.split(",")]
        conditions.append(User.client_id.in_(ids))

    # Get count
    result = await db.execute(
        select(func.count(User.id)).where(and_(*conditions))
    )
    total = result.scalar()

    # Get sample
    sample_result = await db.execute(
        select(User.email, User.first_name, User.role)
        .where(and_(*conditions))
        .limit(10)
    )
    samples = [
        {"email": row[0], "name": row[1], "role": row[2].value}
        for row in sample_result.fetchall()
    ]

    return {
        "total_recipients": total,
        "sample_recipients": samples
    }


# ============================================================
# DASHBOARD STATS
# ============================================================

@router.get("/dashboard/stats")
async def get_admin_dashboard_stats(
    db: AsyncSession = Depends(get_db)
):
    """Get admin dashboard statistics"""
    # Total users
    total_users = await db.execute(
        select(func.count(User.id)).where(User.deleted_at.is_(None))
    )

    # Active users
    active_users = await db.execute(
        select(func.count(User.id)).where(
            and_(User.deleted_at.is_(None), User.is_active == True)
        )
    )

    # Total clients
    total_clients = await db.execute(
        select(func.count(Client.id)).where(Client.deleted_at.is_(None))
    )

    # New users (last 30 days)
    thirty_days_ago = datetime.utcnow() - timedelta(days=30)
    new_users = await db.execute(
        select(func.count(User.id)).where(
            and_(
                User.deleted_at.is_(None),
                User.created_at >= thirty_days_ago
            )
        )
    )

    # Users by role
    role_counts = await db.execute(
        select(User.role, func.count(User.id))
        .where(User.deleted_at.is_(None))
        .group_by(User.role)
    )

    return {
        "total_users": total_users.scalar(),
        "active_users": active_users.scalar(),
        "total_clients": total_clients.scalar(),
        "new_users_30d": new_users.scalar(),
        "users_by_role": [
            {"role": row[0].value, "count": row[1]}
            for row in role_counts.fetchall()
        ]
    }
