#!/usr/bin/env python3
"""
enrich_reviews.py — свежий негатив (оценки ≤ 3 за последние 48 часов) по SKU из выборки.

API: GET /api/v1/feedbacks?dateFrom=<unix>&dateTo=<unix>&isAnswered=false&take=5000&skip=0
"""
from __future__ import annotations

import argparse
import json
import os
import sys
import time
from datetime import date, datetime, timedelta, timezone
from typing import Any

import requests

URL = "https://feedbacks-api.wildberries.ru/api/v1/feedbacks"
MAX_RETRIES = 5


def log(msg: str) -> None:
    print(f"[reviews] {msg}", file=sys.stderr)


def get_jwt() -> str:
    jwt = os.environ.get("WB_ANALYTICS_JWT")
    if not jwt:
        sys.exit(3)
    return jwt


def fetch_recent(jwt: str, hours: int = 48) -> list[dict[str, Any]] | None:
    headers = {"Authorization": jwt}
    now = datetime.now(timezone.utc)
    date_from = int((now - timedelta(hours=hours)).timestamp())
    date_to = int(now.timestamp())
    out: list[dict[str, Any]] = []
    skip = 0
    while True:
        params = {
            "isAnswered": "false",
            "take": 5000,
            "skip": skip,
            "dateFrom": date_from,
            "dateTo": date_to,
            "order": "dateDesc",
        }
        for attempt in range(MAX_RETRIES):
            try:
                r = requests.get(URL, headers=headers, params=params, timeout=60)
            except requests.RequestException as exc:
                log(f"  conn: {exc}")
                time.sleep(5); continue
            if r.status_code in (401, 403):
                return None
            if r.status_code == 429:
                time.sleep(30); continue
            if r.status_code != 200:
                log(f"  HTTP {r.status_code}: {r.text[:200]}")
                time.sleep(5); continue
            data = r.json()
            chunk = (data.get("data") or {}).get("feedbacks", [])
            out.extend(chunk)
            if len(chunk) < 5000:
                return out
            skip += 5000
            break
        else:
            return out
        time.sleep(2)
    return out


def main() -> int:
    p = argparse.ArgumentParser()
    p.add_argument("--insights", required=True)
    args = p.parse_args()
    with open(args.insights, encoding="utf-8") as f:
        insights = json.load(f)
    jwt = get_jwt()
    feedbacks = fetch_recent(jwt)
    if feedbacks is None:
        log("Skipped: no scope or hard error")
        for section in ("drops", "growths", "oos_candidates"):
            for s in insights.get(section, []):
                s.setdefault("enrichment", {})["reviews"] = {"flag": "NO_DATA"}
        with open(args.insights, "w", encoding="utf-8") as f:
            json.dump(insights, f, ensure_ascii=False, indent=2)
        return 0

    log(f"  fetched {len(feedbacks)} fresh feedbacks")
    by_nm: dict[int, list[dict[str, Any]]] = {}
    for fb in feedbacks:
        nm = (fb.get("productDetails") or {}).get("nmId") or fb.get("nmId")
        rating = fb.get("productValuation", 5)
        if rating and rating <= 3 and nm:
            # Текст может быть пустым; берём первое непустое из text/cons/pros
            parts = []
            for fld in ("text", "cons", "pros"):
                v = (fb.get(fld) or "").strip()
                if v:
                    parts.append(f"{fld}: {v}" if fld != "text" else v)
            content = " · ".join(parts)[:200] or "(без текста)"
            by_nm.setdefault(nm, []).append({
                "rating": rating,
                "text": content,
                "userName": fb.get("userName") or "",
                "createdDate": fb.get("createdDate"),
            })

    for section in ("drops", "growths", "oos_candidates"):
        for s in insights.get(section, []):
            nm = s["nmID"]
            negs = by_nm.get(nm, [])
            if negs:
                negs_sorted = sorted(negs, key=lambda x: x.get("createdDate") or "", reverse=True)
                s.setdefault("enrichment", {})["reviews"] = {
                    "fresh_negative_count": len(negs),
                    "flag": "fresh_negative",
                    "sample": negs_sorted[0],
                }
            else:
                s.setdefault("enrichment", {})["reviews"] = {"fresh_negative_count": 0, "flag": "no_negative"}

    with open(args.insights, "w", encoding="utf-8") as f:
        json.dump(insights, f, ensure_ascii=False, indent=2)
    return 0


if __name__ == "__main__":
    sys.exit(main())
