from fastapi import APIRouter, Request, Query, Path, Body
from typing import Any, List, Dict, Union
from app.services.tjnetwork import (
    Any,
    ChangeSet,
    VALVES_TYPE_PRV,
    add_valve,
    delete_valve,
    get_all_valves,
    get_valve,
    get_valve_schema,
    set_valve,
)

router = APIRouter()

@router.get(
    "/getvalveschema",
    summary="获取阀门架构",
    description="获取指定水网中所有阀门的架构和字段定义",
)
async def fastapi_get_valve_schema(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> dict[str, dict[str, Any]]:
    """
    获取阀门架构。
    
    返回指定水网中所有阀门类型的完整架构定义，包括字段名称、类型和默认值。
    """
    return get_valve_schema(network)

@router.post(
    "/addvalve/",
    response_model=None,
    summary="添加阀门",
    description="在指定的水网中添加新的阀门",
)
async def fastapi_add_valve(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    node1: str = Query(..., description="起点节点ID"),
    node2: str = Query(..., description="终点节点ID"),
    diameter: float = Query(0, description="阀门直径（mm）"),
    v_type: str = Query(VALVES_TYPE_PRV, description="阀门类型"),
    setting: float = Query(0, description="阀门开度/设置值"),
    minor_loss: float = Query(0, description="损失系数"),
) -> ChangeSet:
    """
    添加新的阀门。
    
    在指定的水网中创建一个新的阀门，设置其连接的两个节点、直径、类型、开度和损失系数。
    """
    ps = {
        "id": valve,
        "node1": node1,
        "node2": node2,
        "diameter": diameter,
        "v_type": v_type,
        "setting": setting,
        "minor_loss": minor_loss,
    }

    return add_valve(network, ChangeSet(ps))

@router.post(
    "/deletevalve/",
    response_model=None,
    summary="删除阀门",
    description="从指定的水网中删除指定的阀门",
)
async def fastapi_delete_valve(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> ChangeSet:
    """
    删除阀门。
    
    从指定的水网中删除指定ID的阀门。
    """
    ps = {"id": valve}
    return delete_valve(network, ChangeSet(ps))

@router.get(
    "/getvalvenode1/",
    summary="获取阀门起点节点",
    description="获取指定阀门连接的起点节点ID",
)
async def fastapi_get_valve_node1(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> str | None:
    """
    获取阀门的起点节点。
    
    返回指定阀门连接的起点（第一个）节点的ID。
    """
    ps = get_valve(network, valve)
    return ps["node1"]

@router.get(
    "/getvalvenode2/",
    summary="获取阀门终点节点",
    description="获取指定阀门连接的终点节点ID",
)
async def fastapi_get_valve_node2(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> str | None:
    """
    获取阀门的终点节点。
    
    返回指定阀门连接的终点（第二个）节点的ID。
    """
    ps = get_valve(network, valve)
    return ps["node2"]

@router.get(
    "/getvalvediameter/",
    summary="获取阀门直径",
    description="获取指定阀门的直径",
)
async def fastapi_get_valve_diameter(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> float | None:
    """
    获取阀门的直径。
    
    返回指定阀门的直径值（单位：mm）。
    """
    ps = get_valve(network, valve)
    return ps["diameter"]

@router.get(
    "/getvalvetype/",
    summary="获取阀门类型",
    description="获取指定阀门的类型",
)
async def fastapi_get_valve_type(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> str | None:
    """
    获取阀门的类型。
    
    返回指定阀门的类型（例如：减压阀、调节阀等）。
    """
    ps = get_valve(network, valve)
    return ps["type"]

@router.get(
    "/getvalvesetting/",
    summary="获取阀门开度",
    description="获取指定阀门的开度/设置值",
)
async def fastapi_get_valve_setting(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> float | None:
    """
    获取阀门的开度。
    
    返回指定阀门的开度/设置值。
    """
    ps = get_valve(network, valve)
    return ps["setting"]

@router.get(
    "/getvalveminorloss/",
    summary="获取阀门损失系数",
    description="获取指定阀门的损失系数",
)
async def fastapi_get_valve_minor_loss(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> float | None:
    """
    获取阀门的损失系数。
    
    返回指定阀门的损失系数值，用于计算流体通过阀门的压力损失。
    """
    ps = get_valve(network, valve)
    return ps["minor_loss"]

@router.post(
    "/setvalvenode1/",
    response_model=None,
    summary="设置阀门起点节点",
    description="设置指定阀门的起点节点",
)
async def fastapi_set_valve_node1(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    node1: str = Query(..., description="新的起点节点ID"),
) -> ChangeSet:
    """
    设置阀门的起点节点。
    
    更新指定阀门的起点节点连接。
    """
    ps = {"id": valve, "node1": node1}
    return set_valve(network, ChangeSet(ps))

@router.post(
    "/setvalvenode2/",
    response_model=None,
    summary="设置阀门终点节点",
    description="设置指定阀门的终点节点",
)
async def fastapi_set_valve_node2(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    node2: str = Query(..., description="新的终点节点ID"),
) -> ChangeSet:
    """
    设置阀门的终点节点。
    
    更新指定阀门的终点节点连接。
    """
    ps = {"id": valve, "node2": node2}
    return set_valve(network, ChangeSet(ps))

@router.post(
    "/setvalvenodediameter/",
    response_model=None,
    summary="设置阀门直径",
    description="设置指定阀门的直径",
)
async def fastapi_set_valve_diameter(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    diameter: float = Query(..., description="新的直径值（mm）"),
) -> ChangeSet:
    """
    设置阀门的直径。
    
    更新指定阀门的直径值。
    """
    ps = {"id": valve, "diameter": diameter}
    return set_valve(network, ChangeSet(ps))

@router.post(
    "/setvalvetype/",
    response_model=None,
    summary="设置阀门类型",
    description="设置指定阀门的类型",
)
async def fastapi_set_valve_type(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    type: str = Query(..., description="新的阀门类型"),
) -> ChangeSet:
    """
    设置阀门的类型。
    
    更新指定阀门的类型（例如：减压阀、调节阀等）。
    """
    ps = {"id": valve, "type": type}
    return set_valve(network, ChangeSet(ps))

@router.post(
    "/setvalvesetting/",
    response_model=None,
    summary="设置阀门开度",
    description="设置指定阀门的开度/设置值",
)
async def fastapi_set_valve_setting(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    setting: float = Query(..., description="新的开度值"),
) -> ChangeSet:
    """
    设置阀门的开度。
    
    更新指定阀门的开度/设置值。
    """
    ps = {"id": valve, "setting": setting}
    return set_valve(network, ChangeSet(ps))

@router.get(
    "/getvalveproperties/",
    summary="获取阀门所有属性",
    description="获取指定阀门的所有属性",
)
async def fastapi_get_valve_properties(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
) -> dict[str, Any]:
    """
    获取阀门的所有属性。
    
    返回指定阀门的完整属性集合，包括ID、节点、直径、类型、开度和损失系数。
    """
    return get_valve(network, valve)

@router.get(
    "/getallvalveproperties/",
    summary="获取所有阀门属性",
    description="获取指定水网中所有阀门的属性",
)
async def fastapi_get_all_valve_properties(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[dict[str, Any]]:
    """
    获取所有阀门的属性。
    
    返回指定水网中所有阀门的完整属性列表。
    """
    # 缓存查询结果提高性能
    # global redis_client
    results = get_all_valves(network)
    return results

@router.post(
    "/setvalveproperties/",
    response_model=None,
    summary="批量设置阀门属性",
    description="批量设置指定阀门的多个属性",
)
async def fastapi_set_valve_properties(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    valve: str = Query(..., description="阀门ID"),
    req: Request = None,
) -> ChangeSet:
    """
    批量设置阀门的属性。
    
    更新指定阀门的一个或多个属性，通过JSON请求体传递要更新的属性。
    """
    props = await req.json()
    ps = {"id": valve} | props
    return set_valve(network, ChangeSet(ps))
