"""
Router Virtual Box (Fase 2).

Endpoint:
  POST   /virtual-boxes                              → crea VBox
  GET    /virtual-boxes                              → lista VBox del tenant
  GET    /virtual-boxes/{id}                         → dettaglio VBox
  PATCH  /virtual-boxes/{id}                         → aggiorna VBox (incluse caselle)
  DELETE /virtual-boxes/{id}                         → elimina VBox
  PUT    /virtual-boxes/{id}/rules                   → sostituisce regole
  PUT    /virtual-boxes/{id}/mailboxes               → imposta caselle reali associate
  GET    /virtual-boxes/{id}/mailboxes               → lista caselle reali associate
  POST   /virtual-boxes/{id}/assignments             → assegna utenti
  DELETE /virtual-boxes/{id}/assignments/{user_id}   → rimuovi assegnazione
  GET    /virtual-boxes/{id}/assignments             → lista utenti assegnati
  GET    /virtual-boxes/my                           → VBox assegnate all'utente corrente
"""

import uuid

from fastapi import APIRouter, Query

from app.dependencies import AdminUser, CurrentUser, DB
from app.schemas.virtual_box import (
    AssignedUserResponse,
    MailboxBriefResponse,
    VirtualBoxAssignmentResponse,
    VirtualBoxAssignRequest,
    VirtualBoxCreate,
    VirtualBoxListResponse,
    VirtualBoxMailboxAssignRequest,
    VirtualBoxResponse,
    VirtualBoxRuleCreate,
    VirtualBoxUpdate,
)
from app.services.virtual_box_service import VirtualBoxService

router = APIRouter(prefix="/virtual-boxes", tags=["Virtual Box"])


# ─── CRUD ─────────────────────────────────────────────────────────────────────

@router.post(
    "",
    response_model=VirtualBoxResponse,
    status_code=201,
    summary="Crea una nuova Virtual Box",
)
async def create_virtual_box(
    body: VirtualBoxCreate,
    current_user: AdminUser,
    db: DB,
) -> VirtualBoxResponse:
    service = VirtualBoxService(db)
    vbox = await service.create(current_user.tenant_id, body, current_user.id)
    return _to_response(vbox)


@router.get(
    "",
    response_model=VirtualBoxListResponse,
    summary="Lista Virtual Box del tenant",
)
async def list_virtual_boxes(
    current_user: AdminUser,
    db: DB,
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    active_only: bool = Query(False),
) -> VirtualBoxListResponse:
    service = VirtualBoxService(db)
    items, total = await service.list_vboxes(
        current_user.tenant_id, page, page_size, active_only
    )
    return VirtualBoxListResponse(
        items=[_to_response(v) for v in items],
        total=total,
        page=page,
        page_size=page_size,
    )


@router.get(
    "/my",
    response_model=list[VirtualBoxResponse],
    summary="Virtual Box assegnate all'utente corrente",
)
async def my_virtual_boxes(
    current_user: CurrentUser,
    db: DB,
) -> list[VirtualBoxResponse]:
    service = VirtualBoxService(db)
    items = await service.list_user_vboxes(current_user.id, current_user.tenant_id)
    return [_to_response(v) for v in items]


@router.get(
    "/my/mailboxes",
    response_model=list[MailboxBriefResponse],
    summary="Caselle PEC da cui l'utente può inviare tramite Virtual Box",
    description=(
        "Restituisce le caselle PEC attive associate alle Virtual Box "
        "a cui l'utente corrente è assegnato. "
        "Usato dalla pagina di composizione per mostrare le caselle mittente disponibili."
    ),
)
async def my_sendable_mailboxes(
    current_user: CurrentUser,
    db: DB,
) -> list[MailboxBriefResponse]:
    service = VirtualBoxService(db)
    mailboxes = await service.get_user_sendable_mailboxes(
        current_user.id, current_user.tenant_id
    )
    return [MailboxBriefResponse.model_validate(m) for m in mailboxes]


@router.get(
    "/{vbox_id}",
    response_model=VirtualBoxResponse,
    summary="Dettaglio Virtual Box",
)
async def get_virtual_box(
    vbox_id: uuid.UUID,
    current_user: AdminUser,
    db: DB,
) -> VirtualBoxResponse:
    service = VirtualBoxService(db)
    vbox = await service.get(vbox_id, current_user.tenant_id)
    return _to_response(vbox)


@router.patch(
    "/{vbox_id}",
    response_model=VirtualBoxResponse,
    summary="Aggiorna Virtual Box",
    description=(
        "Aggiorna i metadati della Virtual Box. "
        "Se `mailbox_ids` è fornito, sostituisce completamente le caselle PEC associate."
    ),
)
async def update_virtual_box(
    vbox_id: uuid.UUID,
    body: VirtualBoxUpdate,
    current_user: AdminUser,
    db: DB,
) -> VirtualBoxResponse:
    service = VirtualBoxService(db)
    vbox = await service.update(vbox_id, current_user.tenant_id, body)
    return _to_response(vbox)


@router.delete(
    "/{vbox_id}",
    status_code=204,
    summary="Elimina Virtual Box",
)
async def delete_virtual_box(
    vbox_id: uuid.UUID,
    current_user: AdminUser,
    db: DB,
) -> None:
    service = VirtualBoxService(db)
    await service.delete(vbox_id, current_user.tenant_id)


# ─── Regole ───────────────────────────────────────────────────────────────────

@router.put(
    "/{vbox_id}/rules",
    response_model=VirtualBoxResponse,
    summary="Sostituisce le regole di una Virtual Box",
    description="Rimpiazza completamente il set di regole. Inviare lista vuota per azzerarle.",
)
async def replace_rules(
    vbox_id: uuid.UUID,
    body: list[VirtualBoxRuleCreate],
    current_user: AdminUser,
    db: DB,
) -> VirtualBoxResponse:
    service = VirtualBoxService(db)
    vbox = await service.replace_rules(vbox_id, current_user.tenant_id, body)
    return _to_response(vbox)


# ─── Caselle Reali ────────────────────────────────────────────────────────────

@router.put(
    "/{vbox_id}/mailboxes",
    response_model=VirtualBoxResponse,
    summary="Imposta le caselle PEC reali associate alla Virtual Box",
    description=(
        "Sostituisce completamente l'elenco delle caselle PEC reali collegate. "
        "Inviare una lista vuota per rimuovere tutte le associazioni."
    ),
)
async def set_mailboxes(
    vbox_id: uuid.UUID,
    body: VirtualBoxMailboxAssignRequest,
    current_user: AdminUser,
    db: DB,
) -> VirtualBoxResponse:
    service = VirtualBoxService(db)
    vbox = await service.set_mailboxes(vbox_id, current_user.tenant_id, body.mailbox_ids)
    return _to_response(vbox)


@router.get(
    "/{vbox_id}/mailboxes",
    response_model=list[MailboxBriefResponse],
    summary="Lista caselle PEC reali associate alla Virtual Box",
)
async def list_mailboxes(
    vbox_id: uuid.UUID,
    current_user: AdminUser,
    db: DB,
) -> list[MailboxBriefResponse]:
    service = VirtualBoxService(db)
    mailboxes = await service.list_mailboxes(vbox_id, current_user.tenant_id)
    return [MailboxBriefResponse.model_validate(m) for m in mailboxes]


# ─── Assegnazioni ─────────────────────────────────────────────────────────────

@router.post(
    "/{vbox_id}/assignments",
    response_model=list[VirtualBoxAssignmentResponse],
    status_code=201,
    summary="Assegna utenti a una Virtual Box",
)
async def assign_users(
    vbox_id: uuid.UUID,
    body: VirtualBoxAssignRequest,
    current_user: AdminUser,
    db: DB,
) -> list[VirtualBoxAssignmentResponse]:
    service = VirtualBoxService(db)
    assignments = await service.assign_users(
        vbox_id, current_user.tenant_id, body.user_ids, current_user.id
    )
    return [VirtualBoxAssignmentResponse.model_validate(a) for a in assignments]


@router.delete(
    "/{vbox_id}/assignments/{user_id}",
    status_code=204,
    summary="Rimuovi assegnazione utente",
)
async def unassign_user(
    vbox_id: uuid.UUID,
    user_id: uuid.UUID,
    current_user: AdminUser,
    db: DB,
) -> None:
    service = VirtualBoxService(db)
    await service.unassign_user(vbox_id, current_user.tenant_id, user_id)


@router.get(
    "/{vbox_id}/assignments",
    response_model=list[AssignedUserResponse],
    summary="Lista utenti assegnati a una Virtual Box",
)
async def list_assigned_users(
    vbox_id: uuid.UUID,
    current_user: AdminUser,
    db: DB,
) -> list[AssignedUserResponse]:
    service = VirtualBoxService(db)
    rows = await service.list_assigned_users(vbox_id, current_user.tenant_id)
    return [AssignedUserResponse(**row) for row in rows]


# ─── Helper ───────────────────────────────────────────────────────────────────

def _to_response(vbox) -> VirtualBoxResponse:
    """Costruisce la risposta includendo regole, conteggio assegnazioni e caselle reali."""
    from app.schemas.virtual_box import VirtualBoxRuleResponse

    rules = [VirtualBoxRuleResponse.model_validate(r) for r in (vbox.rules or [])]
    mailboxes = [
        MailboxBriefResponse.model_validate(m) for m in (vbox.mailboxes or [])
    ]
    return VirtualBoxResponse(
        id=vbox.id,
        tenant_id=vbox.tenant_id,
        name=vbox.name,
        description=vbox.description,
        label=vbox.label,
        is_active=vbox.is_active,
        created_by=vbox.created_by,
        created_at=vbox.created_at,
        updated_at=vbox.updated_at,
        rules=rules,
        assignment_count=len(vbox.assignments or []),
        mailboxes=mailboxes,
    )
