"""Template CRUD + generate + category routes."""

from __future__ import annotations

import logging

from app.auth import AuthenticatedUser, get_current_user
from app.dependencies import get_db_session
from app.schemas.template import (
    CategoryResponse,
    CreateCategoryRequest,
    CreateTemplateRequest,
    GenerateWarningResponse,
    ListCategoriesResponse,
    ListTemplatesResponse,
    SegmentResponse,
    TemplateResponse,
    ToggleFavoriteResponse,
    UpdateTemplateRequest,
    ValidateTemplateRequest,
    ValidateTemplateResponse,
)
from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy.orm import Session

logger = logging.getLogger(__name__)

from packages.adapters.sqlalchemy_impl.template_repository import SQLAlchemyTemplateRepository
from packages.application.template.commands import (
    CreateCategoryCommand,
    CreateTemplateCommand,
    SegmentCommand,
    UpdateTemplateCommand,
    ValidateTemplateCommand,
)
from packages.application.template.use_cases import (
    CreateCategoryUseCase,
    CreateTemplateUseCase,
    DeleteCategoryUseCase,
    DeleteTemplateUseCase,
    GetTemplateUseCase,
    ListCategoriesUseCase,
    ListTemplatesUseCase,
    NotFoundError,
    UpdateTemplateUseCase,
    ValidateTemplateUseCase,
    ValidationError,
)

router = APIRouter()


def _get_template_repository(session: Session = Depends(get_db_session)) -> SQLAlchemyTemplateRepository:
    return SQLAlchemyTemplateRepository(session)


def _segment_to_response(seg) -> SegmentResponse:
    return SegmentResponse(
        id=seg.id,
        template_id=seg.template_id,
        segment_order=seg.segment_order,
        duration_min=seg.duration_min,
        duration_max=seg.duration_max,
        material_type=seg.material_type,
        created_at=seg.created_at,
        updated_at=seg.updated_at,
    )


def _to_response(template) -> TemplateResponse:
    return TemplateResponse(
        id=template.id,
        user_id=template.user_id,
        name=template.name,
        mode=template.mode,
        category=template.category,
        tags=template.tags,
        title_config=template.title_config,
        subtitle_config=template.subtitle_config,
        bgm_config=template.bgm_config,
        estimated_duration=template.estimated_duration,
        segments=[_segment_to_response(s) for s in getattr(template, "segments", [])],
        is_active=template.is_active,
        created_at=template.created_at,
        updated_at=template.updated_at,
    )


# ── Template CRUD ──


@router.get("", response_model=ListTemplatesResponse)
def list_templates(
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=200),
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> ListTemplatesResponse:
    user_id = authenticated_user.user.id
    try:
        use_case = ListTemplatesUseCase(template_repository)
        templates = use_case.execute(user_id, skip=skip, limit=limit)
        total = template_repository.count_by_user(user_id)
    except Exception:
        logger.exception("list_templates 查询失败: user_id=%s", user_id)
        return ListTemplatesResponse(items=[], total=0)
    return ListTemplatesResponse(
        items=[_to_response(t) for t in templates],
        total=total,
    )


@router.get("/{template_id}", response_model=TemplateResponse)
def get_template(
    template_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> TemplateResponse:
    user_id = authenticated_user.user.id
    try:
        use_case = GetTemplateUseCase(template_repository)
        template = use_case.execute(template_id, user_id)
    except Exception:
        logger.exception("get_template 查询失败: template_id=%s", template_id)
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="模板查询失败")
    if template is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
    return _to_response(template)


@router.post("", response_model=TemplateResponse, status_code=status.HTTP_201_CREATED)
def create_template(
    request: CreateTemplateRequest,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> TemplateResponse:
    user_id = authenticated_user.user.id
    command = CreateTemplateCommand(
        user_id=user_id,
        name=request.name,
        mode=request.mode,
        category=request.category,
        tags=request.tags,
        title_config=request.title_config,
        subtitle_config=request.subtitle_config,
        bgm_config=request.bgm_config,
        estimated_duration=request.estimated_duration,
        segments=[
            SegmentCommand(
                segment_order=s.segment_order,
                duration_min=s.duration_min,
                duration_max=s.duration_max,
                material_type=s.material_type,
            )
            for s in request.segments
        ],
    )
    use_case = CreateTemplateUseCase(template_repository)
    try:
        template = use_case.execute(command)
    except ValidationError as exc:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc))
    return _to_response(template)


@router.patch("/{template_id}", response_model=TemplateResponse)
def update_template(
    template_id: str,
    request: UpdateTemplateRequest,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> TemplateResponse:
    user_id = authenticated_user.user.id
    command = UpdateTemplateCommand(
        template_id=template_id,
        user_id=user_id,
        name=request.name,
        mode=request.mode,
        category=request.category,
        tags=request.tags,
        title_config=request.title_config,
        subtitle_config=request.subtitle_config,
        bgm_config=request.bgm_config,
        estimated_duration=request.estimated_duration,
        segments=(
            [
                SegmentCommand(
                    segment_order=s.segment_order,
                    duration_min=s.duration_min,
                    duration_max=s.duration_max,
                    material_type=s.material_type,
                )
                for s in request.segments
            ]
            if request.segments is not None
            else None
        ),
    )
    use_case = UpdateTemplateUseCase(template_repository)
    try:
        template = use_case.execute(command)
    except NotFoundError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
    except ValidationError as exc:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc))
    return _to_response(template)


@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_template(
    template_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> Response:
    user_id = authenticated_user.user.id
    use_case = DeleteTemplateUseCase(template_repository)
    deleted = use_case.execute(template_id, user_id)
    if not deleted:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
    return Response(status_code=204)


@router.post("/{template_id}/toggle-favorite", response_model=ToggleFavoriteResponse)
def toggle_favorite(
    template_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> ToggleFavoriteResponse:
    """切换模板收藏状态（当前为兼容端点，始终返回 false）"""
    user_id = authenticated_user.user.id
    use_case = GetTemplateUseCase(template_repository)
    try:
        template = use_case.execute(template_id, user_id)
    except Exception:
        logger.exception("toggle_favorite 查询失败: template_id=%s", template_id)
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
    if template is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
    return ToggleFavoriteResponse(id=template_id, is_favorite=False)


# ── Validate template ──


@router.post("/{template_id}/validate", response_model=ValidateTemplateResponse)
def validate_template(
    template_id: str,
    request: ValidateTemplateRequest = ValidateTemplateRequest(),
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> ValidateTemplateResponse:
    user_id = authenticated_user.user.id
    command = ValidateTemplateCommand(
        template_id=template_id,
        user_id=user_id,
        voiceover_duration=request.voiceover_duration,
    )
    use_case = ValidateTemplateUseCase(template_repository)
    try:
        result = use_case.execute(command)
    except NotFoundError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
    except ValidationError as exc:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc))

    return ValidateTemplateResponse(
        template=_to_response(result.template),
        warnings=[GenerateWarningResponse(code=w.code, message=w.message, details=w.details) for w in result.warnings],
    )


# ── Category CRUD ──


@router.get("/categories/list", response_model=ListCategoriesResponse)
def list_categories(
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> ListCategoriesResponse:
    user_id = authenticated_user.user.id
    try:
        use_case = ListCategoriesUseCase(template_repository)
        categories = use_case.execute(user_id)
    except Exception:
        logger.exception("list_categories 查询失败: user_id=%s", user_id)
        return ListCategoriesResponse(items=[])
    return ListCategoriesResponse(
        items=[CategoryResponse(id=c.id, user_id=c.user_id, name=c.name, created_at=c.created_at) for c in categories],
    )


@router.post("/categories", response_model=CategoryResponse, status_code=status.HTTP_201_CREATED)
def create_category(
    request: CreateCategoryRequest,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> CategoryResponse:
    user_id = authenticated_user.user.id
    command = CreateCategoryCommand(user_id=user_id, name=request.name)
    use_case = CreateCategoryUseCase(template_repository)
    category = use_case.execute(command)
    return CategoryResponse(
        id=category.id,
        user_id=category.user_id,
        name=category.name,
        created_at=category.created_at,
    )


@router.delete("/categories/{category_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_category(
    category_id: str,
    authenticated_user: AuthenticatedUser = Depends(get_current_user),
    template_repository: SQLAlchemyTemplateRepository = Depends(_get_template_repository),
) -> Response:
    user_id = authenticated_user.user.id
    use_case = DeleteCategoryUseCase(template_repository)
    deleted = use_case.execute(category_id, user_id)
    if not deleted:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Category not found")
    return Response(status_code=204)
