import os
import sys
import json
import re
import httpx
import feedparser
import jdatetime

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from core.image_generator import create_story

CONFIG_DIR = os.path.join(BASE_DIR, 'config')
SETTINGS_FILE = os.path.join(CONFIG_DIR, 'settings.json')
HISTORY_FILE = os.path.join(CONFIG_DIR, 'history.json')
OUTPUT_DIR = os.path.join(BASE_DIR, 'outputs')
ASSETS_DIR = os.path.join(BASE_DIR, 'assets')

def load_json(path):
    if os.path.exists(path):
        with open(path, 'r', encoding='utf-8') as f:
            return json.load(f)
    return {}

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

def get_proxy_client(settings):
    net = settings.get("network", {})
    proxies = net.get("proxy_url") if net.get("use_proxy") else None
    return httpx.Client(proxy=proxies, timeout=45.0, follow_redirects=True)

def fetch_all_news(settings):
    """خواندن مستقیم فیدها بدون درگیر کردن بیهوده پروکسی برای سرعت بالا"""
    history = load_json(HISTORY_FILE)
    published_links = set(item.get("link") for item in history if isinstance(item, dict))
    
    rss_cfg = settings.get("rss", {})
    feeds = rss_cfg.get("feeds", [])
    news_limit = int(rss_cfg.get("news_per_feed", 5))
    
    all_news = []
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}
    
    # برای فیدها ریکوئست مستقیم می‌زنیم تا سایت‌های ایرانی تایم‌اوت نشوند
    with httpx.Client(timeout=15.0, follow_redirects=True) as client:
        for feed_obj in feeds:
            feed_url = feed_obj.get('url') if isinstance(feed_obj, dict) else feed_obj
            if not feed_url: continue
            try:
                resp = client.get(feed_url, headers=headers)
                feed = feedparser.parse(resp.content)
                for entry in feed.entries[:news_limit]:
                    link = entry.get('link', '')
                    if link in published_links:
                        continue
                    
                    image_url = None
                    if 'media_content' in entry and entry.media_content:
                        image_url = entry.media_content[0].get('url')
                    elif 'enclosures' in entry and entry.enclosures:
                        image_url = entry.enclosures[0].get('href')
                    elif 'description' in entry:
                        m = re.search(r'<img[^>]+src=["\'](.*?)["\']', entry.description)
                        if m:
                            image_url = m.group(1)
                            
                    all_news.append({
                        'title': entry.get('title', ''),
                        'summary': entry.get('summary', '') or entry.get('description', ''),
                        'link': link,
                        'image_url': image_url
                    })
            except Exception as e:
                print(f"[!] خطای فید {feed_url}: {e}")
                
    return all_news

def call_ai(settings, news_list):
    ai_cfg = settings.get("ai", {})
    active_ai = ai_cfg.get("active", "openai")
    topics = ai_cfg.get("topics", "فناوری و هوش مصنوعی")
    
    news_text = ""
    for idx, item in enumerate(news_list[:12], 1):
        news_text += f"{idx}. تیتر: {item['title']}\nخلاصه: {item['summary'][:180]}\nلینک: {item['link']}\n---\n"
        
    custom_prompt_tpl = ai_cfg.get("custom_prompt", "")
    prompt = custom_prompt_tpl.replace("{topics}", topics)
    prompt += f"\n\nاخبار موجود:\n{news_text}"

    # هوش مصنوعی همیشه با پروکسی فرانسه صدا زده می‌شود
    with get_proxy_client(settings) as client:
        if active_ai == "gemini":
            key = ai_cfg.get("gemini_key")
            if not key: raise Exception("کلید Gemini خالی است. لطفاً در پنل وارد کنید.")
            model = ai_cfg.get("gemini_model", "gemini-3.8-flash")
            url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={key}"
            res = client.post(
                url,
                headers={"Content-Type": "application/json"},
                json={"contents": [{"parts": [{"text": prompt + "\nخروجی حتما ساختار JSON باشد."}]}]}
            )
            data = res.json()
            if "error" in data:
                raise Exception(f"پاسخ خطای گوگل جمینی: {data['error'].get('message', 'خطای نامشخص')}")
                
            text = data['candidates'][0]['content']['parts'][0]['text']
            clean = re.sub(r'```json|```', '', text).strip()
            return json.loads(clean)
            
        elif active_ai == "openai":
            key = ai_cfg.get("openai_key")
            if not key: raise Exception("کلید OpenAI تنظیم نشده است.")
            model = ai_cfg.get("openai_model", "gpt-4o-mini")
            res = client.post(
                "https://api.openai.com/v1/chat/completions",
                headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
                json={
                    "model": model,
                    "messages": [{"role": "user", "content": prompt}],
                    "response_format": {"type": "json_object"}
                }
            )
            data = res.json()
            if "error" in data:
                raise Exception(f"پاسخ خطای OpenAI: {data['error'].get('message')}")
            return json.loads(data['choices'][0]['message']['content'])
            
        elif active_ai == "claude":
            key = ai_cfg.get("claude_key")
            if not key: raise Exception("کلید Claude تنظیم نشده است.")
            model = ai_cfg.get("claude_model", "claude-3-haiku-20240307")
            res = client.post(
                "https://api.anthropic.com/v1/messages",
                headers={"x-api-key": key, "anthropic-version": "2023-06-01", "Content-Type": "application/json"},
                json={"model": model, "max_tokens": 1000, "messages": [{"role": "user", "content": prompt}]}
            )
            data = res.json()
            if "error" in data:
                raise Exception(f"پاسخ خطای Claude: {data['error'].get('message')}")
            text = data['content'][0]['text']
            clean = re.sub(r'```json|```', '', text).strip()
            return json.loads(clean)

def download_article_image(settings, chosen_link, fallback_image_url):
    target_path = os.path.join(ASSETS_DIR, 'current_thumb.png')
    img_url = fallback_image_url
    
    with httpx.Client(timeout=15.0, follow_redirects=True) as client:
        if not img_url and chosen_link:
            try:
                r = client.get(chosen_link)
                m = re.search(r'<meta[^>]+property=["\']og:image["\'][^>]+content=["\'](.*?)["\']', r.text)
                if m:
                    img_url = m.group(1)
            except:
                pass
                
        if img_url:
            try:
                r = client.get(img_url)
                if r.status_code == 200:
                    with open(target_path, 'wb') as f:
                        f.write(r.content)
                    return target_path
            except:
                pass
                
    return os.path.join(ASSETS_DIR, 'new_thumb.png')

def publish_to_instagram(settings, story_image_url):
    ig = settings.get("instagram", {})
    if not ig.get("enabled"):
        return {"status": "skipped", "message": "انتشار خودکار غیرفعال است"}
        
    acc_id = ig.get("account_id")
    token = ig.get("access_token")
    if not acc_id or not token:
        return {"status": "error", "message": "اکانت ID یا توکن اینستاگرام خالی است"}
        
    with get_proxy_client(settings) as client:
        res1 = client.post(
            f"https://graph.facebook.com/v19.0/{acc_id}/media",
            params={"media_type": "STORIES", "image_url": story_image_url, "access_token": token}
        )
        data1 = res1.json()
        if "id" not in data1:
            return {"status": "error", "response": data1}
            
        creation_id = data1["id"]
        res2 = client.post(
            f"https://graph.facebook.com/v19.0/{acc_id}/media_publish",
            params={"creation_id": creation_id, "access_token": token}
        )
        return {"status": "published", "response": res2.json()}

def run_pipeline():
    settings = load_json(SETTINGS_FILE)
    print("[*] در حال دریافت اخبار تازه از فیدها...")
    news = fetch_all_news(settings)
    
    if not news:
        return {"success": False, "message": "هیچ خبر تازه‌ای در فیدها پیدا نشد."}
        
    print(f"[*] {len(news)} خبر آماده شد. ارسال به {settings.get('ai', {}).get('active')}...")
    ai_result = call_ai(settings, news)
    
    title = ai_result.get("title", "خبر تکنولوژی")
    summary = ai_result.get("summary", "")
    chosen_link = ai_result.get("chosen_link", "")
    
    fallback_img = None
    for n in news:
        if n['link'] == chosen_link:
            fallback_img = n['image_url']
            break
            
    print(f"[*] خبر گلچین شد: {title}")
    print("[*] دریافت تصویر خبر...")
    thumb_path = download_article_image(settings, chosen_link, fallback_img)
    
    filename = f"story_{jdatetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
    output_path = create_story(thumb_path, title, summary, filename)
    
    public_url = f"https://sc.zimaxweb.ir/outputs/{filename}"
    ig_result = publish_to_instagram(settings, public_url)
    
    history = load_json(HISTORY_FILE)
    history.insert(0, {
        "title": title,
        "summary": summary,
        "link": chosen_link,
        "image_file": filename,
        "image_url": public_url,
        "created_at": jdatetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
        "instagram_status": ig_result.get("status", "none")
    })
    save_json(HISTORY_FILE, history[:50])
    
    return {
        "success": True,
        "title": title,
        "summary": summary,
        "image": filename,
        "url": public_url,
        "instagram": ig_result
    }

if __name__ == "__main__":
    res = run_pipeline()
    print(json.dumps(res, ensure_ascii=False, indent=2))
