from fastapi import APIRouter, Depends, HTTPException, status

from app.api.dependencies.auth import get_access_token
from app.api.dependencies.permissions import require_permission
from app.application.editor.service import EditorService
from app.schemas.auth import AuthenticatedUser
from app.schemas.editor import (
    BuildPreviewRequest,
    BuildPreviewResponse,
    EditorChangeListResponse,
    EditorSessionCreateRequest,
    EditorSessionRead,
    EditorSessionUpdateRequest,
    SaveVariantChangesRequest,
)

router = APIRouter()
service = EditorService()


@router.post("/sessions", response_model=EditorSessionRead)
async def create_editor_session(
    request: EditorSessionCreateRequest,
    current_user: AuthenticatedUser = Depends(require_permission("can_use_editor")),
) -> EditorSessionRead:
    return await service.create_session(request, current_user)


@router.get("/sessions/{session_id}", response_model=EditorSessionRead)
async def get_editor_session(
    session_id: str,
    _: AuthenticatedUser = Depends(require_permission("can_use_editor")),
) -> EditorSessionRead:
    item = await service.get_session(session_id)
    if not item:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Editor session '{session_id}' not found.",
        )
    return item


@router.patch("/sessions/{session_id}", response_model=EditorSessionRead)
async def update_editor_session(
    session_id: str,
    request: EditorSessionUpdateRequest,
    _: AuthenticatedUser = Depends(require_permission("can_use_editor")),
) -> EditorSessionRead:
    item = await service.update_session(session_id, request)
    if not item:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Editor session '{session_id}' not found.",
        )
    return item


@router.delete("/sessions/{session_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_editor_session(
    session_id: str,
    _: AuthenticatedUser = Depends(require_permission("can_use_editor")),
) -> None:
    await service.delete_session(session_id)


@router.get("/variants/{variant_id}/changes", response_model=EditorChangeListResponse)
async def list_variant_changes(
    variant_id: str,
    _: AuthenticatedUser = Depends(require_permission("can_use_editor")),
    access_token: str = Depends(get_access_token),
) -> EditorChangeListResponse:
    return await service.list_changes_with_access_token(variant_id, access_token)


@router.put("/variants/{variant_id}/changes", response_model=EditorChangeListResponse)
async def save_variant_changes(
    variant_id: str,
    request: SaveVariantChangesRequest,
    _: AuthenticatedUser = Depends(require_permission("can_use_editor")),
    access_token: str = Depends(get_access_token),
) -> EditorChangeListResponse:
    return await service.save_changes_with_access_token(variant_id, request, access_token)


@router.post("/previews/build", response_model=BuildPreviewResponse)
async def build_preview(
    request: BuildPreviewRequest,
    _: AuthenticatedUser = Depends(require_permission("can_use_editor")),
) -> BuildPreviewResponse:
    return await service.build_preview(request)
