#!/usr/bin/env python3
"""
=============================================================
 Telegram Broadcaster Script (Channels & Groups)
 learn-lexicore.bytronex.com
=============================================================
"""

import os
import sys
import json
import random
import requests
import argparse
from datetime import datetime
from typing import Optional, Tuple, List

# ── مسارات الملفات ──────────────────────────────────────
SCRIPT_DIR  = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE  = os.path.join(SCRIPT_DIR, "social_config.json")
PROGRESS_FILE = os.path.join(SCRIPT_DIR, "tg_broadcast_progress.json")
LOG_FILE     = os.path.join(SCRIPT_DIR, "tg_broadcast.log")

# مسار الكلمات المشترك (من مجلد الووردبريس)
KEYWORDS_FILE = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "wp_auto_poster", "keywords.txt"))
# مسار الصور
OUTPUT_IMAGES_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "output-images"))

# Session for connection pooling
http_session = requests.Session()


def log(msg: str, level: str = "INFO"):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    line = f"[{timestamp}] [{level}] {msg}"
    print(line)
    with open(LOG_FILE, "a", encoding="utf-8") as f:
        f.write(line + "\n")


def load_json(path: str) -> dict:
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def save_json(path: str, data: dict):
    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def pick_next_keyword(keywords: list, progress: dict) -> Tuple[str, int]:
    last_index = progress.get("last_index", -1)
    next_index = (last_index + 1) % len(keywords)
    return keywords[next_index], next_index


def pick_random_image() -> Optional[str]:
    """يختار صورة عشوائية من مجلد alcpt بشكل رئيسي أو أي مجلد آخر."""
    if not os.path.exists(OUTPUT_IMAGES_DIR):
        log(f"Images folder not found: {OUTPUT_IMAGES_DIR}", "ERROR")
        return None
        
    categories = [d for d in os.listdir(OUTPUT_IMAGES_DIR) if os.path.isdir(os.path.join(OUTPUT_IMAGES_DIR, d))]
    if not categories:
        return None
        
    # Priority: lexicore_app -> alcpt -> random
    if "lexicore_app" in categories:
        cat = "lexicore_app"
    elif "alcpt" in categories:
        cat = "alcpt"
    else:
        cat = random.choice(categories)
        
    cat_path = os.path.join(OUTPUT_IMAGES_DIR, cat)
    
    images = [f for f in os.listdir(cat_path) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.webp'))]
    if not images:
        cat = random.choice(categories)
        cat_path = os.path.join(OUTPUT_IMAGES_DIR, cat)
        images = [f for f in os.listdir(cat_path) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.webp'))]
        if not images:
            return None

    return f"{cat}/{random.choice(images)}"


def generate_telegram_caption(cfg: dict, keyword: str) -> str:
    """يولد وصف مختصر وتفاعلي لجروبات التيليجرام."""
    api_key = cfg["groq"]["api_key"]
    model   = cfg["groq"].get("model", "llama-3.3-70b-versatile")

    prompt = f"""You are an expert English teacher for military personnel (ALCPT/ALC).
Write a VERY SHORT, engaging broadcast message for a Telegram Group regarding: "{keyword}"

REQUIREMENTS:
- Language: English
- Tone: Exciting, helpful, encouraging
- Length: Max 2 short sentences. Get straight to the point.
- Include 1-2 emojis
- Include 3 hashtags (e.g., #ALCPT #LexiCore)
- End with this EXACT text in Arabic for the CTA (preserve the emojis):

⬇️ أقوى تطبيق لتعلم وتجاوز اختبارات ALCPT ⬇️
🍎 الأيفون (iOS): https://apps.apple.com/us/app/alcpt-cat-practice-lexicore/id6761208858
📱 أندرويد (تحميل): https://play.google.com/store/apps/details?id=com.bytronex.lexicore

OUTPUT:
Return ONLY the raw caption text. Do not use markdown code blocks or wrappers.
"""

    url = "https://api.groq.com/openai/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    payload = {
        "model": model,
        "messages": [
            {"role": "system", "content": "You output direct plain text only without meta-commentary."},
            {"role": "user", "content": prompt}
        ],
        "temperature": 0.7,
        "max_completion_tokens": 500
    }

    log(f"Generating Telegram broadcast caption for: '{keyword}'")
    resp = http_session.post(url, headers=headers, json=payload, timeout=60)
    resp.raise_for_status()

    raw = resp.json()
    return raw["choices"][0]["message"]["content"].strip()


def broadcast_to_telegram(bot_token: str, chat_ids: List[str], image_url: str, caption: str) -> int:
    """يقوم بالبث إلى قائمة من Chat IDs."""
    success_count = 0
    url = f"https://api.telegram.org/bot{bot_token}/sendPhoto"
    
    for chat_id in chat_ids:
        if not chat_id or "YOUR_" in chat_id or "GROUP_" in chat_id:
            continue
            
        payload = {
            "chat_id": chat_id,
            "photo": image_url,
            "caption": caption[:1024]
        }
        
        try:
            resp = http_session.post(url, data=payload, timeout=30)
            if resp.status_code == 200:
                log(f"✅ Broadcast success to chat: {chat_id}")
                success_count += 1
            else:
                log(f"❌ Broadcast failed to {chat_id}: {resp.text}", "ERROR")
        except Exception as e:
            log(f"❌ Exception broadcasting to {chat_id}: {e}", "ERROR")
            
    return success_count


def send_admin_notification(cfg: dict, message: str):
    """إرسال إشعارات عبر اليوزربوت (باسم @haarods)."""
    # البحث عن إعدادات اليوزربوت في ملف الإعدادات
    tg_u = cfg.get("telegram_userbot", {})
    if not tg_u.get("enabled"): return

    api_id = tg_u.get("api_id")
    api_hash = tg_u.get("api_hash")
    # نرسل الإشعار للحساب نفسه للتأكد
    targets = ["@haarods"]
    
    if not api_id or not api_hash: return

    import asyncio
    try:
        from telethon import TelegramClient
    except ImportError:
        return

    async def _send():
        # نستخدم نفس مسار الجلسة الموحد
        session_path = os.path.join(SCRIPT_DIR, 'lexicore_userbot')
        client = TelegramClient(session_path, api_id, api_hash)
        await client.connect()
        if not await client.is_user_authorized():
            return
        for target in targets:
            try:
                await client.send_message(target, message, parse_mode='html')
            except:
                pass
        await client.disconnect()

    try:
        loop = asyncio.get_event_loop()
        if loop.is_running():
            asyncio.ensure_future(_send())
        else:
            loop.run_until_complete(_send())
    except:
        pass


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args()

    if not os.path.exists(CONFIG_FILE):
        log("social_config.json not found", "ERROR")
        sys.exit(1)

    cfg = load_json(CONFIG_FILE)
    tg_cfg = cfg.get("telegram", {})
    
    if not tg_cfg.get("enabled"):
        log("Telegram is disabled in config.", "WARNING")
        sys.exit(0)
        
    bot_token = tg_cfg.get("bot_token")
    if not bot_token or "YOUR_" in bot_token:
        log("Invalid Telegram bot_token in config.", "ERROR")
        sys.exit(1)

    broadcast_groups = tg_cfg.get("broadcast_groups", [])
    valid_groups = [g for g in broadcast_groups if g and "YOUR_" not in g and "GROUP_" not in g]
    
    # دائماً نرسل لمالك النظام كنسخة احتياطية
    admin_id = tg_cfg.get("chat_id")
    if admin_id and "YOUR_" not in admin_id and admin_id not in valid_groups:
        valid_groups.append(admin_id)

    if not valid_groups and not args.dry_run:
        log("No valid broadcast_groups or chat_id found in config. Add them first.", "ERROR")
        sys.exit(1)

    if not os.path.exists(KEYWORDS_FILE):
        log("keywords.txt not found", "ERROR")
        sys.exit(1)

    with open(KEYWORDS_FILE, "r", encoding="utf-8") as f:
        keywords = [l.strip() for l in f if l.strip()]

    progress = load_json(PROGRESS_FILE) if os.path.exists(PROGRESS_FILE) else {"last_index": -1, "broadcasts": []}
    
    keyword, index = pick_next_keyword(keywords, progress)
    log(f"Broadcast keyword [{index+1}/{len(keywords)}]: '{keyword}'")

    rel_img_path = pick_random_image()
    if not rel_img_path:
        log("No image could be assigned. Exiting.", "ERROR")
        sys.exit(1)
        
    base_url = cfg.get("settings", {}).get("base_image_url", "").rstrip("/")
    image_url = f"{base_url}/{rel_img_path}"
    log(f"Broadcast Image URL: {image_url}")

    try:
        caption = generate_telegram_caption(cfg, keyword)
    except Exception as e:
        log(f"Groq API Error: {e}", "ERROR")
        sys.exit(1)

    if args.dry_run:
        log("[DRY RUN] Would broadcast to Telegram groups:")
        print(f"\n--- IMAGE URL ---\n{image_url}\n")
        print(f"--- CAPTION ---\n{caption}\n")
        print(f"--- TARGETS ---\n{valid_groups}\n")
        return

    success_count = broadcast_to_telegram(bot_token, valid_groups, image_url, caption)
    
    if success_count > 0:
        progress["last_index"] = index
        progress["broadcasts"].append({
            "date": datetime.now().isoformat(),
            "keyword": keyword,
            "image": rel_img_path,
            "success_count": success_count,
            "targets": valid_groups
        })
        save_json(PROGRESS_FILE, progress)
        log(f"Broadcast sync complete! Reached {success_count} chats.")
        
        # Admin Notification
        notif_msg = f"🚀 <b>تم النشر بنجاح (برودكاست)!</b>\n\n" \
                    f"📝 <b>الكلمة:</b> {keyword}\n" \
                    f"✅ <b>المنصات:</b> Telegram (Public Channels)\n" \
                    f"🔗 <b>الرابط:</b> <a href='{image_url}'>الصورة المستخدمة</a>"
        send_admin_notification(cfg, notif_msg)
    else:
        log("Broadcast failed. No chats were reached.", "WARNING")

if __name__ == "__main__":
    main()
