#!/usr/bin/env python3
"""Bridge Feishu image messages into xhs_flow.py.

The Feishu app must have the ``im.message.receive_v1`` event enabled. The listener
only accepts user-sent standalone images and keeps the generated task local until
the operator explicitly chooses to send the Feishu review notification.
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path
import subprocess
import sys
from typing import Optional


ROOT = Path(__file__).resolve().parent


def fetch_image(message_id: str, identity: str) -> Optional[Path]:
    command = [
        "lark-cli", "im", "+messages-mget", "--as", identity,
        "--message-ids", message_id, "--download-resources", "--format", "json",
    ]
    result = subprocess.run(command, cwd=ROOT, capture_output=True, text=True)
    if result.returncode:
        print(result.stderr.strip(), file=sys.stderr)
        return None
    try:
        envelope = json.loads(result.stdout)
        messages = envelope.get("data", {}).get("messages", [])
        for message in messages:
            for resource in message.get("resources", []):
                if resource.get("type") == "image" and not resource.get("error"):
                    return ROOT / resource["local_path"]
    except (json.JSONDecodeError, KeyError, TypeError):
        print("Could not parse message resource response", file=sys.stderr)
    return None


def run_flow(photo: Path, args: argparse.Namespace) -> None:
    command = [sys.executable, "xhs_flow.py", "ingest", str(photo), "--identity", args.notify_identity]
    if args.product_name:
        command += ["--product-name", args.product_name]
    if args.notify_user_id:
        command += ["--user-id", args.notify_user_id]
        if args.send:
            command.append("--send")
    result = subprocess.run(command, cwd=ROOT, text=True)
    if result.returncode:
        print(f"Flow failed for {photo}", file=sys.stderr)


def parser() -> argparse.ArgumentParser:
    root = argparse.ArgumentParser(description="监听飞书图片并启动小红书内容流程")
    root.add_argument("--sender-id", help="只处理指定发送人的 open_id")
    root.add_argument("--notify-user-id", help="审核通知接收人的 open_id")
    root.add_argument("--notify-identity", choices=["user", "bot"], default="user")
    root.add_argument("--product-name")
    root.add_argument("--send", action="store_true", help="实际发送审核通知；默认 dry-run")
    root.add_argument("--once", action="store_true", help="处理一张图片后退出，便于测试")
    return root


def main() -> None:
    args = parser().parse_args()
    command = ["lark-cli", "event", "consume", "im.message.receive_v1", "--as", "bot"]
    if args.once:
        command += ["--max-events", "1", "--timeout", "10m"]
    process = subprocess.Popen(command, cwd=ROOT, stdout=subprocess.PIPE, text=True)
    assert process.stdout is not None
    for line in process.stdout:
        try:
            event = json.loads(line)
        except json.JSONDecodeError:
            continue
        if event.get("message_type") != "image" or event.get("sender_type") != "user":
            continue
        if args.sender_id and event.get("sender_id") != args.sender_id:
            continue
        message_id = event.get("message_id")
        if not message_id:
            continue
        photo = fetch_image(message_id, "bot")
        if photo and photo.exists():
            print(f"Received image: {photo}")
            run_flow(photo, args)
            if args.once:
                break
    if args.once and process.poll() is None:
        process.terminate()


if __name__ == "__main__":
    main()
