"""
에러 처리 유틸리티
표준화된 에러 응답 및 예외 처리
"""
from fastapi import HTTPException, Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from sqlalchemy.exc import SQLAlchemyError
from typing import Dict, Any
import traceback

from .logger import get_logger

logger = get_logger(__name__)


class TKMPException(Exception):
    """TK-MP 프로젝트 커스텀 예외"""
    
    def __init__(self, message: str, error_code: str = "TKMP_ERROR", status_code: int = 500):
        self.message = message
        self.error_code = error_code
        self.status_code = status_code
        super().__init__(self.message)


class ErrorResponse:
    """표준화된 에러 응답 생성기"""
    
    @staticmethod
    def create_error_response(
        message: str,
        error_code: str = "INTERNAL_ERROR",
        status_code: int = 500,
        details: Dict[str, Any] = None
    ) -> Dict[str, Any]:
        """표준화된 에러 응답 생성"""
        response = {
            "success": False,
            "error": {
                "code": error_code,
                "message": message,
                "timestamp": "2025-01-01T00:00:00Z"  # 실제로는 datetime.utcnow().isoformat()
            }
        }
        
        if details:
            response["error"]["details"] = details
        
        return response
    
    @staticmethod
    def validation_error_response(errors: list) -> Dict[str, Any]:
        """검증 에러 응답"""
        return ErrorResponse.create_error_response(
            message="입력 데이터 검증에 실패했습니다.",
            error_code="VALIDATION_ERROR",
            status_code=422,
            details={"validation_errors": errors}
        )
    
    @staticmethod
    def database_error_response(error: str) -> Dict[str, Any]:
        """데이터베이스 에러 응답"""
        return ErrorResponse.create_error_response(
            message="데이터베이스 작업 중 오류가 발생했습니다.",
            error_code="DATABASE_ERROR",
            status_code=500,
            details={"db_error": error}
        )
    
    @staticmethod
    def file_error_response(error: str) -> Dict[str, Any]:
        """파일 처리 에러 응답"""
        return ErrorResponse.create_error_response(
            message="파일 처리 중 오류가 발생했습니다.",
            error_code="FILE_ERROR",
            status_code=400,
            details={"file_error": error}
        )


async def tkmp_exception_handler(request: Request, exc: TKMPException):
    """TK-MP 커스텀 예외 핸들러"""
    logger.error(f"TK-MP 예외 발생: {exc.message} (코드: {exc.error_code})")
    
    return JSONResponse(
        status_code=exc.status_code,
        content=ErrorResponse.create_error_response(
            message=exc.message,
            error_code=exc.error_code,
            status_code=exc.status_code
        )
    )


async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """검증 예외 핸들러"""
    logger.warning(f"검증 오류: {exc.errors()}")
    
    return JSONResponse(
        status_code=422,
        content=ErrorResponse.validation_error_response(exc.errors())
    )


async def sqlalchemy_exception_handler(request: Request, exc: SQLAlchemyError):
    """SQLAlchemy 예외 핸들러"""
    logger.error(f"데이터베이스 오류: {str(exc)}", exc_info=True)
    
    return JSONResponse(
        status_code=500,
        content=ErrorResponse.database_error_response(str(exc))
    )


async def general_exception_handler(request: Request, exc: Exception):
    """일반 예외 핸들러"""
    logger.error(f"예상치 못한 오류: {str(exc)}", exc_info=True)
    
    return JSONResponse(
        status_code=500,
        content=ErrorResponse.create_error_response(
            message="서버 내부 오류가 발생했습니다.",
            error_code="INTERNAL_SERVER_ERROR",
            status_code=500,
            details={"error": str(exc)} if logger.level <= 10 else None  # DEBUG 레벨일 때만 상세 에러 표시
        )
    )


def setup_error_handlers(app):
    """FastAPI 앱에 에러 핸들러 등록"""
    app.add_exception_handler(TKMPException, tkmp_exception_handler)
    app.add_exception_handler(RequestValidationError, validation_exception_handler)
    app.add_exception_handler(SQLAlchemyError, sqlalchemy_exception_handler)
    app.add_exception_handler(Exception, general_exception_handler)
    
    logger.info("에러 핸들러 등록 완료")
