"""Проверка и удаление дублей телефонных номеров в pending_sms."""

from __future__ import annotations

import asyncio
import logging
import sys
from collections import defaultdict
from datetime import datetime
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")
_log = logging.getLogger("dedupe_pending")


async def main(*, fix: bool) -> int:
    from sqlalchemy import select, update

    from app.database.crud_pending_sms import STATUS_CANCELLED, STATUS_PENDING
    from app.database.engine import async_session
    from app.database.models import PendingSms

    async with async_session() as session:
        result = await session.execute(
            select(PendingSms)
            .where(PendingSms.status == STATUS_PENDING)
            .order_by(PendingSms.id.asc())
        )
        rows = list(result.scalars().all())

    by_phone: dict[str, list] = defaultdict(list)
    for row in rows:
        by_phone[row.phone_number].append(row)

    dup_groups = {p: items for p, items in by_phone.items() if len(items) > 1}
    _log.info(
        "pending=%s unique=%s dup_groups=%s",
        len(rows),
        len(by_phone),
        len(dup_groups),
    )

    cancel_ids: list[int] = []
    for phone, items in sorted(dup_groups.items(), key=lambda x: -len(x[1])):
        keep = items[0]
        drop = items[1:]
        _log.info(
            "DUP %s x%s keep_id=%s drop_ids=%s ads=%s",
            phone,
            len(items),
            keep.id,
            [x.id for x in drop],
            [x.ad_id for x in items],
        )
        cancel_ids.extend(x.id for x in drop)

    if not cancel_ids:
        _log.info("Дублей нет")
        return 0

    if not fix:
        _log.info("Найдено лишних записей: %s (запуск с --fix чтобы отменить)", len(cancel_ids))
        return 0

    async with async_session() as session:
        async with session.begin():
            await session.execute(
                update(PendingSms)
                .where(PendingSms.id.in_(cancel_ids))
                .values(status=STATUS_CANCELLED, updated_at=datetime.utcnow())
            )

    left = len(rows) - len(cancel_ids)
    _log.info("Отменено дублей: %s, pending останется ~%s", len(cancel_ids), left)
    return 0


if __name__ == "__main__":
    do_fix = "--fix" in sys.argv
    raise SystemExit(asyncio.run(main(fix=do_fix)))
