"""
System Functions API
系統功能明細 CRUD API
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_

from app.db.session import get_db
from app.models.system_function import SystemFunction
from app.schemas.system_function import (
    SystemFunctionCreate,
    SystemFunctionUpdate,
    SystemFunctionResponse,
    SystemFunctionListResponse
)
from app.api.deps import get_pagination_params
from app.schemas.base import PaginationParams

router = APIRouter()


@router.get("", response_model=SystemFunctionListResponse)
def get_system_functions(
    function_type: Optional[int] = Query(None, description="功能類型 (1:node, 2:function)"),
    upper_function_id: Optional[int] = Query(None, description="上層功能代碼"),
    is_mana: Optional[bool] = Query(None, description="系統管理"),
    is_active: Optional[bool] = Query(None, description="啟用（預設顯示全部）"),
    search: Optional[str] = Query(None, description="搜尋 (code or name)"),
    pagination: PaginationParams = Depends(get_pagination_params),
    db: Session = Depends(get_db),
):
    """
    取得系統功能列表
    
    - 支援分頁
    - 支援篩選 (function_type, upper_function_id, is_mana, is_active)
    - 支援搜尋 (code or name)
    """
    query = db.query(SystemFunction)
    
    # 篩選條件
    filters = []
    if function_type is not None:
        filters.append(SystemFunction.function_type == function_type)
    if upper_function_id is not None:
        filters.append(SystemFunction.upper_function_id == upper_function_id)
    if is_mana is not None:
        filters.append(SystemFunction.is_mana == is_mana)
    if is_active is not None:
        filters.append(SystemFunction.is_active == is_active)
    
    # 搜尋
    if search:
        filters.append(
            or_(
                SystemFunction.code.ilike(f"%{search}%"),
                SystemFunction.name.ilike(f"%{search}%")
            )
        )
    
    if filters:
        query = query.filter(and_(*filters))
    
    # 排序 (依照 order 排序)
    query = query.order_by(SystemFunction.order.asc())
    
    # 計算總數
    total = query.count()
    
    # 分頁
    offset = (pagination.page - 1) * pagination.page_size
    items = query.offset(offset).limit(pagination.page_size).all()
    
    return SystemFunctionListResponse(
        total=total,
        items=items,
        page=pagination.page,
        page_size=pagination.page_size
    )


@router.get("/{function_id}", response_model=SystemFunctionResponse)
def get_system_function(
    function_id: int,
    db: Session = Depends(get_db),
):
    """
    取得單一系統功能
    """
    function = db.query(SystemFunction).filter(SystemFunction.id == function_id).first()
    
    if not function:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"System function not found: {function_id}"
        )
    
    return function


@router.post("", response_model=SystemFunctionResponse, status_code=status.HTTP_201_CREATED)
def create_system_function(
    function_in: SystemFunctionCreate,
    db: Session = Depends(get_db),
):
    """
    建立系統功能
    
    驗證規則:
    - function_type=1 (node) 時, module_code 不能輸入
    - function_type=2 (function) 時, module_code 和 module_functions 為必填
    - upper_function_id 必須是 function_type=1 且 is_active=1 的功能, 或 0 (初始層)
    """
    # 驗證 upper_function_id
    if function_in.upper_function_id > 0:
        parent = db.query(SystemFunction).filter(
            SystemFunction.id == function_in.upper_function_id,
            SystemFunction.function_type == 1,
            SystemFunction.is_active == True
        ).first()
        
        if not parent:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"Invalid upper_function_id: {function_in.upper_function_id} "
                       "(must be function_type=1 and is_active=1)"
            )
    
    # 檢查 code 是否重複
    existing = db.query(SystemFunction).filter(SystemFunction.code == function_in.code).first()
    if existing:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"System function code already exists: {function_in.code}"
        )
    
    # 建立資料
    db_function = SystemFunction(**function_in.model_dump())
    db.add(db_function)
    db.commit()
    db.refresh(db_function)
    
    return db_function


@router.put("/{function_id}", response_model=SystemFunctionResponse)
def update_system_function(
    function_id: int,
    function_in: SystemFunctionUpdate,
    db: Session = Depends(get_db),
):
    """
    更新系統功能 (完整更新)
    """
    # 查詢現有資料
    db_function = db.query(SystemFunction).filter(SystemFunction.id == function_id).first()
    
    if not db_function:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"System function not found: {function_id}"
        )
    
    # 更新資料
    update_data = function_in.model_dump(exclude_unset=True)
    
    for field, value in update_data.items():
        setattr(db_function, field, value)
    
    db.commit()
    db.refresh(db_function)
    
    return db_function


@router.patch("/{function_id}", response_model=SystemFunctionResponse)
def patch_system_function(
    function_id: int,
    function_in: SystemFunctionUpdate,
    db: Session = Depends(get_db),
):
    """
    更新系統功能 (部分更新)
    """
    return update_system_function(function_id, function_in, db)


@router.delete("/{function_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_system_function(
    function_id: int,
    db: Session = Depends(get_db),
):
    """
    刪除系統功能 (實際上是軟刪除, 設定 is_active=False)
    """
    db_function = db.query(SystemFunction).filter(SystemFunction.id == function_id).first()
    
    if not db_function:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"System function not found: {function_id}"
        )
    
    # 軟刪除
    db_function.is_active = False
    db.commit()
    
    return None


@router.delete("/{function_id}/hard", status_code=status.HTTP_204_NO_CONTENT)
def hard_delete_system_function(
    function_id: int,
    db: Session = Depends(get_db),
):
    """
    永久刪除系統功能 (硬刪除)

    ⚠️ 警告: 此操作無法復原
    """
    db_function = db.query(SystemFunction).filter(SystemFunction.id == function_id).first()

    if not db_function:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"System function not found: {function_id}"
        )

    # 硬刪除
    db.delete(db_function)
    db.commit()

    return None


@router.get("/menu/tree", response_model=List[dict])
def get_menu_tree(
    is_sysmana: bool = Query(False, description="是否為系統管理公司"),
    db: Session = Depends(get_db),
):
    """
    取得功能列表樹狀結構 (用於前端選單顯示)

    根據 is_sysmana 過濾功能:
    - is_sysmana=true: 返回所有功能 (包含 is_mana=true 的系統管理功能)
    - is_sysmana=false: 只返回 is_mana=false 的一般功能

    返回格式:
    [
        {
            "id": 10,
            "code": "system_managements",
            "name": "系統管理後台",
            "function_type": 1,
            "order": 100,
            "function_icon": "",
            "module_code": null,
            "module_functions": [],
            "children": [
                {
                    "id": 11,
                    "code": "system_settings",
                    "name": "系統資料設定",
                    "function_type": 2,
                    ...
                }
            ]
        }
    ]
    """
    # 查詢條件
    query = db.query(SystemFunction).filter(SystemFunction.is_active == True)

    # 如果不是系統管理公司,過濾掉 is_mana=true 的功能
    if not is_sysmana:
        query = query.filter(SystemFunction.is_mana == False)

    # 排序
    functions = query.order_by(SystemFunction.order.asc()).all()

    # 建立樹狀結構
    def build_tree(parent_id: int = 0) -> List[dict]:
        tree = []
        for func in functions:
            if func.upper_function_id == parent_id:
                node = {
                    "id": func.id,
                    "code": func.code,
                    "name": func.name,
                    "function_type": func.function_type,
                    "order": func.order,
                    "function_icon": func.function_icon or "",
                    "module_code": func.module_code,
                    "module_functions": func.module_functions or [],
                    "description": func.description or "",
                    "children": build_tree(func.id) if func.function_type == 1 else []
                }
                tree.append(node)
        return tree

    return build_tree(0)
