from fastapi import APIRouter, Request, Query, Path, Body
from typing import Any, List, Dict, Union
from app.services.tjnetwork import (
    Any,
    ChangeSet,
    add_district_metering_area,
    add_region,
    add_service_area,
    add_virtual_district,
    # calculate_district_metering_area,
    calculate_district_metering_area_for_network,
    calculate_district_metering_area_for_nodes,
    calculate_district_metering_area_for_region,
    # calculate_region,
    calculate_service_area,
    calculate_virtual_district,
    delete_district_metering_area,
    delete_region,
    delete_service_area,
    delete_virtual_district,
    generate_district_metering_area,
    # generate_region,
    generate_service_area,
    generate_sub_district_metering_area,
    generate_virtual_district,
    get_all_district_metering_area_ids,
    get_all_district_metering_areas,
    # get_all_regions,
    get_all_service_areas,
    get_all_virtual_districts,
    get_district_metering_area,
    get_district_metering_area_schema,
    get_region,
    get_region_schema,
    get_service_area,
    get_service_area_schema,
    get_virtual_district,
    get_virtual_district_schema,
    set_district_metering_area,
    set_region,
    set_service_area,
    set_virtual_district,
)

router = APIRouter()

############################################################
# region 32
############################################################

@router.get(
    "/calculateregion/",
    summary="计算区域",
    description="计算指定水网在指定时间步长的区域分区"
)
async def fastapi_calculate_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    time_index: int = Query(..., description="时间步长索引", ge=0)
) -> dict[str, Any]:
    """计算区域分区。"""
    return calculate_region(network, time_index)

@router.get(
    "/getregionschema/",
    summary="获取区域属性架构",
    description="获取指定水网的区域属性架构定义"
)
async def fastapi_get_region_schema(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> dict[str, dict[str, Any]]:
    """获取区域的属性架构。"""
    return get_region_schema(network)

@router.get(
    "/getregion/",
    summary="获取区域信息",
    description="获取指定ID的区域详细信息"
)
async def fastapi_get_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    id: str = Query(..., description="区域ID")
) -> dict[str, Any]:
    """获取区域的详细信息。"""
    return get_region(network, id)

@router.post(
    "/setregion/",
    response_model=None,
    summary="设置区域属性",
    description="修改指定区域的属性信息"
)
async def fastapi_set_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """设置区域属性。"""
    props = await req.json()
    return set_region(network, ChangeSet(props))

@router.post(
    "/addregion/",
    response_model=None,
    summary="添加新区域",
    description="向水网添加一个新的区域"
)
async def fastapi_add_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """添加新的区域。"""
    props = await req.json()
    return add_region(network, ChangeSet(props))

@router.post(
    "/deleteregion/",
    response_model=None,
    summary="删除区域",
    description="删除指定的区域"
)
async def fastapi_delete_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """删除区域。"""
    props = await req.json()
    return delete_region(network, ChangeSet(props))

@router.get(
    "/getallregions/",
    summary="获取所有区域",
    description="获取指定水网中的所有区域信息"
)
async def fastapi_get_all_regions(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[dict[str, Any]]:
    """获取所有区域的信息列表。"""
    return get_all_regions(network)

@router.post(
    "/generateregion/",
    response_model=None,
    summary="生成区域分区",
    description="根据参数自动生成水网的区域分区"
)
async def fastapi_generate_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    inflate_delta: float = Query(..., description="膨胀参数")
) -> ChangeSet:
    """生成区域分区。"""
    return generate_region(network, inflate_delta)


############################################################
# district_metering_area 33
############################################################

@router.get(
    "/calculatedistrictmeteringarea/",
    summary="计算DMA分区",
    description="计算指定节点集的区域计量(DMA)分区方案"
)
async def fastapi_calculate_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> list[list[str]]:
    """
    计算DMA分区。
    
    请求体格式:
    {
        "nodes": 节点ID列表(list[str]),
        "part_count": 分区数量(int),
        "part_type": 分区类型(int)
    }
    """
    props = await req.json()
    nodes = props["nodes"]
    part_count = props["part_count"]
    part_type = props["part_type"]
    return calculate_district_metering_area(
        network, nodes, part_count, part_type
    )

@router.get(
    "/calculatedistrictmeteringareaforregion/",
    summary="计算区域内DMA分区",
    description="为指定区域计算区域计量(DMA)分区方案"
)
async def fastapi_calculate_district_metering_area_for_region(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> list[list[str]]:
    """
    计算区域内DMA分区。
    
    请求体格式:
    {
        "region": 区域ID(str),
        "part_count": 分区数量(int),
        "part_type": 分区类型(int)
    }
    """
    props = await req.json()
    region = props["region"]
    part_count = props["part_count"]
    part_type = props["part_type"]
    return calculate_district_metering_area_for_region(
        network, region, part_count, part_type
    )

@router.get(
    "/calculatedistrictmeteringareafornetwork/",
    summary="计算整网DMA分区",
    description="为整个水网计算区域计量(DMA)分区方案"
)
async def fastapi_calculate_district_metering_area_for_network(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> list[list[str]]:
    """
    计算整网DMA分区。
    
    请求体格式:
    {
        "part_count": 分区数量(int),
        "part_type": 分区类型(int)
    }
    """
    props = await req.json()
    part_count = props["part_count"]
    part_type = props["part_type"]
    return calculate_district_metering_area_for_network(network, part_count, part_type)

@router.get(
    "/getdistrictmeteringareaschema/",
    summary="获取DMA属性架构",
    description="获取指定水网的区域计量(DMA)属性架构定义"
)
async def fastapi_get_district_metering_area_schema(
    network: str = Query(..., description="管网名称（或数据库名称）"),
) -> dict[str, dict[str, Any]]:
    """获取DMA的属性架构。"""
    return get_district_metering_area_schema(network)

@router.get(
    "/getdistrictmeteringarea/",
    summary="获取DMA信息",
    description="获取指定ID的区域计量(DMA)详细信息"
)
async def fastapi_get_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    id: str = Query(..., description="DMA ID")
) -> dict[str, Any]:
    """获取DMA的详细信息。"""
    return get_district_metering_area(network, id)

@router.post(
    "/setdistrictmeteringarea/",
    response_model=None,
    summary="设置DMA属性",
    description="修改指定DMA的属性信息"
)
async def fastapi_set_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """设置DMA属性。"""
    props = await req.json()
    return set_district_metering_area(network, ChangeSet(props))

@router.post(
    "/adddistrictmeteringarea/",
    response_model=None,
    summary="添加新DMA",
    description="向水网添加一个新的区域计量(DMA)"
)
async def fastapi_add_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """添加新的DMA。"""
    props = await req.json()
    # boundary should be [(x,y), (x,y)]
    boundary = props.get("boundary", [])
    newBoundary = []
    for pt in boundary:
        if len(pt) >= 2:
            newBoundary.append((pt[0], pt[1]))
    props["boundary"] = newBoundary
    return add_district_metering_area(network, ChangeSet(props))

@router.post(
    "/deletedistrictmeteringarea/",
    response_model=None,
    summary="删除DMA",
    description="删除指定的区域计量(DMA)"
)
async def fastapi_delete_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """删除DMA。"""
    props = await req.json()
    return delete_district_metering_area(network, ChangeSet(props))

@router.get(
    "/getalldistrictmeteringareaids/",
    summary="获取所有DMA ID",
    description="获取指定水网中所有DMA的ID列表"
)
async def fastapi_get_all_district_metering_area_ids(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[str]:
    """获取所有DMA的ID列表。"""
    return get_all_district_metering_area_ids(network)

@router.get(
    "/getalldistrictmeteringareas/",
    summary="获取所有DMA",
    description="获取指定水网中所有DMA的详细信息"
)
async def getalldistrictmeteringareas(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[dict[str, Any]]:
    """获取所有DMA的详细信息列表。"""
    return get_all_district_metering_areas(network)

@router.post(
    "/generatedistrictmeteringarea/",
    response_model=None,
    summary="生成DMA分区",
    description="根据参数自动生成水网的DMA分区方案"
)
async def fastapi_generate_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    part_count: int = Query(..., description="分区数量", gt=0),
    part_type: int = Query(..., description="分区类型"),
    inflate_delta: float = Query(..., description="膨胀参数")
) -> ChangeSet:
    """生成DMA分区。"""
    return generate_district_metering_area(
        network, part_count, part_type, inflate_delta
    )

@router.post(
    "/generatesubdistrictmeteringarea/",
    response_model=None,
    summary="生成DMA子分区",
    description="为指定DMA生成子DMA分区"
)
async def fastapi_generate_sub_district_metering_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    dma: str = Query(..., description="DMA ID"),
    part_count: int = Query(..., description="分区数量", gt=0),
    part_type: int = Query(..., description="分区类型"),
    inflate_delta: float = Query(..., description="膨胀参数")
) -> ChangeSet:
    """生成DMA子分区。"""
    return generate_sub_district_metering_area(
        network, dma, part_count, part_type, inflate_delta
    )


############################################################
# service_area 34
############################################################

@router.get(
    "/calculateservicearea/",
    summary="计算服务区",
    description="计算指定水网在指定时间步长的服务区分区"
)
async def fastapi_calculate_service_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    time_index: int = Query(..., description="时间步长索引", ge=0)
) -> dict[str, Any]:
    """计算服务区分区。"""
    return calculate_service_area(network, time_index)

@router.get(
    "/getserviceareaschema/",
    summary="获取服务区属性架构",
    description="获取指定水网的服务区属性架构定义"
)
async def fastapi_get_service_area_schema(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> dict[str, dict[str, Any]]:
    """获取服务区的属性架构。"""
    return get_service_area_schema(network)

@router.get(
    "/getservicearea/",
    summary="获取服务区信息",
    description="获取指定ID的服务区详细信息"
)
async def fastapi_get_service_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    id: str = Query(..., description="服务区ID")
) -> dict[str, Any]:
    """获取服务区的详细信息。"""
    return get_service_area(network, id)

@router.post(
    "/setservicearea/",
    response_model=None,
    summary="设置服务区属性",
    description="修改指定服务区的属性信息"
)
async def fastapi_set_service_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """设置服务区属性。"""
    props = await req.json()
    return set_service_area(network, ChangeSet(props))

@router.post(
    "/addservicearea/",
    response_model=None,
    summary="添加新服务区",
    description="向水网添加一个新的服务区"
)
async def fastapi_add_service_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """添加新的服务区。"""
    props = await req.json()
    return add_service_area(network, ChangeSet(props))

@router.post(
    "/deleteservicearea/",
    response_model=None,
    summary="删除服务区",
    description="删除指定的服务区"
)
async def fastapi_delete_service_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """删除服务区。"""
    props = await req.json()
    return delete_service_area(network, ChangeSet(props))

@router.get(
    "/getallserviceareas/",
    summary="获取所有服务区",
    description="获取指定水网中的所有服务区信息"
)
async def fastapi_get_all_service_areas(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[dict[str, Any]]:
    """获取所有服务区的信息列表。"""
    return get_all_service_areas(network)

@router.post(
    "/generateservicearea/",
    response_model=None,
    summary="生成服务区分区",
    description="根据参数自动生成水网的服务区分区"
)
async def fastapi_generate_service_area(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    inflate_delta: float = Query(..., description="膨胀参数")
) -> ChangeSet:
    """生成服务区分区。"""
    return generate_service_area(network, inflate_delta)


############################################################
# virtual_district 35
############################################################

@router.get(
    "/calculatevirtualdistrict/",
    summary="计算虚拟分区",
    description="根据指定的中心节点计算虚拟分区方案"
)
async def fastapi_calculate_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    centers: list[str] = Query(..., description="中心节点ID列表")
) -> dict[str, list[Any]]:
    """计算虚拟分区。"""
    return calculate_virtual_district(network, centers)

@router.get(
    "/getvirtualdistrictschema/",
    summary="获取虚拟分区属性架构",
    description="获取指定水网的虚拟分区属性架构定义"
)
async def fastapi_get_virtual_district_schema(
    network: str = Query(..., description="管网名称（或数据库名称）"),
) -> dict[str, dict[str, Any]]:
    """获取虚拟分区的属性架构。"""
    return get_virtual_district_schema(network)

@router.get(
    "/getvirtualdistrict/",
    summary="获取虚拟分区信息",
    description="获取指定ID的虚拟分区详细信息"
)
async def fastapi_get_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    id: str = Query(..., description="虚拟分区ID")
) -> dict[str, Any]:
    """获取虚拟分区的详细信息。"""
    return get_virtual_district(network, id)

@router.post(
    "/setvirtualdistrict/",
    response_model=None,
    summary="设置虚拟分区属性",
    description="修改指定虚拟分区的属性信息"
)
async def fastapi_set_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """设置虚拟分区属性。"""
    props = await req.json()
    return set_virtual_district(network, ChangeSet(props))

@router.post(
    "/addvirtualdistrict/",
    response_model=None,
    summary="添加新虚拟分区",
    description="向水网添加一个新的虚拟分区"
)
async def fastapi_add_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """添加新的虚拟分区。"""
    props = await req.json()
    return add_virtual_district(network, ChangeSet(props))

@router.post(
    "/deletevirtualdistrict/",
    response_model=None,
    summary="删除虚拟分区",
    description="删除指定的虚拟分区"
)
async def fastapi_delete_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> ChangeSet:
    """删除虚拟分区。"""
    props = await req.json()
    return delete_virtual_district(network, ChangeSet(props))

@router.get(
    "/getallvirtualdistrict/",
    summary="获取所有虚拟分区",
    description="获取指定水网中的所有虚拟分区信息"
)
async def fastapi_get_all_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）")
) -> list[dict[str, Any]]:
    """获取所有虚拟分区的信息列表。"""
    return get_all_virtual_districts(network)

@router.post(
    "/generatevirtualdistrict/",
    response_model=None,
    summary="生成虚拟分区",
    description="根据参数自动生成虚拟分区方案"
)
async def fastapi_generate_virtual_district(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    inflate_delta: float = Query(..., description="膨胀参数"),
    req: Request = None
) -> ChangeSet:
    """生成虚拟分区。"""
    props = await req.json()
    return generate_virtual_district(network, props["centers"], inflate_delta)

@router.get(
    "/calculatedistrictmeteringareafornodes/",
    summary="计算节点DMA分区",
    description="为指定节点集计算区域计量(DMA)分区方案"
)
async def fastapi_calculate_district_metering_area_for_nodes(
    network: str = Query(..., description="管网名称（或数据库名称）"),
    req: Request = None
) -> list[list[str]]:
    """
    计算节点DMA分区。
    
    请求体格式:
    {
        "nodes": 节点ID列表(list[str]),
        "part_count": 分区数量(int),
        "part_type": 分区类型(int)
    }
    """
    props = await req.json()
    nodes = props["nodes"]
    part_count = props["part_count"]
    part_type = props["part_type"]
    return calculate_district_metering_area_for_nodes(
        network, nodes, part_count, part_type
    )
