from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel, Field

from app.services.package_management_service import PackageManagementService
from app.utils.response import success_response


router = APIRouter()
service = PackageManagementService()


class CategoryCreateRequest(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    parent_id: str | int | None = Field(default='all')


class CategoryUpdateRequest(BaseModel):
    name: str = Field(min_length=1, max_length=100)


@router.get('/categories')
def get_categories():
    return success_response(data=service.get_category_tree())


@router.post('/categories')
def create_category(request: CategoryCreateRequest):
    try:
        parent_id = 'all' if request.parent_id is None else str(request.parent_id)
        category = service.create_category(name=request.name.strip(), parent_id=parent_id)
        return success_response(data=category, message='分类创建成功')
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


@router.put('/categories/{category_id}')
def update_category(category_id: str, request: CategoryUpdateRequest):
    try:
        category = service.update_category(category_id=category_id, name=request.name.strip())
        return success_response(data=category, message='分类更新成功')
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


@router.delete('/categories/{category_id}')
def delete_category(category_id: str):
    try:
        service.delete_category(category_id=category_id)
        return success_response(data=True, message='分类删除成功')
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


# Must be declared before /{package_id} routes to avoid path conflict
@router.get('/data-files')
def list_all_data_files():
    return success_response(data=service.list_all_data_files())


class PackageCreateRequest(BaseModel):
    name: str = Field(min_length=1, max_length=255)
    category_id: str | int | None = Field(default=None)
    remark: str | None = Field(default=None)
    file_ids: list[int] = Field(default_factory=list)


class PreviewRequest(BaseModel):
    file_ids: list[int] = Field(default_factory=list)


@router.post('/preview')
def preview_package(request: PreviewRequest, limit: int = Query(default=300, ge=1, le=2000)):
    try:
        result = service.preview_records(file_ids=request.file_ids, limit=limit)
        return success_response(data=result)
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


@router.get('')
def list_packages(
    category_id: str = Query(default=''),
    name: str = Query(default=''),
):
    return success_response(data=service.list_packages(category_id=category_id, name=name.strip()))


@router.post('')
def create_package(request: PackageCreateRequest):
    try:
        category_id = None if request.category_id in (None, '', 'all') else str(request.category_id)
        pkg = service.create_package(
            name=request.name.strip(),
            category_id=category_id,
            remark=request.remark,
            file_ids=request.file_ids,
        )
        return success_response(data=pkg, message='数据包创建成功')
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


@router.get('/{package_id}/records')
def get_package_records(package_id: str, limit: int = Query(default=500, ge=1, le=5000)):
    try:
        result = service.get_package_records(package_id=package_id, limit=limit)
        return success_response(data=result)
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


@router.delete('/{package_id}')
def delete_package(package_id: str):
    try:
        service.delete_package(package_id=package_id)
        return success_response(data=True, message='数据包删除成功')
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error
