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

from app.dependencies import get_db, get_admin_user, get_current_user
from app.models.user import User
from app.models.menu_config import MenuConfig
from app.schemas.menu import MenuConfigCreate, MenuConfigOut
from app.utils.id_gen import generate_id

router = APIRouter(tags=["menu-configs"])


@router.get("/menu-configs")
async def public_list_menu_configs(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Public endpoint: list active menu configs for frontend (frontend + both)."""
    result = await db.execute(
        select(MenuConfig)
        .where(
            MenuConfig.is_active == True,
            MenuConfig.menu_target.in_(["frontend", "both"]),
        )
        .order_by(MenuConfig.sort_order)
    )
    all_menus = result.scalars().all()
    
    # Filter menus based on user permissions
    # Show default menus + user-specific allowed menus (merged)
    user_allowed_paths = set(current_user.allowed_menus or [])
    
    # Start with default menus
    allowed_ids = set()
    for menu in all_menus:
        if menu.is_default:
            allowed_ids.add(menu.id)
            if menu.parent_id:
                allowed_ids.add(menu.parent_id)
    
    # Add user-specific allowed menus (merge with defaults)
    for menu in all_menus:
        if menu.path in user_allowed_paths:
            allowed_ids.add(menu.id)
            if menu.parent_id:
                allowed_ids.add(menu.parent_id)
    
    menus = [m for m in all_menus if m.id in allowed_ids]
    
    return [
        {
            "id": m.id, "label": m.label, "path": m.path, "icon": m.icon,
            "sort_order": m.sort_order, "is_active": m.is_active,
            "parent_id": m.parent_id, "menu_type": m.menu_type, "menu_target": m.menu_target,
            "is_default": m.is_default,
        }
        for m in menus
    ]


@router.get("/admin/menu-configs", response_model=list[MenuConfigOut])
async def admin_list_menu_configs(
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(select(MenuConfig).order_by(MenuConfig.sort_order))
    return result.scalars().all()


@router.post("/admin/menu-configs", response_model=MenuConfigOut)
async def create_menu_config(
    req: MenuConfigCreate,
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
):
    menu = MenuConfig(id=generate_id(), **req.model_dump())
    db.add(menu)
    await db.flush()
    return menu


@router.put("/admin/menu-configs/{menu_id}", response_model=MenuConfigOut)
async def update_menu_config(
    menu_id: str,
    req: MenuConfigCreate,
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(select(MenuConfig).where(MenuConfig.id == menu_id).limit(1))
    menu = result.scalar_one_or_none()
    if not menu:
        from fastapi import HTTPException, status
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="菜单不存在")
    for k, v in req.model_dump().items():
        setattr(menu, k, v)
    await db.flush()
    return menu


@router.delete("/admin/menu-configs/{menu_id}")
async def delete_menu_config(
    menu_id: str,
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(select(MenuConfig).where(MenuConfig.id == menu_id).limit(1))
    menu = result.scalar_one_or_none()
    if not menu:
        from fastapi import HTTPException, status
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="菜单不存在")
    await db.delete(menu)
    await db.flush()
    return {"message": "ok"}
