from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.utils import get_openapi
from fastapi.staticfiles import StaticFiles
from scalar_fastapi import get_scalar_api_reference

from app.admin_manager import init_admin
from app.core.common import lifespan
from app.database.session import engine

# 주의: User 모델을 먼저 import해야 UserProject가 User를 참조할 수 있음
from app.user.models import User, RefreshToken  # noqa: F401

from app.home.api.routers.v1.home import router as home_router
from app.user.api.routers.v1.auth import router as auth_router
from app.lyric.api.routers.v1.lyric import router as lyric_router
from app.song.api.routers.v1.song import router as song_router
from app.video.api.routers.v1.video import router as video_router
from app.utils.cors import CustomCORSMiddleware
from config import prj_settings

tags_metadata = [
    {
        "name": "Auth",
        "description": """카카오 소셜 로그인 및 JWT 토큰 관리 API

## 인증 흐름

1. `GET /api/v1/user/auth/kakao/login` - 카카오 로그인 URL 획득
2. 사용자를 auth_url로 리다이렉트 → 카카오 로그인
3. 카카오에서 인가 코드(code) 발급
4. `POST /api/v1/user/auth/kakao/callback` - 인가 코드로 JWT 토큰 발급
5. 이후 API 호출 시 `Authorization: Bearer {access_token}` 헤더 사용

## 토큰 관리

- **Access Token**: 1시간 유효, API 호출 시 사용
- **Refresh Token**: 7일 유효, Access Token 갱신 시 사용
""",
    },
    {
        "name": "Home",
        "description": "홈 화면 및 프로젝트 관리 API",
    },
    {
        "name": "crawling",
        "description": "네이버 지도 크롤링 API - 장소 정보 및 이미지 수집",
    },
    {
        "name": "image",
        "description": "이미지 업로드 API - 로컬 서버 또는 Azure Blob Storage",
    },
    {
        "name": "Lyric",
        "description": """가사 생성 및 관리 API

## 가사 생성 흐름

1. `POST /api/v1/lyric/generate` - 가사 생성 요청 (백그라운드 처리)
2. `GET /api/v1/lyric/status/{task_id}` - 생성 상태 확인
3. `GET /api/v1/lyric/{task_id}` - 생성된 가사 조회
""",
    },
    {
        "name": "Song",
        "description": """노래 생성 및 관리 API (Suno AI)

## 노래 생성 흐름

1. `POST /api/v1/song/generate/{task_id}` - 노래 생성 요청
2. `GET /api/v1/song/status/{suno_task_id}` - Suno API 상태 확인
3. `GET /api/v1/song/download/{task_id}` - 노래 다운로드 URL 조회
""",
    },
    {
        "name": "Video",
        "description": """영상 생성 및 관리 API (Creatomate)

## 영상 생성 흐름

1. `GET /api/v1/video/generate/{task_id}` - 영상 생성 요청
2. `GET /api/v1/video/status/{creatomate_render_id}` - Creatomate 상태 확인
3. `GET /api/v1/video/download/{task_id}` - 영상 다운로드 URL 조회
""",
    },
]

app = FastAPI(
    title=prj_settings.PROJECT_NAME,
    version=prj_settings.VERSION,
    description=prj_settings.DESCRIPTION,
    lifespan=lifespan,
    docs_url=None,  # 기본 Swagger UI 비활성화
    redoc_url=None,  # 기본 ReDoc 비활성화
    openapi_tags=tags_metadata,
)


def custom_openapi():
    """커스텀 OpenAPI 스키마 생성 (Bearer 인증 추가)"""
    if app.openapi_schema:
        return app.openapi_schema

    openapi_schema = get_openapi(
        title=app.title,
        version=app.version,
        description=app.description,
        routes=app.routes,
        tags=tags_metadata,
    )

    # Bearer 토큰 인증 스키마 추가
    openapi_schema["components"]["securitySchemes"] = {
        "BearerAuth": {
            "type": "http",
            "scheme": "bearer",
            "bearerFormat": "JWT",
            "description": "JWT 액세스 토큰을 입력하세요. 카카오 로그인 후 발급받은 access_token을 사용합니다.",
        }
    }

    # 보안이 필요한 엔드포인트에 security 적용
    for path, path_item in openapi_schema["paths"].items():
        for method, operation in path_item.items():
            if method in ["get", "post", "put", "patch", "delete"]:
                # /auth/me, /auth/logout 등 인증이 필요한 엔드포인트
                if any(
                    auth_path in path
                    for auth_path in ["/auth/me", "/auth/logout"]
                ):
                    operation["security"] = [{"BearerAuth": []}]

    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

init_admin(app, engine)

custom_cors_middleware = CustomCORSMiddleware(app)
custom_cors_middleware.configure_cors()

app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/media", StaticFiles(directory="media"), name="media")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
    allow_credentials=True,
    max_age=-1,
)


@app.get("/docs", include_in_schema=False)
def get_scalar_docs():
    return get_scalar_api_reference(
        openapi_url=app.openapi_url,
        title="Scalar API",
    )


app.include_router(home_router)
app.include_router(auth_router, prefix="/user")  # Auth API 라우터 추가
app.include_router(lyric_router)
app.include_router(song_router)
app.include_router(video_router)
