"""Autoresponder (vacation) API routes."""

from __future__ import annotations

from typing import List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session, joinedload

from .. import models, schemas
from ..db import get_db
from ..mailbox_ops import apply_autoresponder_to_mailbox
from ..security import require_admin

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


def _get_account(db: Session, account_id: int) -> models.Account:
    account = (
        db.query(models.Account)
        .options(joinedload(models.Account.domain), joinedload(models.Account.autoresponder))
        .filter(models.Account.id == account_id)
        .first()
    )
    if not account:
        raise HTTPException(status_code=404, detail="Account not found")
    return account


def _serialize(row: models.Autoresponder) -> schemas.AutoresponderOut:
    return schemas.AutoresponderOut.model_validate(row)


@router.get("/accounts/{account_id}/autoresponder", response_model=schemas.AutoresponderOut | dict)
def get_autoresponder(account_id: int, db: Session = Depends(get_db), _: str = Depends(require_admin)):
    account = _get_account(db, account_id)
    if not account.autoresponder:
        return {
            "account_id": account_id,
            "is_enabled": False,
            "subject": "Out of office",
            "body": "",
            "start_at": None,
            "end_at": None,
            "reply_once_days": 7,
        }
    return _serialize(account.autoresponder)


@router.put("/accounts/{account_id}/autoresponder", response_model=schemas.AutoresponderOut)
def put_autoresponder(
    account_id: int,
    payload: schemas.AutoresponderUpsert,
    db: Session = Depends(get_db),
    _: str = Depends(require_admin),
):
    account = _get_account(db, account_id)
    row = account.autoresponder
    if not row:
        row = models.Autoresponder(account_id=account.id, body="")
        db.add(row)
    row.is_enabled = bool(payload.is_enabled)
    row.subject = payload.subject
    row.body = payload.body or ""
    row.start_at = payload.start_at
    row.end_at = payload.end_at
    row.reply_once_days = int(payload.reply_once_days or 7)
    db.commit()
    db.refresh(row)
    account.autoresponder = row
    try:
        apply_autoresponder_to_mailbox(account, row)
    except Exception as exc:
        raise HTTPException(status_code=500, detail=f"Unable to apply autoresponder sieve: {exc}") from exc
    return _serialize(row)


@router.delete("/accounts/{account_id}/autoresponder", response_model=dict)
def delete_autoresponder(account_id: int, db: Session = Depends(get_db), _: str = Depends(require_admin)):
    account = _get_account(db, account_id)
    row = account.autoresponder
    if row:
        db.delete(row)
        db.commit()
    try:
        apply_autoresponder_to_mailbox(account, None)
    except Exception:
        pass
    return {"deleted": True, "account_id": account_id}


@router.get("/autoresponders", response_model=List[schemas.AutoresponderOut])
def list_autoresponders(db: Session = Depends(get_db), _: str = Depends(require_admin)):
    return db.query(models.Autoresponder).order_by(models.Autoresponder.id.asc()).all()
