"""
Router scadenzario e tracking deadlines (Feature 4).

Endpoint:
  GET  /deadlines                      – messaggi con scadenze imminenti
  POST /messages/{id}/deadline         – imposta/modifica/rimuove scadenza
"""

import uuid
from datetime import datetime, timedelta, timezone

from fastapi import APIRouter, Query
from pydantic import BaseModel
from sqlalchemy import and_, select

from app.dependencies import CurrentUser, DB
from app.models.message import Message
from app.schemas.message import MessageResponse
from app.core.exceptions import NotFoundError

router = APIRouter(tags=["Deadlines"])


class DeadlineSetRequest(BaseModel):
    deadline_at: datetime | None = None
    """Imposta a null per rimuovere la scadenza."""
    deadline_note: str | None = None


class DeadlineMessageResponse(BaseModel):
    model_config = {"from_attributes": True}

    id: uuid.UUID
    subject: str | None
    from_address: str | None
    to_addresses: list[str] | None = None
    direction: str
    pec_type: str
    state: str
    mailbox_id: uuid.UUID
    deadline_at: datetime | None = None
    deadline_note: str | None = None
    is_overdue: bool = False
    received_at: datetime | None = None
    sent_at: datetime | None = None
    created_at: datetime


@router.get("/deadlines", response_model=list[DeadlineMessageResponse])
async def list_deadlines(
    current_user: CurrentUser,
    db: DB,
    days_ahead: int = Query(30, ge=1, le=365, description="Giorni da considerare in avanti"),
    include_overdue: bool = Query(True, description="Includi scadenze gia' passate"),
) -> list[DeadlineMessageResponse]:
    """
    Restituisce i messaggi con scadenze nel range specificato.

    Ordinati per: scaduti prima, poi per deadline_at ASC.
    """
    now = datetime.now(timezone.utc)
    future_limit = now + timedelta(days=days_ahead)

    conditions = [
        Message.tenant_id == current_user.tenant_id,
        Message.deadline_at.is_not(None),
        Message.is_trashed == False,  # noqa: E712
    ]

    if include_overdue:
        # Include scaduti e futuri fino al limite
        conditions.append(Message.deadline_at <= future_limit)
    else:
        # Solo scadenze future
        conditions.append(and_(Message.deadline_at > now, Message.deadline_at <= future_limit))

    result = await db.execute(
        select(Message)
        .where(and_(*conditions))
        .order_by(Message.deadline_at)
        .limit(200)
    )
    messages = list(result.scalars().all())

    items = []
    for msg in messages:
        is_overdue = msg.deadline_at < now if msg.deadline_at else False
        items.append(DeadlineMessageResponse(
            id=msg.id,
            subject=msg.subject,
            from_address=msg.from_address,
            to_addresses=msg.to_addresses,
            direction=msg.direction,
            pec_type=msg.pec_type,
            state=msg.state,
            mailbox_id=msg.mailbox_id,
            deadline_at=msg.deadline_at,
            deadline_note=msg.deadline_note,
            is_overdue=is_overdue,
            received_at=msg.received_at,
            sent_at=msg.sent_at,
            created_at=msg.created_at,
        ))
    return items


@router.post("/messages/{message_id}/deadline", response_model=DeadlineMessageResponse)
async def set_deadline(
    message_id: uuid.UUID,
    data: DeadlineSetRequest,
    current_user: CurrentUser,
    db: DB,
) -> DeadlineMessageResponse:
    """
    Imposta, modifica o rimuove la scadenza di un messaggio.

    Passa deadline_at=null per rimuovere la scadenza.
    """
    result = await db.execute(
        select(Message).where(
            Message.id == message_id,
            Message.tenant_id == current_user.tenant_id,
        )
    )
    msg = result.scalar_one_or_none()
    if not msg:
        raise NotFoundError(f"Messaggio {message_id} non trovato")

    msg.deadline_at = data.deadline_at
    msg.deadline_note = data.deadline_note
    await db.commit()
    await db.refresh(msg)

    now = datetime.now(timezone.utc)
    is_overdue = msg.deadline_at < now if msg.deadline_at else False

    return DeadlineMessageResponse(
        id=msg.id,
        subject=msg.subject,
        from_address=msg.from_address,
        to_addresses=msg.to_addresses,
        direction=msg.direction,
        pec_type=msg.pec_type,
        state=msg.state,
        mailbox_id=msg.mailbox_id,
        deadline_at=msg.deadline_at,
        deadline_note=msg.deadline_note,
        is_overdue=is_overdue,
        received_at=msg.received_at,
        sent_at=msg.sent_at,
        created_at=msg.created_at,
    )
