#!/usr/bin/env python3
"""
PKA Podcast Email Watcher
Polls the inbox via himalaya for new Patreon PKA/PKN emails,
extracts YouTube links, and adds them to the RSS feed.
"""

import json
import os
import re
import subprocess
import sys
from pathlib import Path

BASE_DIR = Path("/mnt/storage/nzbdav/pka-podcast")
sys.path.insert(0, str(BASE_DIR))
import add_episode as pka_core


def get_envelopes(page_size=20):
    cmd = ["himalaya", "--account", "firemail", "envelope", "list", "-m", "INBOX", "-s", str(page_size), "--json"]
    try:
        res = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        if res.returncode != 0:
            print(f"Error listing envelopes: {res.stderr}", file=sys.stderr)
            return []
        data = json.loads(res.stdout)
        if isinstance(data, dict):
            return data.get("envelopes", [])
        return data if isinstance(data, list) else []
    except Exception as e:
        print(f"Failed to fetch envelopes: {e}", file=sys.stderr)
        return []


def read_message(msg_id):
    cmd = ["himalaya", "--account", "firemail", "message", "read", str(msg_id), "--json"]
    try:
        res = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        if res.returncode != 0:
            return ""
        data = json.loads(res.stdout)
        return json.dumps(data)
    except Exception as e:
        print(f"Failed reading message {msg_id}: {e}", file=sys.stderr)
        return ""


def extract_youtube_urls(text):
    patterns = [
        r'https?://(?:www\.)?youtube\.com/watch\?v=([A-Za-z0-9_-]{11})[^\s"<>]*',
        r'https?://youtu\.be/([A-Za-z0-9_-]{11})[^\s"<>]*',
    ]
    urls = []
    for pat in patterns:
        for m in re.finditer(pat, text):
            urls.append(m.group(0))
    # Deduplicate preserving order
    seen = set()
    deduped = []
    for u in urls:
        if u not in seen:
            seen.add(u)
            deduped.append(u)
    return deduped


def clean_title(subject):
    # Strip Fwd: / Re: prefixes
    s = re.sub(r'^(?:fwd|re):\s*', '', subject, flags=re.IGNORECASE).strip()
    return s


def backfill_mp3s():
    """Extract mp3s for any episodes missing them (added before mp3 support).
    Mp3s stay on disk for direct use; the feed is video-only. Returns True if any extracted."""
    state = pka_core.load_state()
    changed = False
    for ep in state.get("episodes", []):
        if ep.get("mp3_filename"):
            continue
        video = pka_core.EPISODES_DIR / ep["filename"]
        if not video.exists():
            print(f"Video missing, skipping mp3 backfill: {ep['filename']}", file=sys.stderr)
            continue
        mp3_path = pka_core.extract_mp3(video)
        if mp3_path:
            ep["mp3_filename"] = mp3_path.name
            ep["mp3_size"] = pka_core.get_file_size(mp3_path)
            changed = True
    if changed:
        pka_core.save_state(state)
    return changed


def run_check():
    pka_core.ensure_dirs()
    backfill_mp3s()
    state = pka_core.load_state()
    existing_vids = {ep.get("video_id") for ep in state.get("episodes", []) if ep.get("video_id")}

    envelopes = get_envelopes(page_size=30)
    if not envelopes:
        return []

    added = []

    for env in envelopes:
        subj = env.get("subject", "")
        # Look for PKN or PKA in subject
        if not re.search(r'\b(PKA|PKN)\s*#?\d+', subj, re.IGNORECASE):
            continue

        msg_id = env.get("id")
        if not msg_id:
            continue

        raw_msg = read_message(msg_id)
        if not raw_msg:
            continue

        yt_urls = extract_youtube_urls(raw_msg)
        if not yt_urls:
            continue

        target_url = yt_urls[0]
        vid = pka_core.extract_video_id(target_url)
        if not vid or vid in existing_vids:
            continue

        title = clean_title(subj)
        print(f"Found new episode in email: '{title}' -> {target_url}")
        success = pka_core.add_episode(target_url, title)
        if success:
            added.append(title)
            existing_vids.add(vid)

    return added


if __name__ == "__main__":
    new_eps = run_check()
    if new_eps:
        print(f"Added {len(new_eps)} episode(s): {', '.join(new_eps)}")
    else:
        # Silent when nothing added
        pass
