from fastapi import APIRouter, Request, Query, Path, Body
from typing import Any, List, Dict, Union
from app.services.tjnetwork import (
    Any,
    ChangeSet,
    add_reservoir,
    delete_reservoir,
    get_all_reservoirs,
    get_reservoir,
    get_reservoir_schema,
    set_reservoir,
)

router = APIRouter()

@router.get(
    "/getreservoirschema",
    summary="获取水库模式",
    description="获取指定供水网络中所有水库的模式/属性字段定义"
)
async def fast_get_reservoir_schema(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> dict[str, dict[str, Any]]:
    """
    获取水库模式定义。
    
    该端点返回指定网络中水库对象的模式定义，包括所有可用的属性字段。
    
    Args:
        network: 管网名称（或数据库名称）
        
    Returns:
        水库属性的模式定义字典
    """
    return get_reservoir_schema(network)

@router.post(
    "/addreservoir/",
    response_model=None,
    summary="添加水库",
    description="在指定供水网络中添加新的水库/水源节点"
)
async def fastapi_add_reservoir(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    x: float = Query(..., description="水库的X坐标"),
    y: float = Query(..., description="水库的Y坐标"),
    head: float = Query(..., description="水库的水头/总水头（米）")
) -> ChangeSet:
    """
    添加新的水库/水源节点。
    
    在指定的供水网络中创建一个新的水库，并设置其坐标和水头参数。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        x: 水库的X坐标位置
        y: 水库的Y坐标位置
        head: 水库的供水水头（以米为单位）
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir, "x": x, "y": y, "head": head}
    return add_reservoir(network, ChangeSet(ps))

@router.post(
    "/deletereservoir/",
    response_model=None,
    summary="删除水库",
    description="从指定供水网络中删除指定的水库/水源节点"
)
async def fastapi_delete_reservoir(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="要删除的水库的唯一标识符")
) -> ChangeSet:
    """
    删除指定的水库节点。
    
    从指定的供水网络中删除一个水库及其相关的所有连接关系。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir}
    return delete_reservoir(network, ChangeSet(ps))

@router.get(
    "/getreservoirhead/",
    summary="获取水库水头",
    description="获取指定水库的供水水头/总水头值"
)
async def fastapi_get_reservoir_head(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符")
) -> float | None:
    """
    获取水库的水头参数。
    
    返回指定水库的供水水头（总水头），单位为米。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        水库的水头值（米），如果水库不存在则返回None
    """
    ps = get_reservoir(network, reservoir)
    return ps["head"]

@router.get(
    "/getreservoirpattern/",
    summary="获取水库模式",
    description="获取指定水库的运行模式/供水模式"
)
async def fastapi_get_reservoir_pattern(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符")
) -> str | None:
    """
    获取水库的运行模式。
    
    返回指定水库的供水模式，如固定水头模式、时间序列模式等。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        水库的运行模式字符串，如果水库不存在则返回None
    """
    ps = get_reservoir(network, reservoir)
    return ps["pattern"]

@router.get(
    "/getreservoirx/",
    summary="获取水库X坐标",
    description="获取指定水库的X坐标位置"
)
async def fastapi_get_reservoir_x(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符")
) -> dict[str, float] | None:
    """
    获取水库的X坐标。
    
    返回指定水库的X轴坐标值。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        水库的X坐标值，如果水库不存在则返回None
    """
    ps = get_reservoir(network, reservoir)
    return ps["x"]

@router.get(
    "/getreservoiry/",
    summary="获取水库Y坐标",
    description="获取指定水库的Y坐标位置"
)
async def fastapi_get_reservoir_y(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符")
) -> dict[str, float] | None:
    """
    获取水库的Y坐标。
    
    返回指定水库的Y轴坐标值。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        水库的Y坐标值，如果水库不存在则返回None
    """
    ps = get_reservoir(network, reservoir)
    return ps["y"]

@router.get(
    "/getreservoircoord/",
    summary="获取水库坐标",
    description="获取指定水库的平面坐标（X和Y坐标）"
)
async def fastapi_get_reservoir_coord(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符")
) -> dict[str, float] | None:
    """
    获取水库的坐标。
    
    返回指定水库的平面坐标，包含水库ID、X坐标和Y坐标。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        包含water库ID和X、Y坐标的字典，如果水库不存在则返回None
    """
    ps = get_reservoir(network, reservoir)
    coord = {"id": reservoir, "x": ps["x"], "y": ps["y"]}
    return coord

@router.post(
    "/setreservoirhead/",
    response_model=None,
    summary="设置水库水头",
    description="更新指定水库的供水水头/总水头值"
)
async def fastapi_set_reservoir_head(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    head: float = Query(..., description="新的水头值（米）")
) -> ChangeSet:
    """
    设置水库的水头参数。
    
    更新指定水库的供水水头（总水头）值。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        head: 新的水头值（以米为单位）
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir, "head": head}
    return set_reservoir(network, ChangeSet(ps))

@router.post(
    "/setreservoirpattern/",
    response_model=None,
    summary="设置水库模式",
    description="更新指定水库的运行模式/供水模式"
)
async def fastapi_set_reservoir_pattern(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    pattern: str = Query(..., description="新的运行模式")
) -> ChangeSet:
    """
    设置水库的运行模式。
    
    更新指定水库的供水模式，如固定水头模式、时间序列模式等。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        pattern: 新的运行模式字符串
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir, "pattern": pattern}
    return set_reservoir(network, ChangeSet(ps))

@router.post(
    "/setreservoirx/",
    response_model=None,
    summary="设置水库X坐标",
    description="更新指定水库的X坐标位置"
)
async def fastapi_set_reservoir_x(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    x: float = Query(..., description="新的X坐标值")
) -> ChangeSet:
    """
    设置水库的X坐标。
    
    更新指定水库的X轴坐标值。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        x: 新的X坐标值
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir, "x": x}
    return set_reservoir(network, ChangeSet(ps))

@router.post(
    "/setreservoiry/",
    response_model=None,
    summary="设置水库Y坐标",
    description="更新指定水库的Y坐标位置"
)
async def fastapi_set_reservoir_y(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    y: float = Query(..., description="新的Y坐标值")
) -> ChangeSet:
    """
    设置水库的Y坐标。
    
    更新指定水库的Y轴坐标值。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        y: 新的Y坐标值
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir, "y": y}
    return set_reservoir(network, ChangeSet(ps))

@router.post(
    "/setreservoircoord/",
    response_model=None,
    summary="设置水库坐标",
    description="更新指定水库的平面坐标（X和Y坐标）"
)
async def fastapi_set_reservoir_coord(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    x: float = Query(..., description="新的X坐标值"),
    y: float = Query(..., description="新的Y坐标值")
) -> ChangeSet:
    """
    设置水库的坐标。
    
    更新指定水库的平面坐标，包括X和Y坐标。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        x: 新的X坐标值
        y: 新的Y坐标值
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    ps = {"id": reservoir, "x": x, "y": y}
    return set_reservoir(network, ChangeSet(ps))

@router.get(
    "/getreservoirproperties/",
    summary="获取水库属性",
    description="获取指定水库的所有属性"
)
async def fastapi_get_reservoir_properties(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符")
) -> dict[str, Any]:
    """
    获取水库的所有属性。
    
    返回指定水库的完整属性信息，包括ID、坐标、水头、模式等所有属性。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        
    Returns:
        包含水库所有属性的字典
    """
    return get_reservoir(network, reservoir)

@router.get(
    "/getallreservoirproperties/",
    summary="获取所有水库属性",
    description="获取指定供水网络中所有水库的属性"
)
async def fastapi_get_all_reservoir_properties(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[dict[str, Any]]:
    """
    获取所有水库的属性。
    
    返回指定供水网络中所有水库的完整属性信息列表。
    
    Args:
        network: 管网名称（或数据库名称）
        
    Returns:
        包含所有水库属性的字典列表
    """
    results = get_all_reservoirs(network)
    return results

@router.post(
    "/setreservoirproperties/",
    response_model=None,
    summary="设置水库属性",
    description="批量更新指定水库的多个属性"
)
async def fastapi_set_reservoir_properties(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    reservoir: str = Query(..., description="水库的唯一标识符"),
    req: Request = None
) -> ChangeSet:
    """
    设置水库的多个属性。
    
    批量更新指定水库的属性。属性通过JSON请求体传递。
    
    Args:
        network: 管网名称（或数据库名称）
        reservoir: 水库的唯一标识符
        req: HTTP请求对象，包含JSON格式的属性数据
        
    Returns:
        包含操作变更集的ChangeSet对象
    """
    props = await req.json()
    ps = {"id": reservoir} | props
    return set_reservoir(network, ChangeSet(ps))
