"""/api/entities — the /projects/manage backend (M5): section payload
with true aggregate counts + rename / move / merge / delete-empty for
operators, clients (edges), and projects. Thin HTTP layer over
services/entities/manage (judgment #10: merge is first-class)."""

from __future__ import annotations

import uuid

from fastapi import APIRouter
from pydantic import BaseModel

from app.routers.deps import ActorDep, ApiError, SessionDep
from app.services.entities import manage as manage_svc
from app.services.errors import ServiceError

router = APIRouter()


def _run(fn, *args, **kwargs):
    try:
        return fn(*args, **kwargs)
    except ServiceError as exc:
        raise ApiError(exc.status, exc.code, exc.summary, exc.detail) from exc


class RenameBody(BaseModel):
    name: str


class ClientRef(BaseModel):
    operator_id: uuid.UUID
    client_id: uuid.UUID


class ClientRenameBody(ClientRef):
    name: str


class MoveProjectBody(BaseModel):
    target_operator_id: uuid.UUID
    target_client_id: uuid.UUID


class MergeIdsBody(BaseModel):
    source_id: uuid.UUID
    target_id: uuid.UUID


class MergeClientsBody(BaseModel):
    source_operator_id: uuid.UUID
    source_client_id: uuid.UUID
    target_operator_id: uuid.UUID
    target_client_id: uuid.UUID


@router.get("/api/entities/manage")
def manage(session: SessionDep, actor: ActorDep) -> dict:
    return _run(manage_svc.manage_payload, session, actor)


# ---------------------------------------------------------------- rename


@router.post("/api/entities/operators/{party_id}/rename")
def rename_operator(
    session: SessionDep, actor: ActorDep, party_id: uuid.UUID, body: RenameBody
) -> dict:
    return _run(manage_svc.rename_operator, session, actor, party_id, body.name)


@router.post("/api/entities/clients/rename")
def rename_client(session: SessionDep, actor: ActorDep, body: ClientRenameBody) -> dict:
    return _run(
        manage_svc.rename_client, session, actor, body.operator_id, body.client_id, body.name
    )


@router.post("/api/entities/projects/{project_id}/rename")
def rename_project(
    session: SessionDep, actor: ActorDep, project_id: uuid.UUID, body: RenameBody
) -> dict:
    return _run(manage_svc.rename_project, session, actor, project_id, body.name)


# ---------------------------------------------------------------- move


@router.post("/api/entities/projects/{project_id}/move")
def move_project(
    session: SessionDep, actor: ActorDep, project_id: uuid.UUID, body: MoveProjectBody
) -> dict:
    return _run(
        manage_svc.move_project,
        session,
        actor,
        project_id,
        body.target_operator_id,
        body.target_client_id,
    )


# ---------------------------------------------------------------- merge


@router.post("/api/entities/projects/merge")
def merge_project(session: SessionDep, actor: ActorDep, body: MergeIdsBody) -> dict:
    return _run(manage_svc.merge_project, session, actor, body.source_id, body.target_id)


@router.post("/api/entities/clients/merge")
def merge_client(session: SessionDep, actor: ActorDep, body: MergeClientsBody) -> dict:
    return _run(
        manage_svc.merge_client,
        session,
        actor,
        body.source_operator_id,
        body.source_client_id,
        body.target_operator_id,
        body.target_client_id,
    )


@router.post("/api/entities/operators/merge")
def merge_operator(session: SessionDep, actor: ActorDep, body: MergeIdsBody) -> dict:
    return _run(manage_svc.merge_operator, session, actor, body.source_id, body.target_id)


# ---------------------------------------------------------------- delete


@router.delete("/api/entities/projects/{project_id}")
def delete_project(session: SessionDep, actor: ActorDep, project_id: uuid.UUID) -> dict:
    return _run(manage_svc.delete_project, session, actor, project_id)


@router.post("/api/entities/clients/delete")
def delete_client(session: SessionDep, actor: ActorDep, body: ClientRef) -> dict:
    return _run(manage_svc.delete_client, session, actor, body.operator_id, body.client_id)


@router.delete("/api/entities/operators/{party_id}")
def delete_operator(session: SessionDep, actor: ActorDep, party_id: uuid.UUID) -> dict:
    return _run(manage_svc.delete_operator, session, actor, party_id)
