import asyncio
from typing import Optional
from fastapi import APIRouter, Query, Depends, HTTPException, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
from starlette import status

from src.category.schemas import CategoryResponse, CategoryStatusEnum, CategoryCreateForm, \
    CategoryUpdateForm
from src.database import get_db
from src.category.models import CategoryStatus
from src.category.service import CategoryService
from src.cache.download_cache import update_category_cache

router = APIRouter(prefix="/category", tags=["Категорії"])

@router.get("")
async def list_categories(
    db: AsyncSession = Depends(get_db),
    needle: Optional[str] = Query(
        default=None,
        description="ID категорії або назва для пошуку"
    ),
    type_filter: Optional[str] = Query(default="all", description="Тип категорій: all, main, final"),
    status: Optional[int] = Query(  # 0 або 1
        default=None,
        description="Статус категорії: 1 - включена, 0 - виключена"
    ),
    sort_order: Optional[str] = Query(
        default="name_path",
        description="Сортування за назвою з повним шляхом або по ID"
    ),
    sort_field: Optional[str] = Query(
        default="asc",
        description="Напрям сортування: по зростанню або спаданню"
    ),
    page: int = Query(1, ge=1),
    limit: int = Query(10, ge=1),
):
    dashboard, items = await CategoryService.get_categories(
        db=db,
        needle=needle,
        type_filter=type_filter,
        status=status,
        sort_by=sort_order,
        sort_order=sort_field,
        page=page,
        limit=limit,
    )

    return {
        "data": items,
        "dashboard": dashboard,
        "total": dashboard["total_quantity"],
        "page": page,
        "limit": limit,
        "status": True,
    }

@router.get("/{category_id}")
async def get_category(
    category_id: int,
    db: AsyncSession = Depends(get_db)
):
    category = await CategoryService.get_category_by_id(db, category_id)

    if not category:
        raise HTTPException(status_code=404, detail="Категорію не знайдено")

    category_data = category.__dict__.copy()
    category_data["status"] = category.status

    if category.parent:
        category_data["parent_category_name"] = category.parent.name
    else:
        category_data["parent_category_name"] = None

    if category.date_added:
        category_data["date_added"] = category.date_added.isoformat()
    if category.date_modify:
        category_data["date_modify"] = category.date_modify.isoformat()

    category_pydantic = CategoryResponse.model_validate(category_data)

    return {
        "data": category_pydantic,
        "status": True
    }

@router.post("")
async def create_category(
    form_data: CategoryCreateForm = Depends(),
    db: AsyncSession = Depends(get_db)
):
    category = await CategoryService.create_category(db, form_data)

    asyncio.create_task(update_category_cache(category.category_id))

    return {
        "data": {
            "category_id": category.category_id,
            "name": category.name,
            "description": category.description,
            "parent_category_id": category.parent_category_id,
            "seo_keyword": category.seo_keyword,
            "meta_title": category.meta_title,
            "meta_description": category.meta_description,
            "meta_keyword": category.meta_keyword,
            "image": category.image,
            "icon": category.icon,
            "status": category.status,
            "sort_order": category.sort_order,
            "date_added": category.date_added,
            "date_modify": category.date_modify,
        },
        "status": True
    }

@router.patch("/{category_id}")
async def update_category(
    category_id: int,
    data: CategoryUpdateForm = Depends(),
    image: Optional[UploadFile] = File(None),
    db: AsyncSession = Depends(get_db),
):
    updated_category = await CategoryService.update_category(
        db=db,
        category_id=category_id,
        name=data.name,
        description=data.description,
        parent_id=data.parent_id,
        slug=data.slug,
        meta_title=data.meta_title,
        meta_description=data.meta_description,
        meta_keywords=data.meta_keywords,
        status=data.status,
        sort_order=data.sort_order,
        image=image,
        icon=data.icon,
    )

    asyncio.create_task(update_category_cache(category_id))

    if not updated_category:
        raise HTTPException(status_code=404, detail="Category not found")

    return {
        "data": updated_category,
        "status": True
    }

@router.delete("/{category_id}", status_code=status.HTTP_200_OK)
async def delete_category(
    category_id: int,
    db: AsyncSession = Depends(get_db),
):
    success = await CategoryService.delete_category_recursive(db, category_id)

    if not success:
        raise HTTPException(status_code=404, detail=f"Category {category_id} not found")

    return {
        "data": f"Category {category_id} and its subcategories deleted successfully",
        "status": True,
    }