#!/usr/bin/env python3
"""Analyze video content via Qwen3-VL model using OpenAI-compatible API."""

import argparse
import json
import os
import sys
import urllib.request
import urllib.error

DEFAULT_MODEL = "Qwen3-VL-235B-A22B-Instruct"
OPENCLAW_CONFIG = os.path.expanduser("/home/node/.openclaw/openclaw.json")
UPLOAD_URL = "https://www.sophnet.com/api/open-apis/projects/upload"

def _build_multipart(file_path: str) -> tuple:
    """Build multipart/form-data body for file upload. Returns (body_bytes, content_type)."""
    boundary = f"----PythonFormBoundary{os.urandom(16).hex()}"
    file_name = os.path.basename(file_path)

    lines = []
    lines.append(f"--{boundary}")
    lines.append(f'Content-Disposition: form-data; name="file"; filename="{file_name}"')
    lines.append("Content-Type: application/octet-stream")
    lines.append("")

    header = "\r\n".join(lines).encode("utf-8") + b"\r\n"
    footer = f"\r\n--{boundary}--\r\n".encode("utf-8")

    with open(file_path, "rb") as f:
        file_data = f.read()

    body = header + file_data + footer
    content_type = f"multipart/form-data; boundary={boundary}"
    return body, content_type


def upload_oss(file_path: str, api_key: str = None) -> str:
    """Upload a file to OSS and return the signed URL."""
    if not os.path.isfile(file_path):
        print(f"错误: 文件 '{file_path}' 不存在或不是一个文件。", file=sys.stderr)
        sys.exit(1)
    if not api_key:
        _, api_key = load_openclaw_config()

    if not api_key:
        print("错误: 上传需要 API key，请提供 --api-key 或配置 ~/.openclaw/openclaw.json",
              file=sys.stderr)
        sys.exit(1)

    try:
        body, content_type = _build_multipart(file_path)
    except IOError as e:
        print(f"错误: 无法读取文件 - {e}", file=sys.stderr)
        sys.exit(1)

    req = urllib.request.Request(
        UPLOAD_URL,
        data=body,
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": content_type,
        },
        method="POST",
    )

    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            resp_data = resp.read().decode("utf-8")
    except urllib.error.HTTPError as e:
        resp_body = e.read().decode("utf-8", errors="replace")
        print(f"上传失败: HTTP {e.code}", file=sys.stderr)
        print(f"服务器响应: {resp_body}", file=sys.stderr)
        sys.exit(1)
    except urllib.error.URLError as e:
        print(f"错误: 网络请求异常 - {e.reason}", file=sys.stderr)
        sys.exit(1)

    try:
        json_data = json.loads(resp_data)
    except ValueError:
        print("错误: 服务器返回的不是有效的 JSON 格式", file=sys.stderr)
        print(f"响应内容: {resp_data[:200]}...", file=sys.stderr)
        sys.exit(1)

    result = json_data.get("result")
    if not result or not isinstance(result, dict):
        print("错误: 响应中缺少 'result' 字段或格式错误", file=sys.stderr)
        sys.exit(1)

    signed_url = result.get("signedUrl")
    if not signed_url:
        print("错误: 未返回有效的 signedUrl", file=sys.stderr)
        sys.exit(1)

    return signed_url

def load_openclaw_config():
    """Load API credentials from openclaw.json."""
    if not os.path.exists(OPENCLAW_CONFIG):
        return None, None
    with open(OPENCLAW_CONFIG, "r") as f:
        config = json.load(f)
    providers = config.get("models", {}).get("providers", {})
    sophnet = providers.get("sophnet", {})
    return sophnet.get("baseUrl"), sophnet.get("apiKey")


def call_video_understand(video_url, prompt, base_url=None, api_key=None):
    if not base_url or not api_key:
        cfg_url, cfg_key = load_openclaw_config()
        base_url = base_url or cfg_url
        api_key = api_key or cfg_key

    if not base_url or not api_key:
        print("Error: API base URL and key are required. "
              "Provide --base-url/--api-key or configure ~/.openclaw/openclaw.json",
              file=sys.stderr)
        sys.exit(1)

    endpoint = f"{base_url.rstrip('/')}/chat/completions"

    payload = {
        "model": DEFAULT_MODEL,
        "messages": [
            {
                "role": "user",
                "content": [
                    {
                        "type": "video_url",
                        "video_url": {"url": video_url}
                    },
                    {
                        "type": "text",
                        "text": prompt
                    }
                ]
            }
        ]
    }

    data = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(
        endpoint,
        data=data,
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {api_key}"
        },
        method="POST"
    )

    try:
        with urllib.request.urlopen(req, timeout=300) as resp:
            result = json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        print(f"API error {e.code}: {body}", file=sys.stderr)
        sys.exit(1)
    except urllib.error.URLError as e:
        print(f"Request failed: {e.reason}", file=sys.stderr)
        sys.exit(1)

    choices = result.get("choices", [])
    if not choices:
        print("No response from model.", file=sys.stderr)
        sys.exit(1)

    content = choices[0].get("message", {}).get("content", "")
    print(content)

    # usage = result.get("usage")
    # if usage:
    #     print(f"\n--- Token usage: prompt={usage.get('prompt_tokens', '?')}, "
    #           f"completion={usage.get('completion_tokens', '?')}, "
    #           f"total={usage.get('total_tokens', '?')} ---",
    #           file=sys.stderr)


def main():
    parser = argparse.ArgumentParser(description="Analyze video content with Qwen3-VL")
    video_source = parser.add_mutually_exclusive_group(required=True)
    video_source.add_argument("--video-url", help="Public URL of the video")
    video_source.add_argument("--video-file", help="Local path to a video file (will be uploaded to OSS first)")
    parser.add_argument("--prompt", required=True, help="Question or instruction about the video")
    parser.add_argument("--base-url", default=None, help="Override API base URL")
    parser.add_argument("--api-key", default=None, help="Override API key")
    args = parser.parse_args()

    video_url = args.video_url
    if args.video_file:
        print(f"正在上传视频文件: {args.video_file} ...", file=sys.stderr)
        video_url = upload_oss(args.video_file, api_key=args.api_key)
        print(f"上传完成，获取到视频 URL{video_url}", file=sys.stderr)

    call_video_understand(
        video_url=video_url,
        prompt=args.prompt,
        base_url=args.base_url,
        api_key=args.api_key,
    )


if __name__ == "__main__":
    main()
