"""One-shot: recover today's SMS stats lost due to asyncio.gather bug."""
from __future__ import annotations

import asyncio
import logging
import sys
from datetime import datetime

sys.path.insert(0, "/app")

from sqlalchemy import select, text

from app.database.engine import async_session
from app.database.models import AutoInfo, MessageLog, MessageTotals, SentPhones

logging.basicConfig(level=logging.INFO)
log = logging.getLogger("recover_today_sms")

TODAY = "2026-07-16"


async def recover() -> None:
    async with async_session() as session:
        phone_rows = (
            await session.execute(
                text(
                    "SELECT id, phone_number, ad_id, ad_name, sent_at "
                    "FROM sent_phones "
                    "WHERE date(sent_at) = :d AND is_successful = 0 "
                    "ORDER BY id"
                ),
                {"d": TODAY},
            )
        ).mappings().all()
        phone_rows = [dict(r) for r in phone_rows]

        log.info("Found %s unsuccessful sent_phones for %s", len(phone_rows), TODAY)
        if not phone_rows:
            return

        ad_ids = [r["ad_id"] for r in phone_rows if r["ad_id"]]
        links: dict[str, str] = {}
        if ad_ids:
            rows = (
                await session.execute(
                    select(AutoInfo.ad_id, AutoInfo.link).where(AutoInfo.ad_id.in_(ad_ids))
                )
            ).all()
            links = {str(a): ln for a, ln in rows}

        await session.rollback()

        recovered = 0
        for r in phone_rows:
            phone = (
                await session.execute(
                    select(SentPhones).where(SentPhones.id == r["id"])
                )
            ).scalar_one()
            phone.is_successful = True

            link = links.get(str(r["ad_id"] or ""), "") or f"ad:{r['ad_id'] or '?'}"
            name = f"{r['ad_name'] or 'Неизвестно'} | Телефоны: {r['phone_number']}"
            exists = (
                await session.execute(
                    text(
                        "SELECT id FROM message_log "
                        "WHERE name = :name AND date(created_at) = :d LIMIT 1"
                    ),
                    {"name": name, "d": TODAY},
                )
            ).scalar()
            if not exists:
                created = r["sent_at"]
                if isinstance(created, str):
                    try:
                        created = datetime.fromisoformat(created)
                    except ValueError:
                        created = datetime.utcnow()
                session.add(
                    MessageLog(
                        name=name,
                        link=link,
                        is_sent=True,
                        created_at=created or datetime.utcnow(),
                    )
                )
            recovered += 1

        totals = (
            await session.execute(select(MessageTotals).limit(1))
        ).scalars().first()
        if totals:
            totals.sent_total = int(totals.sent_total or 0) + recovered
        else:
            session.add(MessageTotals(id=1, sent_total=recovered, failed_total=0))

        await session.commit()
        log.info("Recovered %s SMS records; totals updated", recovered)

    from app.database.crud_static import get_sms_statistics

    stats = await get_sms_statistics()
    log.info("stats after recover: %s", stats)


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