#!/usr/bin/env python3
"""
Verify that products Sellematics reported as "no video" truly have no video.
Uses card.json via the correct basket host (extracted from Sellematics image URLs).

Also checks products that Sellematics couldn't find (errors).
"""

import sqlite3
import requests
import re
import time
import json
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path

DB_PATH = "/mnt/video/videobot_prod.db"
SELLEMATICS_URL = "http://127.0.0.1:43761/api/v1"
EXCLUDE_USERS = {100000001, 100000002, 100000003}


def get_all_product_ids():
    """All unique product IDs from successful real-user generations."""
    conn = sqlite3.connect(DB_PATH)
    cur = conn.cursor()
    cur.execute("""
        SELECT DISTINCT t.product_id
        FROM transactions t
        WHERE t.type = 'generation'
          AND t.product_id IS NOT NULL 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
          )
    """.format(",".join(str(u) for u in EXCLUDE_USERS)))
    rows = cur.fetchall()
    conn.close()
    return [r[0] for r in rows]


def get_products_with_video():
    """Products already confirmed as having video from the full analysis."""
    with open('/tmp/wb_video_full_analysis_20260216_154052.json') as f:
        report = json.load(f)
    return {r['product_id'] for r in report['results']}


def check_product_via_sellematics(product_id: str) -> dict:
    """Get product from Sellematics, extract basket host from image URL, then check card.json."""
    result = {
        "product_id": product_id,
        "sellematics_videos": 0,
        "sellematics_countVideos": 0,
        "card_json_has_video": None,
        "basket_host": None,
        "error": None,
    }

    try:
        # Get from Sellematics
        resp = requests.post(
            f"{SELLEMATICS_URL}/products",
            data={"mall": "wb", "id": product_id},
            timeout=15,
        )
        if resp.status_code != 200 or not resp.text.strip():
            result["error"] = f"sellematics HTTP {resp.status_code}"
            return result

        data = resp.json()
        products = data.get("products", [])
        if not products:
            result["error"] = "not found in sellematics"
            return result

        current = products[0].get("current", {})
        result["sellematics_videos"] = len(current.get("videos", []))
        result["sellematics_countVideos"] = current.get("countVideos", 0)
        result["name"] = current.get("name", "?")

        # Extract basket host from image URL
        images = current.get("images", [])
        if not images:
            result["error"] = "no images in sellematics"
            return result

        # Parse: https://basket-32.wbbasket.ru/vol6457/part645744/645744957/images/big/1.webp
        m = re.match(r'https://(basket-\d+\.wbbasket\.ru)/vol(\d+)/part(\d+)/(\d+)/', images[0])
        if not m:
            result["error"] = f"cannot parse image URL: {images[0][:80]}"
            return result

        basket_host = m.group(1)
        vol = m.group(2)
        part = m.group(3)
        nm = m.group(4)
        result["basket_host"] = basket_host

        # Fetch card.json from the correct basket
        card_url = f"https://{basket_host}/vol{vol}/part{part}/{nm}/info/ru/card.json"
        card_resp = requests.get(card_url, timeout=10, headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        })

        if card_resp.status_code == 200:
            card_data = card_resp.json()
            media = card_data.get("media", {})
            result["card_json_has_video"] = media.get("has_video", False)
        elif card_resp.status_code == 404:
            result["error"] = "card.json 404"
        else:
            result["error"] = f"card.json HTTP {card_resp.status_code}"

    except Exception as e:
        result["error"] = str(e)[:100]

    return result


def main():
    print("Loading data...")
    all_pids = set(get_all_product_ids())
    already_checked = get_products_with_video()

    # Products NOT in the "with video" report = reported as no video or errors
    to_check = sorted(all_pids - already_checked)
    print(f"Total products: {len(all_pids)}")
    print(f"Already confirmed with video: {len(already_checked)}")
    print(f"Products to verify (no video / errors): {len(to_check)}\n")

    found_video = []
    confirmed_no_video = []
    errors = []

    with ThreadPoolExecutor(max_workers=4) as executor:
        futures = {}
        for i, pid in enumerate(to_check):
            futures[executor.submit(check_product_via_sellematics, pid)] = pid
            if i % 4 == 3:
                time.sleep(0.3)

        done = 0
        for future in as_completed(futures):
            done += 1
            r = future.result()

            has_video_sel = r["sellematics_videos"] > 0 or r["sellematics_countVideos"] > 0
            has_video_card = r.get("card_json_has_video")

            if has_video_sel or has_video_card:
                found_video.append(r)
                print(f"  FOUND VIDEO: {r['product_id']} (sel={r['sellematics_countVideos']}, card={has_video_card}) - {r.get('name','?')[:40]}")
            elif r["error"]:
                errors.append(r)
            else:
                confirmed_no_video.append(r)

            if done % 50 == 0:
                print(f"  Checked {done}/{len(to_check)} (found: {len(found_video)}, no video: {len(confirmed_no_video)}, errors: {len(errors)})")

    print(f"\n{'='*80}")
    print(f"VERIFICATION RESULTS")
    print(f"{'='*80}\n")
    print(f"  Checked: {len(to_check)}")
    print(f"  FOUND VIDEO (missed by previous check): {len(found_video)}")
    print(f"  Confirmed no video: {len(confirmed_no_video)}")
    print(f"  Errors: {len(errors)}")

    if found_video:
        print(f"\n  NEWLY FOUND VIDEOS:")
        for r in found_video:
            print(f"    {r['product_id']} | sel_videos={r['sellematics_countVideos']} | card_has_video={r['card_json_has_video']} | {r.get('name','?')[:50]}")

    # Summary with correct denominator
    total_with_video = len(already_checked) + len(found_video)
    total_products = len(all_pids)
    print(f"\n{'='*80}")
    print(f"FINAL NUMBERS")
    print(f"{'='*80}")
    print(f"  Total unique products (real users, successful): {total_products}")
    print(f"  Products with video on WB: {total_with_video} (prev {len(already_checked)} + new {len(found_video)})")
    print(f"  Products without video: {len(confirmed_no_video)}")
    print(f"  Unverifiable (errors): {len(errors)}")
    print(f"  Video presence rate: {total_with_video}/{total_products} = {total_with_video/total_products*100:.1f}%")

    # Save
    report = {
        "total_products": total_products,
        "previously_with_video": len(already_checked),
        "newly_found_video": len(found_video),
        "confirmed_no_video": len(confirmed_no_video),
        "errors": len(errors),
        "newly_found": [r for r in found_video],
        "error_products": [{"product_id": r["product_id"], "error": r["error"]} for r in errors],
    }
    with open("/tmp/wb_no_video_verify.json", "w") as f:
        json.dump(report, f, ensure_ascii=False, indent=2, default=str)
    print(f"\nReport: /tmp/wb_no_video_verify.json")


if __name__ == "__main__":
    main()
