"""
Script one-shot: corregge il body_text/body_html delle ricevute PEC gia' in DB.

Problema: il parser EML sovrascriveva il body delle ricevute con il contenuto
di postacert.eml (messaggio originale inviato), invece di mostrare il testo
della ricevuta stessa.

Questo script:
1. Trova tutti i messaggi in DB con pec_type di tipo ricevuta
2. Scarica l'EML grezzo da MinIO (raw_eml_path)
3. Lo ri-parsa con is_receipt=True (parser corretto)
4. Aggiorna body_text e body_html nel DB

Uso:
    cd /opt/pechub
    docker compose exec pechub-worker-1 python /app/scripts/fix_receipt_body.py
"""

import asyncio
import logging
import sys
from datetime import UTC, datetime

from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

# Aggiungi il path dell'app
sys.path.insert(0, "/app")

from app.config import get_settings
from app.models import Message
from app.parsers.eml_parser import parse_eml
from app.storage.minio_client import download_attachment

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
)
logger = logging.getLogger(__name__)

# Tipi di ricevuta che potrebbero avere il body sbagliato
RECEIPT_TYPES = {
    "accettazione",
    "non_accettazione",
    "presa_in_carico",
    "avvenuta_consegna",
    "mancata_consegna",
    "errore_consegna",
    "preavviso_mancata_consegna",
    "rilevazione_virus",
}


async def fix_receipt_bodies() -> None:
    settings = get_settings()

    engine = create_async_engine(settings.database_url, echo=False)
    async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

    async with async_session() as db:
        # Trova tutti i messaggi ricevuta con raw_eml_path
        result = await db.execute(
            select(Message).where(
                Message.pec_type.in_(RECEIPT_TYPES),
                Message.raw_eml_path.is_not(None),
            ).order_by(Message.created_at)
        )
        messages = result.scalars().all()

        logger.info(f"Trovate {len(messages)} ricevute da verificare")

        fixed = 0
        skipped = 0
        errors = 0

        for msg in messages:
            try:
                # Scarica EML grezzo da MinIO (download_attachment funziona per qualsiasi path)
                raw_eml = await download_attachment(msg.raw_eml_path)
                if not raw_eml:
                    logger.warning(f"EML non trovato su MinIO per messaggio {msg.id} (path={msg.raw_eml_path!r})")
                    skipped += 1
                    continue

                # Re-parsing con is_receipt=True (parser corretto)
                parsed = parse_eml(raw_eml, is_receipt=True)

                # Controlla se il body e' cambiato
                new_body_text = parsed.body_text
                new_body_html = parsed.body_html

                if new_body_text == msg.body_text and new_body_html == msg.body_html:
                    logger.debug(f"Messaggio {msg.id} ({msg.pec_type}): body invariato, skip")
                    skipped += 1
                    continue

                # Aggiorna nel DB
                msg.body_text = new_body_text
                msg.body_html = new_body_html
                msg.updated_at = datetime.now(UTC)

                logger.info(
                    f"Fixato: id={msg.id} pec_type={msg.pec_type!r} subject={msg.subject!r} "
                    f"body_text_len={len(new_body_text or '')}"
                )
                fixed += 1

            except Exception as e:
                logger.error(f"Errore su messaggio {msg.id}: {e}", exc_info=True)
                errors += 1
                continue

        if fixed > 0:
            await db.commit()
            logger.info(f"Commit eseguito: {fixed} messaggi aggiornati")
        else:
            logger.info("Nessun messaggio da aggiornare")

        logger.info(
            f"Completato: fixed={fixed} skipped={skipped} errors={errors} "
            f"totale={len(messages)}"
        )

    await engine.dispose()


if __name__ == "__main__":
    asyncio.run(fix_receipt_bodies())
