#!/usr/bin/env python3
"""
V2: Targeted construction timelapse video finder.
Strategy: Focus on KNOWN high-yield construction creators + deep pagination.
"""

import httpx
import json
import time
from datetime import datetime

API_KEY = "vUELI81uMMWm8tQkgj3N6BXAsag1"
BASE_URL = "https://api.scrapecreators.com"
HEADERS = {"x-api-key": API_KEY, "Content-Type": "application/json"}

MIN_VIEWS = 1_000_000
MIN_DURATION_MS = 50_000
MAX_DURATION_MS = 90_000

credits_used = 0

# ── Verified construction timelapse creators from Phase 1+2 results ──
# These are REAL accounts that had construction content
VERIFIED_CREATORS = [
    # Heavy hitters - bunker/container/house builds
    "vukovic_vlad",          # 10 vids, 80M+ top, bunker builds
    "superconstructions",    # 6 vids, construction timelapse
    "buildrescue",           # 3 vids, bunker builds
    "build_inseconds",       # 3 vids, construction timelapse
    "knowledge.sharingss",   # 3 vids, transformations
    "coolhurstuk",           # 3 vids, container houses
    "caselucasrobinson",     # 3 vids, home build
    "stamperhome",           # 3 vids, home build + pool
    "emgraceyoung",          # 3 vids, barndominium
    "lance_ramsey",          # 4 vids, custom homes
    "quocthien2508",         # 3 vids, construction/renovation
    "farisandlisa",          # 1 vid, house build 151 days
    "timelapse.studio6",     # 1 vid, pallet builds
    "surfaceflowoficial",    # 2 vids, container homes
    "camxot_01",             # 1 vid, epoxy/construction
    "builder.c",             # 1 vid, thermos house
    "le_estatehomes",        # 1 vid, french home design
    "dust2dreamy",           # 1 vid, backyard makeover
    "winnidesigns",          # 1 vid, shelves install
    "sabrinaanoelle",        # 3 vids, house build
    "graciehknight",         # 4 vids, house build
    "prestonkonrad",         # 4 vids, home renovation
    "barefoot___wanderer",   # 1 vid, house build
    "tommyharr05",           # 1 vid, real estate/construction
]

# ── Additional creators to discover via targeted search ──
TARGETED_SEARCHES = [
    # Very specific construction timelapse queries
    "bunker build timelapse",
    "underground bunker construction",
    "container home build timelapse",
    "shipping container house build",
    "house build foundation to finish",
    "house build 0 to 100",
    "construction timelapse viral 2025",
    "construction timelapse viral 2024",
    "house build complete process",
    "satisfying construction compilation",
    "house build couple first time",
    "custom home build progress",
    "house build drone view",
    "building our dream home timelapse",
    "construction site timelapse camera",
    "house build day by day",
    "swimming pool construction complete",
    "house renovation before after",
    "house flip transformation",
    "concrete house build",
    "wooden house construction timelapse",
    "barn conversion timelapse",
    "house addition construction",
    "house build australia timelapse",
    "house build uk complete",
    "3d printed house construction",
    "insulation construction timelapse",
    "house build winter",
    "underground house build",
    "a frame house build",
    "earthship build timelapse",
    "log cabin build start to finish",
    "modular home construction",
    "prefab house assembly timelapse",
    "house build budget",
    "first time builder house",
    "self build house timelapse",
    "one man house build",
    "solo house build",
    "house build 30 days",
]


def api_request(endpoint, params=None):
    global credits_used
    for attempt in range(3):
        try:
            with httpx.Client(timeout=60) as client:
                resp = client.get(f"{BASE_URL}{endpoint}", params=params, headers=HEADERS)
                if resp.status_code == 200:
                    credits_used += 1
                    return resp.json()
                elif resp.status_code == 429:
                    print(f"    Rate limited, waiting 5s...")
                    time.sleep(5)
                elif resp.status_code == 404:
                    return None
                else:
                    print(f"    API {resp.status_code}")
                    return None
        except Exception as e:
            print(f"    Error: {e}")
            if attempt < 2:
                time.sleep(2)
    return None


def extract_video(item, source="search", fallback_user=""):
    if not isinstance(item, dict):
        return None

    vid_id = item.get("aweme_id", item.get("id", ""))
    stats = item.get("statistics", {})
    views = stats.get("play_count", 0)
    likes = stats.get("digg_count", 0)
    collects = stats.get("collect_count", 0)
    shares = stats.get("share_count", 0)
    comments = stats.get("comment_count", 0)

    video_obj = item.get("video", {})
    duration_ms = video_obj.get("duration", 0) if isinstance(video_obj, dict) else 0

    author = item.get("author", {})
    username = (author.get("unique_id", "") or author.get("uniqueId", "") or fallback_user) if isinstance(author, dict) else fallback_user
    nickname = author.get("nickname", "") if isinstance(author, dict) else ""

    desc = item.get("desc", "")
    url = item.get("url", item.get("share_url", ""))
    if not url and vid_id and username:
        url = f"https://www.tiktok.com/@{username}/video/{vid_id}"
    # Clean URL
    if url and "?" in url:
        url = url.split("?")[0]

    return {
        "id": str(vid_id),
        "url": url,
        "views": int(views),
        "likes": int(likes),
        "collects": int(collects),
        "shares": int(shares),
        "comments": int(comments),
        "duration_ms": int(duration_ms),
        "duration_s": round(int(duration_ms) / 1000),
        "username": username,
        "nickname": nickname,
        "description": str(desc)[:200],
    }


def is_construction(text):
    text = text.lower()
    # Strong construction indicators
    strong = ["construct", "build", "house", "bunker", "container home",
              "foundation", "concrete", "framing", "mansion", "barn",
              "renovation", "remodel", "roof", "brick", "drywall",
              "plumbing", "flooring", "basement", "custom home",
              "pool", "deck", "cabin", "shed", "garage",
              "insulation", "excavat", "lumber", "siding",
              "timelapse", "time lapse", "time-lapse",
              "construção", "casa", "obra", "reforma",
              "thi công", "xây", "cải tạo",  # Vietnamese (quocthien)
              "shelv", "install", "epoxy", "tile"]
    return any(kw in text for kw in strong)


def qualifies(v):
    return (v["views"] >= MIN_VIEWS and
            MIN_DURATION_MS <= v["duration_ms"] <= MAX_DURATION_MS)


def main():
    print("=" * 70)
    print("CONSTRUCTION TIMELAPSE V2 - TARGETED APPROACH")
    print(f"Views: {MIN_VIEWS/1e6:.0f}M+ | Duration: {MIN_DURATION_MS//1000}-{MAX_DURATION_MS//1000}s")
    print("=" * 70)

    all_videos = {}
    all_creators = set()

    # ── Step 1: Deep-scrape verified creators (up to 200 videos each) ──
    print(f"\n▶ STEP 1: Deep-scraping {len(VERIFIED_CREATORS)} verified creators...")

    for i, username in enumerate(VERIFIED_CREATORS):
        print(f"\n  [{i+1}/{len(VERIFIED_CREATORS)}] @{username}...")

        cursor = "0"
        page = 0
        creator_vids = 0
        creator_total = 0

        while page < 10:  # Up to 500 videos
            params = {"handle": username, "count": 50}
            if cursor and cursor != "0":
                params["cursor"] = cursor

            data = api_request("/v1/tiktok/profile/videos", params)
            time.sleep(1)

            if not data or not isinstance(data, dict):
                break

            aweme_list = data.get("aweme_list", [])
            has_more = data.get("has_more", 0)
            next_cursor = str(data.get("max_cursor", "0"))

            if not aweme_list:
                if page == 0:
                    print(f"    No videos found")
                break

            creator_total += len(aweme_list)

            for item in aweme_list:
                v = extract_video(item, "profile", username)
                if not v or not v["id"]:
                    continue
                if qualifies(v) and v["id"] not in all_videos:
                    all_videos[v["id"]] = v
                    creator_vids += 1
                    all_creators.add(username)
                    print(f"    ✓ {v['views']/1e6:.1f}M | {v['duration_s']}s | {v['description'][:55]}")

            if not has_more or next_cursor == cursor:
                break
            cursor = next_cursor
            page += 1

        print(f"    → {creator_vids} qualifying (from {creator_total} checked, {page+1} pages)")

    print(f"\n  Step 1: {len(all_videos)} videos from {len(all_creators)} creators")

    # ── Step 2: Search for more creators and their videos ──
    print(f"\n▶ STEP 2: Searching {len(TARGETED_SEARCHES)} targeted queries...")

    new_creators_found = set()

    for i, query in enumerate(TARGETED_SEARCHES):
        print(f"\n  [{i+1}/{len(TARGETED_SEARCHES)}] '{query}'")
        data = api_request("/v1/tiktok/search/top", {"query": query, "count": 30})
        time.sleep(1)

        if not data or not isinstance(data, dict):
            continue

        items = data.get("items", [])
        search_vids = 0

        for item in items:
            v = extract_video(item)
            if not v or not v["id"]:
                continue

            if qualifies(v) and v["id"] not in all_videos:
                if is_construction(v["description"]):
                    all_videos[v["id"]] = v
                    search_vids += 1
                    all_creators.add(v["username"])

                    # If new creator, scrape their profile too
                    if v["username"] and v["username"] not in new_creators_found and v["username"] not in set(VERIFIED_CREATORS):
                        new_creators_found.add(v["username"])

        if search_vids > 0:
            print(f"    → {search_vids} qualifying videos")

    print(f"\n  Step 2: {len(all_videos)} total videos, {len(new_creators_found)} new creators to scrape")

    # ── Step 3: Scrape new creators found in search ──
    if new_creators_found:
        print(f"\n▶ STEP 3: Scraping {len(new_creators_found)} new creators...")

        for i, username in enumerate(sorted(new_creators_found)):
            print(f"\n  [{i+1}/{len(new_creators_found)}] @{username}...")

            cursor = "0"
            page = 0
            creator_vids = 0

            while page < 5:
                params = {"handle": username, "count": 50}
                if cursor and cursor != "0":
                    params["cursor"] = cursor

                data = api_request("/v1/tiktok/profile/videos", params)
                time.sleep(1)

                if not data or not isinstance(data, dict):
                    break

                aweme_list = data.get("aweme_list", [])
                has_more = data.get("has_more", 0)
                next_cursor = str(data.get("max_cursor", "0"))

                if not aweme_list:
                    break

                for item in aweme_list:
                    v = extract_video(item, "profile", username)
                    if not v or not v["id"]:
                        continue
                    if qualifies(v) and v["id"] not in all_videos:
                        all_videos[v["id"]] = v
                        creator_vids += 1
                        print(f"    ✓ {v['views']/1e6:.1f}M | {v['duration_s']}s | {v['description'][:55]}")

                if not has_more or next_cursor == cursor:
                    break
                cursor = next_cursor
                page += 1

            if creator_vids > 0:
                print(f"    → {creator_vids} qualifying")

    # ── Generate output ──
    sorted_videos = sorted(all_videos.values(), key=lambda x: x["views"], reverse=True)

    if not sorted_videos:
        print("\n❌ No qualifying videos found!")
        return

    all_links = [v["url"] for v in sorted_videos if v["url"]]
    total_views = sum(v["views"] for v in sorted_videos)
    unique_creators = len(set(v["username"] for v in sorted_videos if v["username"]))

    # ── HTML Generation ──
    html = f"""<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Construction Timelapse - {len(sorted_videos)} Viral Videos</title>
    <style>
        * {{ margin: 0; padding: 0; box-sizing: border-box; }}
        body {{ font-family: 'Segoe UI', sans-serif; background: #0f0f23; color: #e0e0e0; padding: 20px; }}
        h1 {{ color: #7c3aed; margin-bottom: 10px; font-size: 24px; }}
        .stats {{
            background: #1a1a3e; padding: 15px 20px; border-radius: 12px;
            margin-bottom: 20px; display: flex; gap: 30px; flex-wrap: wrap;
        }}
        .stat {{ text-align: center; }}
        .stat-value {{ font-size: 28px; font-weight: bold; color: #7c3aed; }}
        .stat-label {{ font-size: 12px; color: #888; }}
        .copy-section {{
            background: #1a1a3e; border-radius: 12px; padding: 20px; margin-bottom: 20px;
        }}
        .copy-section h2 {{ color: #7c3aed; margin-bottom: 10px; font-size: 18px; }}
        .copy-btn {{
            background: #7c3aed; color: white; border: none; padding: 12px 24px;
            border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: bold;
            margin-bottom: 15px; margin-right: 10px;
        }}
        .copy-btn:hover {{ background: #6d28d9; }}
        .copy-btn.copied {{ background: #22c55e; }}
        .links-box {{
            background: #0a0a1a; border: 1px solid #333; border-radius: 8px;
            padding: 15px; max-height: 400px; overflow-y: auto;
            font-family: monospace; font-size: 13px; line-height: 1.8;
            white-space: pre-wrap; word-break: break-all; user-select: all;
        }}
        .video-table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
        .video-table th {{
            background: #1a1a3e; color: #7c3aed; padding: 10px; text-align: left;
            position: sticky; top: 0; z-index: 1;
        }}
        .video-table td {{ padding: 8px 10px; border-bottom: 1px solid #222; font-size: 13px; }}
        .video-table tr:hover {{ background: #1a1a2e; }}
        .views {{ color: #22c55e; font-weight: bold; }}
        .duration {{ color: #f59e0b; }}
        a {{ color: #818cf8; text-decoration: none; }}
        a:hover {{ text-decoration: underline; }}
        .filter-bar {{
            background: #1a1a3e; padding: 15px; border-radius: 12px;
            margin-bottom: 20px; display: flex; gap: 15px; align-items: center; flex-wrap: wrap;
        }}
        .filter-bar label {{ font-size: 13px; color: #888; }}
        .filter-bar select, .filter-bar input {{
            background: #0a0a1a; color: #e0e0e0; border: 1px solid #333;
            padding: 6px 10px; border-radius: 6px;
        }}
    </style>
</head>
<body>
    <h1>Construction Timelapse - Viral Videos</h1>
    <p style="color:#888; margin-bottom:20px;">Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')} | Credits: ~{credits_used}</p>

    <div class="stats">
        <div class="stat"><div class="stat-value">{len(sorted_videos)}</div><div class="stat-label">Videos</div></div>
        <div class="stat"><div class="stat-value">{unique_creators}</div><div class="stat-label">Creators</div></div>
        <div class="stat"><div class="stat-value">{total_views/1e9:.1f}B</div><div class="stat-label">Total Views</div></div>
        <div class="stat"><div class="stat-value">{sorted_videos[0]['views']/1e6:.0f}M</div><div class="stat-label">Top Video</div></div>
    </div>

    <div class="copy-section">
        <h2>Links para Download em Massa</h2>
        <button class="copy-btn" onclick="copyLinks(this)">COPIAR TODOS OS {len(all_links)} LINKS</button>
        <button class="copy-btn" style="background:#059669;" onclick="copySelected(this)">Copiar Selecionados</button>
        <div class="links-box" id="all-links">{chr(10).join(all_links)}</div>
    </div>

    <div class="filter-bar">
        <label>Min Views:</label>
        <select id="filterViews" onchange="filterTable()">
            <option value="1000000">1M+</option>
            <option value="5000000">5M+</option>
            <option value="10000000">10M+</option>
            <option value="50000000">50M+</option>
        </select>
        <label>Creator:</label>
        <input type="text" id="filterCreator" placeholder="@username" oninput="filterTable()">
        <label>Descricao:</label>
        <input type="text" id="filterDesc" placeholder="keyword" oninput="filterTable()">
        <span id="filterCount" style="color:#7c3aed;font-weight:bold;margin-left:10px;"></span>
    </div>

    <table class="video-table" id="videoTable">
        <thead><tr>
            <th><input type="checkbox" id="selectAll" onchange="toggleAll(this)"></th>
            <th>#</th><th>Creator</th><th>Views</th><th>Likes</th><th>Dur</th><th>Description</th><th>Link</th>
        </tr></thead>
        <tbody>
"""

    for i, v in enumerate(sorted_videos, 1):
        views_str = f"{v['views']/1e6:.1f}M"
        likes_str = f"{v['likes']/1e6:.1f}M" if v['likes'] >= 1e6 else f"{v['likes']/1e3:.0f}K"
        desc_safe = v['description'].replace('&', '&amp;').replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;')

        html += f"""            <tr data-views="{v['views']}" data-creator="{v['username']}" data-desc="{desc_safe.lower()}" data-url="{v['url']}">
                <td><input type="checkbox" class="vid-check" data-url="{v['url']}"></td>
                <td>{i}</td>
                <td><a href="https://tiktok.com/@{v['username']}" target="_blank">@{v['username']}</a></td>
                <td class="views">{views_str}</td>
                <td>{likes_str}</td>
                <td class="duration">{v['duration_s']}s</td>
                <td title="{desc_safe}">{desc_safe[:80]}</td>
                <td><a href="{v['url']}" target="_blank">Abrir</a></td>
            </tr>
"""

    html += """        </tbody>
    </table>
    <script>
        function copyLinks(btn) {
            const text = document.getElementById('all-links').textContent;
            navigator.clipboard.writeText(text).then(() => {
                btn.textContent = 'COPIADO!'; btn.classList.add('copied');
                setTimeout(() => { btn.textContent = 'COPIAR TODOS OS """ + str(len(all_links)) + """ LINKS'; btn.classList.remove('copied'); }, 2000);
            });
        }
        function copySelected(btn) {
            const checks = document.querySelectorAll('.vid-check:checked');
            const urls = Array.from(checks).map(c => c.dataset.url).join('\\n');
            if (!urls) { alert('Selecione pelo menos um video!'); return; }
            navigator.clipboard.writeText(urls).then(() => {
                btn.textContent = checks.length + ' COPIADOS!'; btn.classList.add('copied');
                setTimeout(() => { btn.textContent = 'Copiar Selecionados'; btn.classList.remove('copied'); }, 2000);
            });
        }
        function toggleAll(cb) {
            document.querySelectorAll('.vid-check').forEach(c => {
                if (c.closest('tr').style.display !== 'none') c.checked = cb.checked;
            });
        }
        function filterTable() {
            const minV = parseInt(document.getElementById('filterViews').value);
            const cr = document.getElementById('filterCreator').value.toLowerCase().replace('@','');
            const desc = document.getElementById('filterDesc').value.toLowerCase();
            let count = 0;
            document.querySelectorAll('#videoTable tbody tr').forEach(row => {
                const show = parseInt(row.dataset.views) >= minV &&
                    (!cr || row.dataset.creator.includes(cr)) &&
                    (!desc || row.dataset.desc.includes(desc));
                row.style.display = show ? '' : 'none';
                if (show) count++;
            });
            document.getElementById('filterCount').textContent = count + ' videos';
        }
        filterTable();
    </script>
</body>
</html>"""

    output_path = "/home/glauko/viral-social/data/construction_timelapse_videos.html"
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(html)

    json_path = "/home/glauko/viral-social/data/construction_timelapse_videos.json"
    with open(json_path, "w", encoding="utf-8") as f:
        json.dump({
            "generated": datetime.now().isoformat(),
            "total_videos": len(sorted_videos),
            "total_creators": unique_creators,
            "credits_used": credits_used,
            "videos": sorted_videos,
        }, f, indent=2, ensure_ascii=False)

    print(f"\n{'='*70}")
    print(f"DONE!")
    print(f"  Videos: {len(sorted_videos)}")
    print(f"  Creators: {unique_creators}")
    print(f"  Total views: {total_views/1e9:.1f}B")
    print(f"  Credits used: ~{credits_used}")
    print(f"\n  HTML: {output_path}")
    print(f"  JSON: {json_path}")
    print(f"\n  Access at: https://viral.chatys.com.br/data/construction_timelapse_videos.html")
    print(f"{'='*70}")

    print(f"\nTOP 20:")
    for i, v in enumerate(sorted_videos[:20], 1):
        print(f"  {i}. @{v['username']}: {v['views']/1e6:.1f}M views | {v['duration_s']}s | {v['description'][:50]}")


if __name__ == "__main__":
    main()
