#!/usr/bin/env python3
"""
Full analysis of WB product videos vs our generations.

For each product with video on WB:
1. Get content history from Sellematics (when video count changed)
2. Compare video-added date vs our generation date
3. Download all videos (WB can have up to 3 per product)
4. Check duration and resolution
5. Classify: likely ours / pre-existing / unclear

Primary signal: video_added_date AFTER our_generation_date
Secondary: video count increased after our generation
"""

import sqlite3
import requests
import subprocess
import time
import sys
import json
from datetime import datetime, timezone, timedelta
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed

DB_PATH = "/mnt/video/videobot_prod.db"
SELLEMATICS_URL = "http://127.0.0.1:43761/api/v1"

EXCLUDE_USERS = {100000001, 100000002, 100000003}


def get_products_with_video_from_report():
    """Load from previous check."""
    with open("/tmp/wb_video_check_report.json") as f:
        return json.load(f)["products_with_video"]


def get_generation_dates(product_id: str) -> list:
    conn = sqlite3.connect(DB_PATH)
    cur = conn.cursor()
    cur.execute("""
        SELECT t.task_id, t.created_at, t.user_id, u.username, u.first_name
        FROM transactions t
        JOIN users u ON t.user_id = u.user_id
        WHERE t.type = 'generation'
          AND t.product_id = ?
          AND t.user_id NOT IN ({})
          AND NOT EXISTS (
              SELECT 1 FROM transactions r
              WHERE r.type = 'refund' AND r.task_id = t.task_id
          )
        ORDER BY t.created_at
    """.format(",".join(str(u) for u in EXCLUDE_USERS)), (product_id,))
    rows = cur.fetchall()
    conn.close()
    return [
        {"task_id": r[0], "date": r[1], "user_id": r[2],
         "username": r[3], "first_name": r[4]}
        for r in rows
    ]


def get_content_history(product_id: str) -> list:
    try:
        resp = requests.post(
            f"{SELLEMATICS_URL}/archive/product/content",
            data={"mall": "wb", "id": product_id},
            timeout=30,
        )
        if resp.status_code == 200:
            return resp.json().get("payload", [])
    except:
        pass
    return []


def analyze_video_history(history: list, gen_dates: list) -> dict:
    """
    Analyze content history to determine if video was added after our generation.
    Returns detailed analysis.
    """
    result = {
        "video_added_ts": None,
        "video_added_date": None,
        "video_was_present_before_gen": None,
        "video_appeared_after_gen": False,
        "video_count_at_gen_time": None,
        "video_count_now": None,
        "days_between_gen_and_video": None,
        "history_points": len(history),
    }

    if not history or not gen_dates:
        return result

    sorted_hist = sorted(history, key=lambda x: x["ts"])

    # Find all video count transitions
    transitions = []
    prev_videos = None
    for rec in sorted_hist:
        content = rec.get("content", {})
        cur_videos = content.get("videos", 0)
        if prev_videos is not None and cur_videos != prev_videos:
            transitions.append({
                "ts": rec["ts"],
                "from": prev_videos,
                "to": cur_videos,
                "date": datetime.fromtimestamp(rec["ts"], tz=timezone.utc).strftime("%Y-%m-%d %H:%M"),
            })
        prev_videos = cur_videos

    result["video_count_now"] = sorted_hist[-1].get("content", {}).get("videos", 0) if sorted_hist else 0

    # Find the FIRST gen date (as timestamp)
    first_gen_str = gen_dates[0]["date"]  # "2026-02-13 01:06:53"
    first_gen_dt = datetime.strptime(first_gen_str, "%Y-%m-%d %H:%M:%S")
    first_gen_ts = int(first_gen_dt.timestamp())

    # What was video count at the time of our generation?
    video_at_gen = 0
    for rec in sorted_hist:
        if rec["ts"] <= first_gen_ts:
            video_at_gen = rec.get("content", {}).get("videos", 0)
        else:
            break
    result["video_count_at_gen_time"] = video_at_gen
    result["video_was_present_before_gen"] = video_at_gen > 0

    # Find transitions from 0->N or N->N+1 that happened AFTER our generation
    for t in transitions:
        if t["ts"] > first_gen_ts and t["to"] > t["from"]:
            result["video_appeared_after_gen"] = True
            result["video_added_ts"] = t["ts"]
            result["video_added_date"] = t["date"]
            delta = (t["ts"] - first_gen_ts) / 86400
            result["days_between_gen_and_video"] = round(delta, 1)
            break

    # If video was already there before gen, find when it was first added
    if not result["video_added_date"]:
        for t in transitions:
            if t["from"] == 0 and t["to"] > 0:
                result["video_added_ts"] = t["ts"]
                result["video_added_date"] = t["date"]
                break
        if not result["video_added_date"] and sorted_hist[0].get("content", {}).get("videos", 0) > 0:
            first_ts = sorted_hist[0]["ts"]
            result["video_added_date"] = f"before {datetime.fromtimestamp(first_ts, tz=timezone.utc).strftime('%Y-%m-%d')}"

    return result


def download_video(url: str, save_path: Path) -> bool:
    try:
        resp = requests.get(url, timeout=30, stream=True)
        if resp.status_code != 200:
            return False
        save_path.parent.mkdir(parents=True, exist_ok=True)
        with open(save_path, "wb") as f:
            for chunk in resp.iter_content(chunk_size=8192):
                f.write(chunk)
        return True
    except:
        return False


def get_video_info(filepath: str) -> dict:
    try:
        r = subprocess.run(
            ["ffprobe", "-v", "quiet", "-print_format", "json",
             "-show_format", "-show_streams", filepath],
            capture_output=True, text=True, timeout=10
        )
        data = json.loads(r.stdout)
        duration = float(data.get("format", {}).get("duration", 0))
        vs = next((s for s in data.get("streams", []) if s.get("codec_type") == "video"), {})
        return {"duration": round(duration, 3), "width": vs.get("width", 0), "height": vs.get("height", 0)}
    except:
        return {"duration": 0, "width": 0, "height": 0}


def try_download_all_videos(product_id: str, video_urls: list, save_dir: Path) -> list:
    """Download all known videos + try to find additional ones via direct URL pattern."""
    downloaded = []

    # Download from Sellematics-provided URLs
    for i, url in enumerate(video_urls):
        fname = f"video_{i+1}_360p.mp4"
        path = save_dir / fname
        if download_video(url, path):
            info = get_video_info(str(path))
            downloaded.append({
                "index": i + 1,
                "url": url,
                "path": str(path),
                "source": "sellematics",
                **info,
            })

    # Try to find additional videos by incrementing index in URL
    if video_urls:
        base_url = video_urls[0]
        # Try indices up to 3 (WB supports up to 3 videos)
        for idx in range(len(video_urls) + 1, 4):
            # Replace /1.mp4 with /2.mp4, /3.mp4 etc
            try_url = base_url.replace("/1.mp4", f"/{idx}.mp4")
            if try_url == base_url:
                break
            fname = f"video_{idx}_360p.mp4"
            path = save_dir / fname
            if download_video(try_url, path):
                info = get_video_info(str(path))
                downloaded.append({
                    "index": idx,
                    "url": try_url,
                    "path": str(path),
                    "source": "direct_probe",
                    **info,
                })

    return downloaded


def classify(analysis: dict, videos_downloaded: list) -> tuple:
    """Classify: CONFIRMED_OURS / LIKELY_OURS / PRE_EXISTING / UNCLEAR."""

    appeared_after = analysis.get("video_appeared_after_gen", False)
    days_delta = analysis.get("days_between_gen_and_video")
    was_before = analysis.get("video_was_present_before_gen")
    count_at_gen = analysis.get("video_count_at_gen_time", 0)
    count_now = analysis.get("video_count_now", 0)

    # Video appeared within 7 days of our generation
    if appeared_after and days_delta is not None and days_delta <= 7:
        if days_delta <= 3:
            return "CONFIRMED_OURS", f"video added {days_delta}d after gen"
        else:
            return "LIKELY_OURS", f"video added {days_delta}d after gen"

    # Video count increased (they had video before AND added more after our gen)
    if was_before and count_now > count_at_gen:
        return "LIKELY_OURS", f"video count {count_at_gen}->{count_now} (added after gen)"

    # Video was there before our generation
    if was_before:
        return "PRE_EXISTING", f"video present before gen (count={count_at_gen})"

    # Video appeared after gen but with long delay
    if appeared_after and days_delta is not None:
        return "UNCLEAR", f"video added {days_delta}d after gen (long delay)"

    return "UNCLEAR", "insufficient history data"


def main():
    now = datetime.now()
    now_str = now.strftime("%Y%m%d_%H%M%S")

    print("Loading products with video from report...")
    products = get_products_with_video_from_report()
    print(f"Found {len(products)} products with video\n")

    # Counters
    stats = {"CONFIRMED_OURS": 0, "LIKELY_OURS": 0, "PRE_EXISTING": 0, "UNCLEAR": 0}
    all_results = []

    for i, prod in enumerate(products):
        pid = prod["product_id"]
        name = prod["name"][:50]
        video_urls = prod.get("videos", [])
        progress = f"[{i+1}/{len(products)}]"

        gen_dates = get_generation_dates(pid)
        history = get_content_history(pid)
        analysis = analyze_video_history(history, gen_dates)

        # Download videos
        save_dir = Path(f"/mnt/video/wb_{pid}/downloaded-video/{now_str}")
        videos = try_download_all_videos(pid, video_urls, save_dir)

        verdict, reason = classify(analysis, videos)
        stats[verdict] += 1

        marker = {"CONFIRMED_OURS": "+++", "LIKELY_OURS": " + ", "PRE_EXISTING": " - ", "UNCLEAR": " ? "}
        print(f"{progress} [{marker[verdict]}] {pid} | {name}")
        if verdict in ("CONFIRMED_OURS", "LIKELY_OURS"):
            user = gen_dates[0]["username"] or gen_dates[0]["first_name"] if gen_dates else "?"
            print(f"         {reason} | @{user} | gen: {gen_dates[0]['date']}")
            for v in videos:
                print(f"         video #{v['index']}: {v['duration']}s {v['width']}x{v['height']} ({v['source']})")

        result = {
            "product_id": pid,
            "name": prod["name"],
            "wb_url": f"https://www.wildberries.ru/catalog/{pid}/detail.aspx",
            "verdict": verdict,
            "reason": reason,
            "analysis": analysis,
            "our_generations": gen_dates,
            "videos_downloaded": videos,
            "download_time": now.isoformat(),
        }
        all_results.append(result)

        # Save per-product log
        if videos:
            log_path = save_dir / "download_log.json"
            with open(log_path, "w", encoding="utf-8") as f:
                json.dump(result, f, ensure_ascii=False, indent=2, default=str)

        time.sleep(0.3)

    # Summary
    print(f"\n{'='*80}")
    print(f"SUMMARY: {len(products)} products with video analyzed")
    print(f"{'='*80}\n")
    print(f"  CONFIRMED OURS:  {stats['CONFIRMED_OURS']}")
    print(f"  LIKELY OURS:     {stats['LIKELY_OURS']}")
    print(f"  PRE-EXISTING:    {stats['PRE_EXISTING']}")
    print(f"  UNCLEAR:         {stats['UNCLEAR']}")
    total_ours = stats['CONFIRMED_OURS'] + stats['LIKELY_OURS']
    print(f"\n  Total likely ours: {total_ours} out of {len(products)} with video")

    # Detailed list of confirmed/likely
    if total_ours:
        print(f"\n{'='*80}")
        print(f"CONFIRMED + LIKELY OURS ({total_ours}):")
        print(f"{'='*80}\n")
        for r in all_results:
            if r["verdict"] in ("CONFIRMED_OURS", "LIKELY_OURS"):
                gens = r["our_generations"]
                user = gens[0]["username"] or gens[0]["first_name"] if gens else "?"
                a = r["analysis"]
                print(f"  {r['product_id']} | {r['name'][:50]}")
                print(f"    WB: {r['wb_url']}")
                print(f"    User: @{user} | Gen: {gens[0]['date']}")
                print(f"    Video added: {a.get('video_added_date')} ({r['reason']})")
                for v in r["videos_downloaded"]:
                    print(f"    Video #{v['index']}: {v['duration']}s {v['width']}x{v['height']}")
                print()

    # Save full report
    report_path = f"/tmp/wb_video_full_analysis_{now_str}.json"
    report = {
        "run_time": now.isoformat(),
        "total_products_with_video": len(products),
        "stats": stats,
        "total_likely_ours": total_ours,
        "results": all_results,
    }
    with open(report_path, "w", encoding="utf-8") as f:
        json.dump(report, f, ensure_ascii=False, indent=2, default=str)
    print(f"\nFull report: {report_path}")


if __name__ == "__main__":
    main()
