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)


class CleanRules(BaseModel):
    enabled: bool = False
    newton_interp: bool = False
    current_min: float | None = None
    current_max: float | None = None
    voltage_min: float | None = None
    voltage_max: float | None = None
    temperature_min: float | None = None
    temperature_max: float | None = None


class SmoothConfig(BaseModel):
    enabled: bool = False
    window: int = Field(default=5, ge=2, le=500)


@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(
    category_id: str = Query(default=''),
    filename: str = Query(default=''),
    remark: str = Query(default=''),
):
    return success_response(data=service.list_all_data_files(
        category_id=category_id,
        filename=filename.strip(),
        remark=remark.strip(),
    ))


class PackageUpdateRequest(BaseModel):
    name: str = Field(min_length=1, max_length=255)
    category_id: str | int | None = Field(default=None)
    remark: str | None = Field(default=None)


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)
    clean_rules: CleanRules | None = Field(default=None)
    smooth: SmoothConfig | None = Field(default=None)
    auto_split: bool = Field(default=False)
    row_start: int | None = Field(default=None, ge=1)
    row_end: int | None = Field(default=None, ge=1)


class PreviewRequest(BaseModel):
    file_ids: list[int] = Field(default_factory=list)
    clean_rules: CleanRules | None = Field(default=None)
    smooth: SmoothConfig | None = Field(default=None)
    row_start: int | None = Field(default=None, ge=1)
    row_end: int | None = Field(default=None, ge=1)


@router.post('/preview')
def preview_package(request: PreviewRequest):
    try:
        if request.row_start and request.row_end and request.row_start > request.row_end:
            raise ValueError('起始行不能大于结束行')
        clean_rules = request.clean_rules.model_dump() if request.clean_rules else None
        smooth = request.smooth.model_dump() if request.smooth else None
        result = service.preview_records(
            file_ids=request.file_ids,
            limit=None,
            clean_rules=clean_rules,
            smooth=smooth,
            row_start=request.row_start,
            row_end=request.row_end,
        )
        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:
        if request.row_start and request.row_end and request.row_start > request.row_end:
            raise ValueError('起始行不能大于结束行')
        category_id = None if request.category_id in (None, '', 'all') else str(request.category_id)
        clean_rules = request.clean_rules.model_dump() if request.clean_rules else None
        smooth = request.smooth.model_dump() if request.smooth else None
        base_name = request.name.strip()
        if request.auto_split:
            pkgs = service.create_package_split(
                name=base_name,
                category_id=category_id,
                remark=request.remark,
                file_ids=request.file_ids,
                clean_rules=clean_rules,
                smooth=smooth,
                row_start=request.row_start,
                row_end=request.row_end,
            )
            return success_response(data=pkgs, message='数据包创建成功，已自动划分训练集/验证集/测试集')
        pkg = service.create_package(
            name=base_name,
            category_id=category_id,
            remark=request.remark,
            file_ids=request.file_ids,
            clean_rules=clean_rules,
            smooth=smooth,
            row_start=request.row_start,
            row_end=request.row_end,
        )
        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):
    try:
        result = service.get_package_records(package_id=package_id, limit=None)
        return success_response(data=result)
    except ValueError as error:
        raise HTTPException(status_code=400, detail=str(error)) from error


@router.put('/{package_id}')
def update_package(package_id: str, request: PackageUpdateRequest):
    try:
        category_id = None if request.category_id in (None, '', 'all') else str(request.category_id)
        result = service.update_package(
            package_id=package_id,
            name=request.name.strip(),
            category_id=category_id,
            remark=request.remark,
        )
        return success_response(data=result, message='数据包更新成功')
    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
