"""Alıntı tweet yorumu üretir.

Kaynağın (ör. resmi yayıncı) tweet'ini alıntılarken üstüne yazacağımız kendi
yorumumuz burada üretilir. İki kural mimariye gömülü:

1. KAYNAK METNİ KOPYALANMAZ. LLM olayı kendi cümleleriyle yazar; kaynak
   metin yalnızca bağlam olarak verilir.
2. VİDEO/GÖRSEL ÇOĞALTILMAZ. Medya alıntı yoluyla kaynağın hesabından oynar;
   biz sadece link veririz.
"""
import logging

from sqlalchemy.orm import Session

from app.db import models, crud
from app.content_engine import generator, textutil
import config

log = logging.getLogger("content.quote")

# Tweet 280; t.co linki 23 karakter sayılır + boşluk + etiket payı
MAX_LEN = 230
SKIP_TOKEN = "ATLA"

SYSTEM_PROMPT = (
    "Sen bir Türk futbol haber ajansısın. Sana resmi yayıncının paylaştığı bir "
    "video gönderisinin metni veriliyor. Sen bu olayı KENDİ TWEETİN olarak "
    "anlatacaksın; tweetin sonuna videonun linki eklenecek.\n\n"
    "KURALLAR:\n"
    "- Verilen metni KOPYALAMA ve yeniden yazma. Olayı kendi cümlelerinle, "
    "kendi üslubunla anlat.\n"
    "- Tweet KENDİ BAŞINA ANLAŞILIR olsun: kim, ne yaptı, hangi maç, skor. "
    "Okuyan videoyu açmadan ne olduğunu anlasın.\n"
    "- UYDURMA YASAĞI: yalnızca verilen bilgileri kullan. Maçın gidişatı "
    "hakkında elinde veri yok — 'baskılıydı', 'nefes kesen mücadele', "
    "'hâkimiyet kurdu' gibi görmediğin şeyleri yazma.\n"
    "- Videoya yönlendiren kısa bir ifade doğal ('izleyin', 'işte o an').\n"
    "- En fazla 180 karakter. 1-2 uygun emoji. Abartı ve klişe yok.\n"
    "- SATIR DÜZENİ: olayı ilk satıra yaz, skor/bağlam varsa ALT SATIRA "
    "geçir. Tek blok duvar metin yazma; en fazla 2 satır.\n"
    "- Sadece tweet metnini döndür; tırnak, başlık, hashtag, LİNK ekleme "
    "(etiketi ve linki sistem kendisi ekleyecek).\n\n"
    f"Şu durumlarda SADECE '{SKIP_TOKEN}' yaz:\n"
    f"- Futbolla ilgisizse\n"
    f"- Stüdyo yorumu / röportaj (konuşan kişi) içeriğiyse\n"
    f"- Kaynağın kendi sitesine/uygulamasına YÖNLENDİRME ise "
    f"('İzlemek için:', 'Detaylar için:', 'ÖZET BURADA', link tıklatma)\n\n"
    f"Gol/aksiyon videoları ve skor kartı/istatistik görselleri PAYLAŞILIR."
)


def _prompt(item: models.SourceTweet, match: models.Match | None) -> str:
    parts = [f"Kaynak hesap: @{item.handle}", f"Gönderi metni: {item.text}"]
    if item.media == "video":
        parts.append("Tweetine VİDEO eklenecek; 'izleyin/videoda' gibi "
                     "yönlendirme uygun.")
    elif item.media == "photo":
        parts.append("Tweetine GÖRSEL eklenecek (video YOK); 'videoda/izleyin' "
                     "YAZMA, olayı/skoru anlat.")
    if match:
        parts.append(
            f"İlgili maç: {match.home_team} {match.home_score or 0}-"
            f"{match.away_score or 0} {match.away_team}"
            f" ({match.league.name if match.league else ''})"
        )
    parts.append(f"İçerik türü: {item.kind}")
    return "\n".join(parts)


_FALLBACK = {
    "goal": "⚽ İşte o gol!",
    "action": "👀 Maçın o anı!",
    "summary": "📺 Maçın özeti",
    "interview": "🎙️ Maç sonu açıklamaları",
    "studio": "💬 Değerlendirme",
    "other": "👀",
}


def build_tweet(comment: str, item: models.SourceTweet,
                match: models.Match | None) -> tuple[str, str]:
    """(tweet metni, gönderime eklenecek görsel URL'si) döner.

    Alıntı kartı KULLANILMAZ: kart kaynağın gönderisini olduğu gibi gömüyor,
    bizim tweetimiz onun tekrarı gibi duruyordu.
    - VİDEO: metnin sonuna /video/1 linki (X'in kabul ettiği, kart
      oluşturmayan tek biçim — canlı test edildi).
    - FOTOĞRAF: link YOK (düz status linki karta dönüşüyor); görselin
      kendisi indirilip kendi tweetimize eklenir (kullanıcı kararı).
    - Medyasız: paylaşacak bir şey yok, boş döner — çağıran atlar.
    """
    text = _with_tag(comment, match)
    if item.media == "video":
        return f"{text}\n{item.video_url}", ""
    if item.media == "photo" and item.media_url:
        return text, item.media_url
    return "", ""


def _with_tag(text: str, match: models.Match | None) -> str:
    """Maçın resmi etiketini boş satırdan sonra ekle (#BJKvEYP)."""
    tag = (match.hashtag if match else "") or ""
    return textutil.append_tags(text, [tag] if tag else [], MAX_LEN)


def write_comment(db: Session, item: models.SourceTweet) -> str | None:
    """Alıntı yorumu üretir. Atlanacaksa None."""
    match = db.get(models.Match, item.match_id) if item.match_id else None
    engine = crud.get_setting(db, "content_engine", "deepseek")
    api_key = crud.get_setting(db, "deepseek_api_key", "")

    if engine == "deepseek" and api_key:
        try:
            client = generator._get_client(api_key)
            # Reasoning payı için bol bütçe (yalnız üretilen kadar ödenir);
            # 800'de yarım kalan metinler görülmüştü.
            resp = client.chat.completions.create(
                model=config.DEEPSEEK_MODEL,
                messages=[
                    {"role": "system", "content": SYSTEM_PROMPT},
                    {"role": "user", "content": _prompt(item, match)},
                ],
                temperature=0.9,
                max_tokens=10000,
            )
            choice = resp.choices[0]
            if choice.finish_reason == "length":
                crud.add_log(db, "Alıntı yorumu sınıra takıldı (10k!), atlandı",
                             level="warn", source="sources")
                return None
            text = (choice.message.content or "").strip().strip('"').strip()
            if not text:
                return None
            if SKIP_TOKEN in text.upper()[:20]:
                return None
            # Kaynağın marka etiketi (#beINSPORTS) bizim tweetimizde yer almaz
            handles = [h for (h,) in db.query(models.SourceAccount.handle).all()]
            text = textutil.strip_hashtags(
                text, textutil.block_tags_from_sources(handles))
            return _with_tag(textutil.normalize(text), match)
        except Exception as e:
            crud.add_log(db, f"Alıntı yorumu (DeepSeek) hatası: {e}",
                         level="warn", source="sources")

    # LLM yoksa: maç bilgisiyle sade bir giriş
    base = _FALLBACK.get(item.kind, _FALLBACK["other"])
    if match:
        base = (f"{match.home_team} {match.home_score or 0}-"
                f"{match.away_score or 0} {match.away_team} · {base}")
    return _with_tag(base, match)
