#!/usr/bin/env python3
import json
import os
import re
import subprocess
import sys
import time
import urllib.request
from pathlib import Path

PROJECT_ROOT = Path('/Users/bot1/Volumes/root_for_ai/AI工作区/通用_产品宣传视频_古钱币杜邦纸钱袋包_20260530_1702')
SKILL_SCRIPTS = Path('/Users/bot1/.hermes/backups/seedance_default_remove_libtv_20260522_184712/locked-skills/creative/libtv-skill/scripts')
sys.path.insert(0, str(SKILL_SCRIPTS))

from _common import query_session, build_project_url
from download_results import extract_urls_from_messages, download_file

OUT_DIR = PROJECT_ROOT / 'outputs/libtv-seedance-4x15-20260530_174949'
SUMMARY_PATH = OUT_DIR / 'submission_summary.json'
POLL_STATUS_PATH = OUT_DIR / 'poll_status.json'
LATEST_QUERY_PATH = OUT_DIR / 'latest_query.json'
VIDEO_DIR = OUT_DIR / 'videos'


def ffprobe(path: Path) -> dict:
    cmd = [
        'ffprobe', '-v', 'error', '-show_entries',
        'format=duration:stream=codec_type,width,height',
        '-of', 'json', str(path)
    ]
    try:
        res = subprocess.run(cmd, text=True, capture_output=True, timeout=30)
        if res.returncode != 0:
            return {'ok': False, 'error': res.stderr.strip()}
        data = json.loads(res.stdout)
        video_stream = next((s for s in data.get('streams', []) if s.get('codec_type') == 'video'), {})
        audio_stream = next((s for s in data.get('streams', []) if s.get('codec_type') == 'audio'), None)
        return {
            'ok': True,
            'duration': float(data.get('format', {}).get('duration', 0) or 0),
            'width': video_stream.get('width'),
            'height': video_stream.get('height'),
            'has_audio': audio_stream is not None,
        }
    except Exception as e:
        return {'ok': False, 'error': str(e)}


def download_videos(urls):
    VIDEO_DIR.mkdir(parents=True, exist_ok=True)
    downloaded = []
    errors = []
    for idx, url in enumerate(urls, 1):
        ext = os.path.splitext(url.split('?')[0])[-1] or '.mp4'
        path = VIDEO_DIR / f'coin_pouch_seedance_segment_{idx:02d}{ext}'
        if path.exists() and path.stat().st_size > 0:
            downloaded.append(str(path))
            continue
        fp, err = download_file(url, str(path))
        if err:
            errors.append({'url': url, 'file': str(path), 'error': err})
        else:
            downloaded.append(fp)
    return downloaded, errors


def main():
    if not SUMMARY_PATH.exists():
        raise SystemExit(f'submission_summary_missing: {SUMMARY_PATH}')
    summary = json.loads(SUMMARY_PATH.read_text(encoding='utf-8'))
    session_id = summary.get('session_id')
    project_uuid = summary.get('project_uuid')
    markers = [s.get('marker') for s in summary.get('submitted_segments', []) if s.get('marker')]
    if not session_id:
        raise SystemExit('missing session_id in summary')

    first_marker = markers[0] if markers else ''
    known_video_urls = []
    max_polls = 80  # about 26 minutes at 20 sec intervals
    final_status = 'poll_timeout'
    downloaded = []
    errors = []

    for poll in range(1, max_polls + 1):
        try:
            data = query_session(session_id, after_seq=0)
        except SystemExit:
            raise
        except Exception as e:
            data = {'error': str(e), 'messages': []}
        LATEST_QUERY_PATH.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding='utf-8')
        messages = data.get('messages') or []

        # Ignore anything before this batch's first user marker if the session had older history.
        rel = messages
        if first_marker:
            start_idx = None
            for i, msg in enumerate(messages):
                if first_marker in (msg.get('content') or ''):
                    start_idx = i
                    break
            if start_idx is not None:
                rel = messages[start_idx:]

        urls = extract_urls_from_messages(rel)
        video_urls = []
        for u in urls:
            clean = u.split('?')[0].lower()
            if clean.endswith(('.mp4', '.mov', '.webm')) and u not in video_urls:
                video_urls.append(u)

        # Keep all videos seen so far, preserving order.
        for u in video_urls:
            if u not in known_video_urls:
                known_video_urls.append(u)

        status = {
            'status': 'polling',
            'poll': poll,
            'session_id': session_id,
            'project_uuid': project_uuid,
            'project_url': build_project_url(project_uuid),
            'video_url_count': len(known_video_urls),
            'video_urls': known_video_urls,
            'updated_at': time.strftime('%Y-%m-%dT%H:%M:%S%z'),
        }
        POLL_STATUS_PATH.write_text(json.dumps(status, ensure_ascii=False, indent=2), encoding='utf-8')
        print(json.dumps(status, ensure_ascii=False), flush=True)

        if len(known_video_urls) >= 4:
            final_status = 'completed'
            break
        time.sleep(20)

    if known_video_urls:
        # Download all known; if more than 4 appeared, keep all but first four are expected segments.
        downloaded, errors = download_videos(known_video_urls)

    probes = []
    for p in downloaded:
        path = Path(p)
        probes.append({'file': p, 'bytes': path.stat().st_size if path.exists() else 0, 'ffprobe': ffprobe(path) if path.exists() else {'ok': False, 'error': 'missing'}})

    final = {
        'status': final_status,
        'session_id': session_id,
        'project_uuid': project_uuid,
        'project_url': build_project_url(project_uuid),
        'video_urls': known_video_urls,
        'downloaded': downloaded,
        'errors': errors,
        'ffprobe': probes,
        'completed_at': time.strftime('%Y-%m-%dT%H:%M:%S%z'),
    }
    POLL_STATUS_PATH.write_text(json.dumps(final, ensure_ascii=False, indent=2), encoding='utf-8')
    print(json.dumps(final, ensure_ascii=False, indent=2), flush=True)
    return 0 if final_status == 'completed' else 2


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