"""
Восстановить AutoInfo из bot.log после ошибки extract_clean_phones.
Берёт пары «Переходим на … / Ссылка / Итого найдено» перед ошибкой импорта.
"""

from __future__ import annotations

import ast
import asyncio
import logging
import re
import sys
from datetime import datetime
from pathlib import Path

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

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

_TS = re.compile(r"^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})")
_NAME = re.compile(r"Переходим на страницу объявления: (.+)$")
_LINK = re.compile(r"🔗 Ссылка: (https?://\S+)")
_PHONES = re.compile(r"Итого найдено телефонов для (\S+): (\d+) — (.+)$")
_ERR = "cannot import name 'extract_clean_phones'"


def _year_from_name(name: str) -> int:
    m = re.search(r"\b((?:19|20)\d{2})\b", name or "")
    return int(m.group(1)) if m else 0


def parse_failed_ads(log_path: Path) -> dict[str, dict]:
    if not log_path.is_file():
        _log.warning("нет лога %s", log_path)
        return {}

    lines = log_path.read_text(encoding="utf-8", errors="ignore").splitlines()
    out: dict[str, dict] = {}
    cur_name: str | None = None
    cur_link: str | None = None
    cur_ts: datetime | None = None

    for i, line in enumerate(lines):
        ts_m = _TS.match(line)
        ts = datetime.strptime(ts_m.group(1), "%Y-%m-%d %H:%M:%S") if ts_m else None

        nm = _NAME.search(line)
        if nm:
            cur_name = nm.group(1).strip()
            cur_ts = ts
            continue

        lm = _LINK.search(line)
        if lm:
            cur_link = lm.group(1).strip()
            continue

        pm = _PHONES.search(line)
        if not pm:
            continue

        ad_id = pm.group(1)
        phones_raw = pm.group(3).strip()
        if phones_raw in ("пусто", "[]"):
            continue

        window = "\n".join(lines[i : i + 8])
        if _ERR not in window:
            continue

        phones_src: list = [phones_raw]
        if phones_raw.startswith("["):
            try:
                parsed = ast.literal_eval(phones_raw)
                if isinstance(parsed, (list, tuple)):
                    phones_src = list(parsed)
            except Exception:
                phones_src = [phones_raw]

        link = cur_link or ""
        if not link and ad_id.isdigit():
            link = f"https://auto.ria.com/uk/auto_ad_{ad_id}.html"
        name = cur_name or f"ad {ad_id}"
        out[ad_id] = {
            "ad_id": ad_id,
            "name": name,
            "year": _year_from_name(name),
            "link": link,
            "phones_raw": phones_src,
            "created_at": ts or cur_ts or datetime.utcnow(),
        }

    return out


async def main() -> int:
    from app.database.crud import add_autoinfo, get_autoinfo_phones, update_autoinfo_phones
    from spam_sms import extract_clean_phones

    log_paths = [Path("/app/logs/bot.log"), ROOT / "logs" / "bot.log"]
    ads: dict[str, dict] = {}
    for p in log_paths:
        ads.update(parse_failed_ads(p))

    _log.info("Найдено в логах (ошибка импорта): %s", len(ads))
    if not ads:
        return 0

    added = 0
    updated = 0
    skipped = 0

    for ad_id, meta in ads.items():
        phones = extract_clean_phones(meta["phones_raw"])
        existing = await get_autoinfo_phones(ad_id)
        if existing:
            # уже есть — обновим телефоны если пусто/сырые
            if phones:
                await update_autoinfo_phones(ad_id, phones)
                updated += 1
            else:
                skipped += 1
            continue

        try:
            row = await add_autoinfo(
                ad_id=ad_id,
                name=meta["name"],
                year=meta["year"],
                usd_price=0,
                publish_time="",
                all_phones=phones,
                link=meta["link"],
                spam=False,
            )
            # Подтянуть created_at из лога
            if row is not None and meta.get("created_at"):
                from app.database.engine import async_session
                from app.database.models import AutoInfo
                from sqlalchemy import select

                async with async_session() as session:
                    async with session.begin():
                        r = await session.execute(
                            select(AutoInfo).where(AutoInfo.ad_id == ad_id)
                        )
                        obj = r.scalar_one_or_none()
                        if obj is not None:
                            obj.created_at = meta["created_at"]
            added += 1
            _log.info("added %s %s", ad_id, meta["name"][:60])
        except Exception as e:
            _log.warning("skip %s: %s", ad_id, e)
            skipped += 1

    _log.info("Готово: added=%s updated=%s skipped=%s", added, updated, skipped)
    return 0


if __name__ == "__main__":
    raise SystemExit(asyncio.run(main()))
