"""
Storage Admin API

存储管理 API 端点，用于管理员管理存储资源。
"""

import logging
import os
from typing import Optional, Dict, Any, List
from datetime import datetime
from fastapi import APIRouter, Depends, Query, Request
from pydantic import BaseModel, Field
from sqlmodel import Session, select, func

from src.auth.dependencies import require_admin
from src.auth.models import UserAuth
from src.models.schemas import ResponseModel
from src.utils.pagination import Paginator
from src.config.database import engine
from src.models.entities import ProjectDB, UserDB
from src.services.storage_service import storage_manager
from src.utils.errors import ErrorCode, AppException

router = APIRouter(prefix="/admin/storage", tags=["admin-storage"])
logger = logging.getLogger(__name__)


# ===== 响应模型 =====

class StorageStatsResponse(BaseModel):
    """存储统计响应"""
    total_capacity: int = Field(..., description="总容量 (bytes)")
    used_space: int = Field(..., description="已用空间 (bytes)")
    file_count: int = Field(..., description="文件数量")
    usage_percent: float = Field(..., description="使用百分比")


class StorageFileItem(BaseModel):
    """存储文件项"""
    id: str
    path: str
    size: int
    user_id: str
    username: Optional[str]
    project_id: Optional[str]
    project_name: Optional[str]
    created_at: float


class StorageUserRankingItem(BaseModel):
    """用户存储排行项"""
    user_id: str
    username: str
    storage_used: int
    file_count: int
    rank: int


class StorageConfigResponse(BaseModel):
    """存储配置响应"""
    storage_type: str
    base_path: Optional[str]
    max_file_size: int
    allowed_extensions: List[str]


# ===== API 端点 =====

@router.get("/stats", response_model=ResponseModel)
async def get_storage_stats(
    current_user: UserAuth = Depends(require_admin),
):
    """
    获取存储统计信息

    需要管理员权限。
    """
    try:
        # 计算存储统计
        with Session(engine) as session:
            # 这里需要根据实际存储实现调整
            # 暂时返回一个基础统计
            total_capacity = 100 * 1024 * 1024 * 1024  # 100GB
            used_space = 0  # 待实现
            file_count = 0  # 待实现

            return ResponseModel(
                data=StorageStatsResponse(
                    total_capacity=total_capacity,
                    used_space=used_space,
                    file_count=file_count,
                    usage_percent=(used_space / total_capacity * 100) if total_capacity > 0 else 0,
                ).model_dump()
            )
    except Exception as e:
        logger.error(f"Error getting storage stats: {e}")
        raise AppException(
                message=str(e),
                code=ErrorCode.INTERNAL_ERROR,
                status_code=500
            )


@router.get("/files", response_model=ResponseModel)
async def list_storage_files(
    request: Request,
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    user_id: Optional[str] = Query(None, description="按用户 ID 过滤"),
    project_id: Optional[str] = Query(None, description="按项目 ID 过滤"),
    search: Optional[str] = Query(None, description="搜索文件路径"),
    current_user: UserAuth = Depends(require_admin),
):
    """
    列出存储文件

    支持按用户、项目过滤。
    需要管理员权限。
    """
    try:
        with Session(engine) as session:
            # 查询项目关联的文件
            query = select(ProjectDB)

            if user_id:
                query = query.where(ProjectDB.user_id == user_id)

            total = session.exec(
                select(func.count()).select_from(query.subquery())
            ).one()

            offset = (page - 1) * page_size
            projects = session.exec(query.offset(offset).limit(page_size)).all()

            items = []
            for project in projects:
                items.append(
                    StorageFileItem(
                        id=project.id,
                        path=f"/projects/{project.id}",
                        size=0,  # 待实现
                        user_id=project.user_id or "",
                        username=None,  # 待关联用户表
                        project_id=project.id,
                        project_name=project.name,
                        created_at=project.created_at,
                    ).model_dump()
                )

            paginator = Paginator(
                items=items,
                total=total,
                page=page,
                page_size=page_size,
            )

            return paginator.to_response(request)
    except Exception as e:
        logger.error(f"Error listing storage files: {e}")
        raise AppException(
                message=str(e),
                code=ErrorCode.INTERNAL_ERROR,
                status_code=500
            )


@router.get("/users/ranking", response_model=ResponseModel)
async def get_storage_user_ranking(
    request: Request,
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    current_user: UserAuth = Depends(require_admin),
):
    """
    获取用户存储使用排行

    需要管理员权限。
    """
    try:
        with Session(engine) as session:
            # 查询用户项目数量作为排行依据
            query = """
                SELECT user_id, COUNT(*) as project_count
                FROM projects
                WHERE deleted_at IS NULL
                GROUP BY user_id
                ORDER BY project_count DESC
            """
            # 简化的实现
            users_query = select(UserDB)
            users = session.exec(users_query.limit(page_size).offset((page - 1) * page_size)).all()

            items = []
            for idx, user in enumerate(users):
                project_count = session.exec(
                    select(func.count()).where(ProjectDB.user_id == user.id)
                ).one()

                items.append(
                    StorageUserRankingItem(
                        user_id=user.id,
                        username=user.username,
                        storage_used=0,  # 待实现
                        file_count=project_count,
                        rank=(page - 1) * page_size + idx + 1,
                    ).model_dump()
                )

            total = session.exec(select(func.count()).select_from(UserDB)).one()

            paginator = Paginator(
                items=items,
                total=total,
                page=page,
                page_size=page_size,
            )

            return paginator.to_response(request)
    except Exception as e:
        logger.error(f"Error getting storage ranking: {e}")
        raise AppException(
                message=str(e),
                code=ErrorCode.INTERNAL_ERROR,
                status_code=500
            )


@router.post("/cleanup", response_model=ResponseModel)
async def cleanup_orphan_files(
    dry_run: bool = Query(True, description="是否仅模拟执行"),
    current_user: UserAuth = Depends(require_admin),
):
    """
    清理孤立文件（没有关联项目的文件）

    需要管理员权限。
    """
    try:
        # 简化的实现
        return ResponseModel(
            data={
                "orphan_count": 0,
                "deleted_count": 0,
                "deleted_size": 0,
                "dry_run": dry_run,
                "message": "清理功能待实现",
            }
        )
    except Exception as e:
        logger.error(f"Error cleaning up orphan files: {e}")
        raise AppException(
                message=str(e),
                code=ErrorCode.INTERNAL_ERROR,
                status_code=500
            )


@router.get("/config", response_model=ResponseModel)
async def get_storage_config(
    current_user: UserAuth = Depends(require_admin),
):
    """
    获取存储配置信息

    需要管理员权限。
    """
    try:
        from src.config.settings import (
            STORAGE_TYPE,
            STORAGE_BASE_PATH,
            STORAGE_MAX_FILE_SIZE,
            STORAGE_ALLOWED_EXTENSIONS,
        )

        return ResponseModel(
            data=StorageConfigResponse(
                storage_type=STORAGE_TYPE or "local",
                base_path=STORAGE_BASE_PATH,
                max_file_size=STORAGE_MAX_FILE_SIZE,
                allowed_extensions=STORAGE_ALLOWED_EXTENSIONS or [],
            ).model_dump()
        )
    except Exception as e:
        logger.error(f"Error getting storage config: {e}")
        raise AppException(
                message=str(e),
                code=ErrorCode.INTERNAL_ERROR,
                status_code=500
            )
