from fastapi import APIRouter, Request, Query
from app.services.tjnetwork import (
    ChangeSet,
    get_current_operation,
    execute_undo,
    execute_redo,
    list_snapshot,
    have_snapshot,
    have_snapshot_for_operation,
    have_snapshot_for_current_operation,
    take_snapshot_for_operation,
    take_snapshot_for_current_operation,
    take_snapshot,
    pick_snapshot,
    pick_operation,
    sync_with_server,
    execute_batch_commands,
    execute_batch_command,
    get_restore_operation,
    set_restore_operation,
)

router = APIRouter()

@router.get("/getcurrentoperationid/", summary="获取当前操作ID", description="获取网络当前的操作ID")
async def get_current_operation_id_endpoint(network: str = Query(..., description="管网名称（或数据库名称）")) -> int:
    """
    获取当前操作ID
    
    返回网络当前正在执行的操作ID
    """
    return get_current_operation(network)

@router.post("/undo/", summary="撤销操作", description="撤销网络上最后的一个操作")
async def undo_endpoint(network: str = Query(..., description="管网名称（或数据库名称）")):
    """
    撤销操作
    
    撤销网络上最近执行的一个操作
    """
    return execute_undo(network)

@router.post("/redo/", summary="重做操作", description="重做网络上被撤销的操作")
async def redo_endpoint(network: str = Query(..., description="管网名称（或数据库名称）")):
    """
    重做操作
    
    重做网络上被撤销的操作
    """
    return execute_redo(network)

@router.get("/getsnapshots/", summary="获取快照列表", description="获取网络中的所有快照")
async def list_snapshot_endpoint(network: str = Query(..., description="管网名称（或数据库名称）")) -> list[tuple[int, str]]:
    """
    获取快照列表
    
    返回网络中所有可用的快照及其信息
    """
    return list_snapshot(network)

@router.get("/havesnapshot/", summary="检查快照是否存在", description="检查指定标签的快照是否存在")
async def have_snapshot_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), tag: str = Query(..., description="快照标签")) -> bool:
    """
    检查快照是否存在
    
    返回指定标签的快照是否存在
    """
    return have_snapshot(network, tag)

@router.get("/havesnapshotforoperation/", summary="检查操作快照是否存在", description="检查指定操作ID的快照是否存在")
async def have_snapshot_for_operation_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), operation: int = Query(..., description="操作ID")) -> bool:
    """
    检查操作快照是否存在
    
    返回指定操作ID的快照是否存在
    """
    return have_snapshot_for_operation(network, operation)

@router.get("/havesnapshotforcurrentoperation/", summary="检查当前操作快照是否存在", description="检查当前操作的快照是否存在")
async def have_snapshot_for_current_operation_endpoint(network: str = Query(..., description="管网名称（或数据库名称）")) -> bool:
    """
    检查当前操作快照是否存在
    
    返回当前操作的快照是否存在
    """
    return have_snapshot_for_current_operation(network)

@router.post("/takesnapshotforoperation/", summary="为操作创建快照", description="为指定的操作创建快照")
async def take_snapshot_for_operation_endpoint(
    network: str = Query(..., description="管网名称（或数据库名称）"), 
    operation: int = Query(..., description="操作ID"), 
    tag: str = Query(..., description="快照标签")
) -> None:
    """
    为操作创建快照
    
    为指定操作创建一个带标签的快照
    """
    return take_snapshot_for_operation(network, operation, tag)

@router.post("/takesnapshotforcurrentoperation", summary="为当前操作创建快照", description="为当前操作创建快照")
async def take_snapshot_for_current_operation_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), tag: str = Query(..., description="快照标签")) -> None:
    """
    为当前操作创建快照
    
    为网络当前操作创建一个快照
    """
    return take_snapshot_for_current_operation(network, tag)

# 兼容旧拼写: takenapshotforcurrentoperation
@router.post("/takenapshotforcurrentoperation", summary="为当前操作创建快照（兼容模式）", description="为当前操作创建快照（兼容旧的API路径）")
async def take_snapshot_for_current_operation_legacy_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), tag: str = Query(..., description="快照标签")) -> None:
    """
    为当前操作创建快照（兼容模式）
    
    兼容旧的API路径，为网络当前操作创建一个快照
    """
    return take_snapshot_for_current_operation(network, tag)

@router.post("/takesnapshot/", summary="创建快照", description="为网络创建一个快照")
async def take_snapshot_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), tag: str = Query(..., description="快照标签")) -> None:
    """
    创建快照
    
    为网络创建一个带标签的快照
    """
    return take_snapshot(network, tag)

@router.post("/picksnapshot/", summary="选择快照", description="选择并恢复到指定的快照", response_model=None)
async def pick_snapshot_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), tag: str = Query(..., description="快照标签"), discard: bool = Query(False, description="是否丢弃当前更改")) -> ChangeSet:
    """
    选择快照
    
    选择并恢复到指定的快照
    """
    return pick_snapshot(network, tag, discard)

@router.post("/pickoperation/", summary="选择操作", description="选择并恢复到指定的操作", response_model=None)
async def pick_operation_endpoint(
    network: str = Query(..., description="管网名称（或数据库名称）"), 
    operation: int = Query(..., description="操作ID"), 
    discard: bool = Query(False, description="是否丢弃当前更改")
) -> ChangeSet:
    """
    选择操作
    
    选择并恢复到指定的操作
    """
    return pick_operation(network, operation, discard)

@router.get("/syncwithserver/", summary="与服务器同步", description="将网络与服务器同步到指定操作", response_model=None)
async def sync_with_server_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), operation: int = Query(..., description="目标操作ID")) -> ChangeSet:
    """
    与服务器同步
    
    将网络与服务器同步到指定的操作
    """
    return sync_with_server(network, operation)

@router.post("/batch/", summary="执行批量命令", description="执行多个网络操作命令", response_model=None)
async def execute_batch_commands_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), req: Request = None) -> ChangeSet:
    """
    执行批量命令
    
    在网络上执行多个操作命令
    """
    jo_root = await req.json()
    cs: ChangeSet = ChangeSet()
    cs.operations = jo_root["operations"]
    rcs = execute_batch_commands(network, cs)
    return rcs

@router.post("/compressedbatch/", summary="执行压缩批量命令", description="执行压缩的批量命令", response_model=None)
async def execute_compressed_batch_commands_endpoint(
    network: str = Query(..., description="管网名称（或数据库名称）"), 
    req: Request = None
) -> ChangeSet:
    """
    执行压缩批量命令
    
    执行压缩格式的批量命令
    """
    jo_root = await req.json()
    cs: ChangeSet = ChangeSet()
    cs.operations = jo_root["operations"]
    return execute_batch_command(network, cs)

@router.get("/getrestoreoperation/", summary="获取恢复操作ID", description="获取网络的恢复操作ID")
async def get_restore_operation_endpoint(network: str = Query(..., description="管网名称（或数据库名称）")) -> int:
    """
    获取恢复操作ID
    
    返回网络的恢复操作ID
    """
    return get_restore_operation(network)

@router.post("/setrestoreoperation/", summary="设置恢复操作ID", description="设置网络的恢复操作ID")
async def set_restore_operation_endpoint(network: str = Query(..., description="管网名称（或数据库名称）"), operation: int = Query(..., description="操作ID")) -> None:
    """
    设置恢复操作ID
    
    设置网络的恢复操作ID
    """
    return set_restore_operation(network, operation)
