from fastapi import APIRouter, Request, Depends
from typing import Any, List, Dict, Union
from app.services.tjnetwork import (
    Any,
    get_all_scada_info,
    get_major_node_coords,
    get_major_pipe_nodes,
    get_network_in_extent,
    get_network_link_nodes,
    get_network_node_coords,
    get_node_coord,
)
from app.auth.dependencies import get_current_user as verify_token
from app.infra.cache.redis_client import redis_client, encode_datetime, decode_datetime
import msgpack

router = APIRouter()

############################################################
# coord 24.[COORDINATES]
############################################################

# @router.get("/getcoordschema/")
# async def fastapi_get_coord_schema(network: str) -> dict[str, dict[str, Any]]:
#     return get_coord_schema(network)

# @router.get("/getcoord/")
# async def fastapi_get_coord(network: str, node: str) -> dict[str, Any]:
#     return get_coord(network, node)

# # example: set_coord(p, ChangeSet({'node': 'j1', 'x': 1.0, 'y': 2.0}))
# @router.post("/setcoord/", response_model=None)
# async def fastapi_set_coord(network: str, req: Request) -> ChangeSet:
#     props = await req.json()
#     return set_coord(network, ChangeSet(props))

@router.get("/getnodecoord/")
async def fastapi_get_node_coord(network: str, node: str) -> dict[str, float] | None:
    return get_node_coord(network, node)

# Additional geometry queries found in main.py logic (implicit or explicit)
@router.get("/getnetworkinextent/")
async def fastapi_get_network_in_extent(
    network: str, x1: float, y1: float, x2: float, y2: float
) -> dict[str, Any]:
    return get_network_in_extent(network, x1, y1, x2, y2)

@router.get("/getnetworkgeometries/", dependencies=[Depends(verify_token)])
async def fastapi_get_network_geometries(network: str) -> dict[str, Any] | None:
    cache_key = f"getnetworkgeometries_{network}"
    data = redis_client.get(cache_key)
    if data:
        loaded_dict = msgpack.unpackb(data, object_hook=decode_datetime)
        return loaded_dict

    coords = get_network_node_coords(network)
    nodes = []
    for node_id, coord in coords.items():
        nodes.append(f"{node_id}:{coord['type']}:{coord['x']}:{coord['y']}")
    links = get_network_link_nodes(network)
    scadas = get_all_scada_info(network)

    results = {"nodes": nodes, "links": links, "scadas": scadas}
    redis_client.set(cache_key, msgpack.packb(results, default=encode_datetime))
    return results

@router.get("/getmajornodecoords/")
async def fastapi_get_majornode_coords(
    network: str, diameter: int
) -> dict[str, dict[str, float]]:
    return get_major_node_coords(network, diameter)

@router.get("/getmajorpipenodes/")
async def fastapi_get_major_pipe_nodes(network: str, diameter: int) -> list[str] | None:
    return get_major_pipe_nodes(network, diameter)

@router.get("/getnetworklinknodes/")
async def fastapi_get_network_link_nodes(network: str) -> list[str] | None:
    return get_network_link_nodes(network)

# @router.get("/getallcoords/")
# async def fastapi_get_all_coords(network: str) -> list[Any]:
#     return get_all_coords(network)

# @router.get("/projectcoordinates/")
# async def fastapi_project_coordinates(
#     network: str, from_epsg: int, to_epsg: int
# ) -> ChangeSet:
#     return project_coordinates(network, from_epsg, to_epsg)
