"""DB yardımcı fonksiyonları: ayarlar, hesaplar, ligler, loglar."""
from datetime import datetime
from sqlalchemy.orm import Session
from app.db import models
from app.core import security


# ---------------------------------------------------------------- Ayarlar
DEFAULT_SETTINGS = {
    # otomasyon
    "automation_mode": ("auto", False),        # auto | approval
    "posting_enabled": ("false", False),       # ana açma/kapama (güvenli başlangıç: kapalı)
    "active_hours_start": ("8", False),        # gece uykusu
    "active_hours_end": ("24", False),
    "min_gap_seconds": ("90", False),          # ana akış: min bekleme
    "max_gap_seconds": ("400", False),         # ana akış: jitter üst sınır
    # Thread yanıtları ana akışı doldurmaz; canlı maçta gol anında gitsin diye
    # çok daha kısa aralık kullanılır.
    "reply_min_gap_seconds": ("15", False),
    "reply_max_gap_seconds": ("45", False),
    "daily_post_cap": ("120", False),          # hesap başına günlük tavan
    # içerik
    "deepseek_api_key": ("", True),            # ŞİFRELİ
    "content_engine": ("deepseek", False),     # deepseek | template
    "budget_enabled": ("true", False),         # akıllı bütçe planı açık mı
    "sources_enabled": ("true", False),        # izlenen hesap alıntıları
    # Görsel üretimi (Wiro.ai) — maç önü/devre arası/maç sonu kartları
    "wiro_api_key": ("", True),                # ŞİFRELİ
    "images_enabled": ("true", False),
    "images_per_day": ("60", False),          # goller de görselli -> yüksek
    # Saatlik kaynak paylaşımı tavanı. Yoğun bir Süper Lig gününde ~9 maçta
    # ~23 gol atılıyor ve bunların hepsi paylaşmaya değer içerik. Thread
    # şeridi saatte ~95 tweet kaldırdığı için darboğaz kapasite değil;
    # bu sayı yalnızca aşırı yığılmaya karşı emniyet supabı.
    "quotes_per_hour": ("12", False),
    "news_per_hour": ("2", False),             # saatlik haber tweeti tavanı
    "news_enabled": ("true", False),           # haber paylaşımı açık mı
    "tone_prompt": (
        "Sen profesyonel bir Türk spor ajansısın. Heyecanlı ama abartısız, "
        "doğal Türkçe ile kısa tweetler yazarsın. Klişe ve bot gibi tekrar etmezsin. "
        "Emoji ve hashtag'i dengeli kullanırsın.",
        False,
    ),
}


def get_setting(db: Session, key: str, default: str = "") -> str:
    row = db.get(models.Setting, key)
    if not row:
        return default
    if row.is_secret:
        return security.decrypt(row.value)
    return row.value


def set_setting(db: Session, key: str, value: str, is_secret: bool = False):
    row = db.get(models.Setting, key)
    stored = security.encrypt(value) if is_secret else value
    if row:
        row.value = stored
        row.is_secret = is_secret
        row.updated_at = datetime.utcnow()
    else:
        row = models.Setting(key=key, value=stored, is_secret=is_secret)
        db.add(row)
    return row


def ensure_default_settings(db: Session):
    for key, (val, secret) in DEFAULT_SETTINGS.items():
        if not db.get(models.Setting, key):
            db.add(models.Setting(
                key=key,
                value=security.encrypt(val) if (secret and val) else val,
                is_secret=secret,
            ))


def all_settings(db: Session) -> dict:
    out = {}
    for row in db.query(models.Setting).all():
        out[row.key] = security.decrypt(row.value) if row.is_secret else row.value
    return out


# ---------------------------------------------------------------- Ligler
DEFAULT_LEAGUES = [
    # (key, name, country, priority)
    ("super_lig", "Trendyol Süper Lig", "Türkiye", 1),
    ("trendyol_1lig", "Trendyol 1. Lig", "Türkiye", 2),
    ("ucl", "UEFA Şampiyonlar Ligi", "Avrupa", 1),
    ("uel", "UEFA Avrupa Ligi", "Avrupa", 2),
    ("uecl", "UEFA Konferans Ligi", "Avrupa", 3),
    ("premier_league", "Premier Lig", "İngiltere", 3),
    ("la_liga", "La Liga", "İspanya", 3),
    ("serie_a", "Serie A", "İtalya", 3),
    ("bundesliga", "Bundesliga", "Almanya", 3),
    ("ligue_1", "Ligue 1", "Fransa", 4),
]


# ---------------------------------------------------------------- kaynak hesaplar
DEFAULT_SOURCES = [
    # (handle, etiket)  — otomatik alıntı VARSAYILAN KAPALI; kullanıcı açar
    ("beINSPORTS_TR", "beIN Sports Türkiye (resmi yayıncı)"),
]


def ensure_default_sources(db: Session):
    existing = {s.handle for s in db.query(models.SourceAccount.handle).all()}
    for handle, label in DEFAULT_SOURCES:
        if handle not in existing:
            db.add(models.SourceAccount(
                handle=handle, label=label, enabled=True, auto_quote=False,
            ))


def ensure_default_leagues(db: Session):
    existing = {l.key for l in db.query(models.League.key).all()}
    for key, name, country, prio in DEFAULT_LEAGUES:
        if key not in existing:
            db.add(models.League(
                key=key, name=name, country=country, priority=prio,
                enabled=True, provider="sofascore",
            ))


# ---------------------------------------------------------------- Hesaplar
def create_account(db: Session, label, username, auth_token, ct0, notes=""):
    acc = models.Account(
        label=label.strip(),
        username=username.strip().lstrip("@"),
        auth_token_enc=security.encrypt(auth_token.strip()),
        ct0_enc=security.encrypt(ct0.strip()),
        notes=notes,
        status="unknown",
    )
    db.add(acc)
    db.commit()
    db.refresh(acc)
    return acc


def account_cookies(acc: models.Account) -> dict:
    return {
        "auth_token": security.decrypt(acc.auth_token_enc),
        "ct0": security.decrypt(acc.ct0_enc),
    }


# ---------------------------------------------------------------- Loglar
def add_log(db: Session, message: str, level: str = "info", source: str = ""):
    """Log yazar (çağıranın oturumunda; SQLite tek yazar kilidi nedeniyle ayrı
    oturum kullanılamaz — kilitlenir).

    Dikkat: commit ettiği için çağıranın bekleyen değişikliklerini de kalıcı
    yapar. Yarım kalmış iş varken log yazan taraf ÖNCE rollback etmelidir
    (bkz. scheduler/manager.py::_safe)."""
    db.add(models.LogEntry(message=message, level=level, source=source))
    db.commit()
