from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.deps import require_role
from app.database import get_db
from app.models.user import User
from app.schemas.common import ApiResponse
from app.schemas.product_group import (
    ProductCategoryCreate,
    ProductCategoryResponse,
    ProductCategoryUpdate,
    ProductGroupCreate,
    ProductGroupOsOptionsPageUpdate,
    ProductGroupResponse,
    ProductGroupUpdate,
    ProductGroupVerificationRuleUpdate,
)
from app.services import product_group_service

router = APIRouter()
_admin = require_role("admin", "super_admin")


def _serialize_group(item, include_os_options: bool) -> ProductGroupResponse:
    if include_os_options:
        return ProductGroupResponse.model_validate(item)

    return ProductGroupResponse.model_validate({
        "id": item.id,
        "category_id": item.category_id,
        "parent_id": item.parent_id,
        "slug": item.slug,
        "name": item.name,
        "headline": item.headline,
        "description": item.description,
        "icon": item.icon,
        "network_type": item.network_type,
        "sort_order": item.sort_order,
        "requires_real_name": item.requires_real_name,
        "area": item.area,
        "node": item.node,
        "os_options": [],
        "created_at": item.created_at,
        "updated_at": item.updated_at,
    })


# ---------- categories ----------


@router.get("/categories", response_model=ApiResponse)
async def list_categories(
    db: AsyncSession = Depends(get_db), _: User = Depends(_admin)
):
    items = await product_group_service.list_categories(db)
    return ApiResponse(data=[ProductCategoryResponse.model_validate(i) for i in items])


@router.post("/categories", response_model=ApiResponse)
async def create_category(
    data: ProductCategoryCreate,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    cat = await product_group_service.create_category(db, data)
    return ApiResponse(data=ProductCategoryResponse.model_validate(cat))


@router.put("/categories/{cat_id}", response_model=ApiResponse)
async def update_category(
    cat_id: int,
    data: ProductCategoryUpdate,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    cat = await product_group_service.update_category(db, cat_id, data)
    return ApiResponse(data=ProductCategoryResponse.model_validate(cat))


@router.delete("/categories/{cat_id}", response_model=ApiResponse)
async def delete_category(
    cat_id: int,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    await product_group_service.delete_category(db, cat_id)
    return ApiResponse(data=None)


# ---------- groups ----------


@router.get("/groups", response_model=ApiResponse)
async def list_groups(
    category_id: int | None = Query(None),
    include_os_options: bool = Query(True),
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    items = await product_group_service.list_groups(db, category_id, include_os_options)
    return ApiResponse(data=[_serialize_group(item, include_os_options) for item in items])


@router.get("/groups/{group_id}/os-options", response_model=ApiResponse)
async def list_group_os_options(
    group_id: int,
    offset: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=200),
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    data = await product_group_service.get_os_options_page(db, group_id, offset, limit)
    return ApiResponse(data=data)


@router.put("/groups/{group_id}/os-options/page", response_model=ApiResponse)
async def update_group_os_options_page(
    group_id: int,
    data: ProductGroupOsOptionsPageUpdate,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    page = await product_group_service.replace_os_options_page(
        db,
        group_id,
        data.offset,
        data.limit,
        data.items,
    )
    return ApiResponse(data=page)


@router.post("/groups", response_model=ApiResponse)
async def create_group(
    data: ProductGroupCreate,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    grp = await product_group_service.create_group(db, data)
    return ApiResponse(data=ProductGroupResponse.model_validate(grp))


@router.put("/groups/{group_id}", response_model=ApiResponse)
async def update_group(
    group_id: int,
    data: ProductGroupUpdate,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    grp = await product_group_service.update_group(db, group_id, data)
    return ApiResponse(data=ProductGroupResponse.model_validate(grp))


@router.put("/groups/{group_id}/verification-rule", response_model=ApiResponse)
async def update_group_verification_rule(
    group_id: int,
    data: ProductGroupVerificationRuleUpdate,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    result = await product_group_service.update_group_verification_rule(
        db,
        group_id,
        requires_real_name=data.requires_real_name,
        apply_to_products=data.apply_to_products,
    )
    return ApiResponse(data={
        "group": ProductGroupResponse.model_validate(result["group"]),
        "updated_products": result["updated_products"],
    })


@router.delete("/groups/{group_id}", response_model=ApiResponse)
async def delete_group(
    group_id: int,
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    await product_group_service.delete_group(db, group_id)
    return ApiResponse(data=None)
