"""HTTP routes for the mail module — mounted onto the main app via modules/registry.py."""
from __future__ import annotations

import asyncio as _asyncio
from typing import Any, Dict

from fastapi import APIRouter, Body, HTTPException

from . import backend as mail

MANIFEST = {"key": "mail", "label": "Mail", "icon": "✉️"}

router = APIRouter(prefix="/mail", tags=["mail"])


def _require_mail(account_id: str):
    if not mail.is_configured(account_id):
        raise HTTPException(status_code=400, detail="mail account not configured")


# --- accounts --------------------------------------------------------------------
@router.get("/accounts")
async def mail_accounts():
    return {"accounts": mail.public_accounts()}


@router.post("/accounts")
async def mail_account_create(payload: Dict[str, Any] = Body(...)):
    return mail.save_account(None, payload)


@router.put("/accounts/{account_id}")
async def mail_account_update(account_id: str, payload: Dict[str, Any] = Body(...)):
    try:
        return mail.save_account(account_id, payload)
    except KeyError:
        raise HTTPException(status_code=404, detail="account not found")


@router.delete("/accounts/{account_id}")
async def mail_account_delete(account_id: str):
    mail.delete_account(account_id)
    return {"status": "deleted"}


@router.post("/accounts/{account_id}/test")
async def mail_account_test(account_id: str):
    _require_mail(account_id)
    return await _asyncio.to_thread(mail.test_connection, account_id)


# --- mailbox -----------------------------------------------------------------------
@router.get("/folders")
async def mail_folders(account_id: str):
    _require_mail(account_id)
    try:
        return {"folders": await _asyncio.to_thread(mail.list_folders, account_id)}
    except Exception as e:
        raise HTTPException(status_code=502, detail=f"IMAP error: {e}")


@router.get("/messages")
async def mail_messages(account_id: str, folder: str = "INBOX", limit: int = 30, offset: int = 0):
    _require_mail(account_id)
    try:
        msgs = await _asyncio.to_thread(mail.list_messages, account_id, folder, limit, offset)
        return {"messages": msgs}
    except Exception as e:
        raise HTTPException(status_code=502, detail=f"IMAP error: {e}")


@router.get("/message")
async def mail_message(account_id: str, folder: str, uid: str):
    _require_mail(account_id)
    try:
        msg = await _asyncio.to_thread(mail.get_message, account_id, folder, uid)
    except Exception as e:
        raise HTTPException(status_code=502, detail=f"IMAP error: {e}")
    if not msg:
        raise HTTPException(status_code=404, detail="message not found")
    return msg


@router.post("/send")
async def mail_send(payload: Dict[str, Any] = Body(...)):
    account_id = payload.get("account_id", "")
    _require_mail(account_id)
    to = (payload.get("to") or "").strip()
    if not to:
        raise HTTPException(status_code=400, detail="'to' is required")
    try:
        return await _asyncio.to_thread(
            mail.send_message, account_id, to, payload.get("subject", ""), payload.get("body", ""),
            payload.get("cc", ""), payload.get("from_addr", ""),
        )
    except Exception as e:
        raise HTTPException(status_code=502, detail=f"SMTP error: {e}")


@router.post("/seen")
async def mail_seen(payload: Dict[str, Any] = Body(...)):
    account_id = payload.get("account_id", "")
    _require_mail(account_id)
    await _asyncio.to_thread(mail.set_seen, account_id, payload["folder"], payload["uid"], payload.get("seen", True))
    return {"status": "ok"}


@router.post("/delete")
async def mail_delete(payload: Dict[str, Any] = Body(...)):
    account_id = payload.get("account_id", "")
    _require_mail(account_id)
    await _asyncio.to_thread(mail.delete_message, account_id, payload["folder"], payload["uid"])
    return {"status": "deleted"}
