from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from app.database import get_db
from app.schemas.admin import (
    UserCreate, UserUpdate, UserInfo, UserListResponse,
    VMAccessCreate, VMAccessUpdate, VMAccessInfo, VMAccessListResponse,
    AdminResponse
)
from app.schemas.auth import CurrentUser
from app.api.auth import get_current_user
from app.models.user import User, UserRole
from app.models.vm import VMAccess
from app.utils.security import hash_password
from app.utils.exceptions import PermissionDeniedError, NotFoundError, BadRequestError

router = APIRouter()

def require_admin(current_user: CurrentUser = Depends(get_current_user)):
    """관리자 권한 확인"""
    if current_user.role != "admin":
        raise PermissionDeniedError("관리자 권한이 필요합니다")
    return current_user

# ==================== 사용자 관리 ====================

@router.get("/users", response_model=UserListResponse)
async def get_users(
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """사용자 목록 조회"""
    users = db.query(User).all()
    
    user_list = [
        UserInfo(
            id=user.id,
            username=user.username,
            email=user.email,
            full_name=user.full_name,
            role=user.role.value,
            is_active=user.is_active,
            created_at=user.created_at,
            last_login=user.last_login
        )
        for user in users
    ]
    
    return UserListResponse(total=len(user_list), users=user_list)

@router.post("/users", response_model=AdminResponse)
async def create_user(
    user_data: UserCreate,
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """사용자 생성"""
    # 중복 확인
    if db.query(User).filter(User.username == user_data.username).first():
        raise BadRequestError("이미 존재하는 사용자명입니다")
    
    if db.query(User).filter(User.email == user_data.email).first():
        raise BadRequestError("이미 존재하는 이메일입니다")
    
    # 역할 유효성 검사
    if user_data.role not in ["admin", "user"]:
        raise BadRequestError("역할은 'admin' 또는 'user'만 가능합니다")
    
    # 사용자 생성
    new_user = User(
        username=user_data.username,
        email=user_data.email,
        hashed_password=hash_password(user_data.password),
        full_name=user_data.full_name,
        role=UserRole.ADMIN if user_data.role == "admin" else UserRole.USER,
        is_active=True
    )
    
    db.add(new_user)
    db.commit()
    
    return AdminResponse(
        success=True,
        message=f"사용자 '{user_data.username}'이(가) 생성되었습니다"
    )

@router.put("/users/{user_id}", response_model=AdminResponse)
async def update_user(
    user_id: int,
    user_data: UserUpdate,
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """사용자 정보 수정"""
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise NotFoundError("사용자를 찾을 수 없습니다")
    
    # 이메일 중복 확인
    if user_data.email and user_data.email != user.email:
        if db.query(User).filter(User.email == user_data.email).first():
            raise BadRequestError("이미 존재하는 이메일입니다")
        user.email = user_data.email
    
    # 비밀번호 변경
    if user_data.password:
        user.hashed_password = hash_password(user_data.password)
    
    # 기타 정보 업데이트
    if user_data.full_name is not None:
        user.full_name = user_data.full_name
    
    if user_data.role:
        if user_data.role not in ["admin", "user"]:
            raise BadRequestError("역할은 'admin' 또는 'user'만 가능합니다")
        user.role = UserRole.ADMIN if user_data.role == "admin" else UserRole.USER
    
    if user_data.is_active is not None:
        user.is_active = user_data.is_active
    
    db.commit()
    
    return AdminResponse(
        success=True,
        message=f"사용자 '{user.username}'의 정보가 수정되었습니다"
    )

@router.delete("/users/{user_id}", response_model=AdminResponse)
async def delete_user(
    user_id: int,
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """사용자 삭제"""
    # 자기 자신은 삭제 불가
    if user_id == current_user.id:
        raise BadRequestError("자기 자신은 삭제할 수 없습니다")
    
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise NotFoundError("사용자를 찾을 수 없습니다")
    
    username = user.username
    db.delete(user)
    db.commit()
    
    return AdminResponse(
        success=True,
        message=f"사용자 '{username}'이(가) 삭제되었습니다"
    )

# ==================== VM 접근 권한 관리 ====================

@router.get("/vm-access", response_model=VMAccessListResponse)
async def get_vm_access_list(
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """VM 접근 권한 목록 조회"""
    accesses = db.query(VMAccess).join(User).all()
    
    access_list = [
        VMAccessInfo(
            id=access.id,
            user_id=access.user_id,
            username=access.user.username,
            vm_id=access.vm_id,
            node=access.node,
            vm_name=access.vm_name,
            static_ip=access.static_ip,
            rdp_username=access.rdp_username,
            rdp_port=access.rdp_port,
            is_active=access.is_active,
            created_at=access.created_at
        )
        for access in accesses
    ]
    
    return VMAccessListResponse(total=len(access_list), accesses=access_list)

@router.post("/vm-access", response_model=AdminResponse)
async def create_vm_access(
    access_data: VMAccessCreate,
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """VM 접근 권한 부여"""
    # 사용자 존재 확인
    user = db.query(User).filter(User.id == access_data.user_id).first()
    if not user:
        raise NotFoundError("사용자를 찾을 수 없습니다")
    
    # 중복 확인
    existing = db.query(VMAccess).filter(
        VMAccess.user_id == access_data.user_id,
        VMAccess.vm_id == access_data.vm_id
    ).first()
    
    if existing:
        raise BadRequestError("이미 해당 사용자에게 VM 접근 권한이 있습니다")
    
    # 권한 생성
    access = VMAccess(
        user_id=access_data.user_id,
        vm_id=access_data.vm_id,
        node=access_data.node,
        static_ip=access_data.static_ip,
        rdp_username=access_data.rdp_username,
        rdp_password=access_data.rdp_password,
        rdp_port=access_data.rdp_port,
        is_active=True
    )
    
    db.add(access)
    db.commit()
    
    return AdminResponse(
        success=True,
        message=f"사용자 '{user.username}'에게 VM {access_data.vm_id} 접근 권한이 부여되었습니다"
    )

@router.put("/vm-access/{access_id}", response_model=AdminResponse)
async def update_vm_access(
    access_id: int,
    access_data: VMAccessUpdate,
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """VM 접근 권한 수정"""
    access = db.query(VMAccess).filter(VMAccess.id == access_id).first()
    if not access:
        raise NotFoundError("접근 권한을 찾을 수 없습니다")
    
    # 정보 업데이트
    if access_data.static_ip is not None:
        access.static_ip = access_data.static_ip
    
    if access_data.rdp_username is not None:
        access.rdp_username = access_data.rdp_username
    
    if access_data.rdp_password is not None:
        access.rdp_password = access_data.rdp_password
    
    if access_data.rdp_port is not None:
        access.rdp_port = access_data.rdp_port
    
    if access_data.is_active is not None:
        access.is_active = access_data.is_active
    
    db.commit()
    
    return AdminResponse(
        success=True,
        message=f"VM {access.vm_id} 접근 권한이 수정되었습니다"
    )

@router.delete("/vm-access/{access_id}", response_model=AdminResponse)
async def delete_vm_access(
    access_id: int,
    current_user: CurrentUser = Depends(require_admin),
    db: Session = Depends(get_db)
):
    """VM 접근 권한 삭제"""
    access = db.query(VMAccess).filter(VMAccess.id == access_id).first()
    if not access:
        raise NotFoundError("접근 권한을 찾을 수 없습니다")
    
    vm_id = access.vm_id
    db.delete(access)
    db.commit()
    
    return AdminResponse(
        success=True,
        message=f"VM {vm_id} 접근 권한이 삭제되었습니다"
    )
