"""Günlük içerik — maçlara bağlı olmayan planlı paylaşımlar.

- morning_fixture : sabah, o gün oynanacak öne çıkan maçlar
- evening_results : akşam, gün içinde biten maçların skorları
- standings       : haftalık, açık liglerin puan durumu

Bu içerikler Post olarak doğrudan kuyruğa girer (MatchEvent üzerinden gitmez);
aynı gün ikinci kez üretilmemesi için kind+tarih kontrolü yapılır.
"""
import logging
from datetime import datetime, timedelta

from sqlalchemy.orm import Session

from app.db import models, crud
from app.core import timeutil
from app.content_engine import templates
from app.data_engine import sofascore as ss

log = logging.getLogger("scheduler.daily")

MAX_MATCHES = 30   # thread'e bölünür; yine de makul bir üst sınır


def _already_today(db: Session, kind: str) -> bool:
    start, _ = timeutil.tr_day_bounds_utc()
    return (
        db.query(models.Post.id)
        .filter(models.Post.kind == kind, models.Post.created_at >= start)
        .first()
        is not None
    )


def _queue(db: Session, kind: str, text: str) -> bool:
    if not text:
        return False
    db.add(models.Post(content=text[:280], kind=kind, status="queued"))
    db.commit()
    crud.add_log(db, f"Günlük içerik kuyruğa alındı: {kind}", source="scheduler")
    return True


def _queue_thread(db: Session, kind: str, header: str, lines: list[str]) -> bool:
    """Uzun listeyi thread olarak kuyruğa alır.

    20 maçlık bir cumartesi programı tek tweete sığmıyor; 8 maçta kesip
    gerisini atmak yerine parçalara bölünüp thread yapılır.
    """
    if not lines:
        return False

    chunks, current = [], []
    # İlk parçada başlık da yer alacağı için payı düşülür.
    budget = 280 - len(header) - 12
    for line in lines:
        candidate = current + [line]
        if len("\n".join(candidate)) > budget and current:
            chunks.append(current)
            current = [line]
            budget = 268          # sonraki parçalarda başlık yok
        else:
            current = candidate
    if current:
        chunks.append(current)

    parent_id = None
    for i, chunk in enumerate(chunks):
        body = "\n".join(chunk)
        if i == 0:
            content = f"{header}\n{body}"
        else:
            content = f"({i + 1}/{len(chunks)})\n{body}"
        post = models.Post(
            content=content[:280], kind=kind, status="queued",
            reply_to_post_id=parent_id, is_reply=parent_id is not None,
        )
        db.add(post)
        db.flush()               # id lazım: sonraki parça buna yanıt verecek
        parent_id = post.id
    db.commit()
    crud.add_log(db, f"Günlük içerik kuyruğa alındı: {kind} ({len(chunks)} parça)",
                 source="scheduler")
    return True


def _tr_time(dt: datetime) -> str:
    return timeutil.fmt_tr(dt, "%H:%M")


# ------------------------------------------------------------------ sabah programı
def morning_fixture(db: Session) -> bool:
    """O gün oynanacak maçların listesi. Öncelikli liglerden seçer."""
    if _already_today(db, "daily_fixture"):
        return False
    now = datetime.utcnow()
    _, end = timeutil.tr_day_bounds_utc(now)
    matches = (
        db.query(models.Match)
        .join(models.League, models.Match.league_id == models.League.id)
        .filter(
            models.Match.status == "scheduled",
            models.Match.kickoff >= now,
            models.Match.kickoff <= end,
            models.League.enabled == True,  # noqa: E712
        )
        .order_by(models.League.priority, models.Match.kickoff)
        .limit(MAX_MATCHES)
        .all()
    )
    if not matches:
        return False
    lines = [
        f"{_tr_time(m.kickoff)} {m.home_team} - {m.away_team}"
        for m in matches
    ]
    header = templates.render("daily_fixture", {"detail": ""}).strip()
    return _queue_thread(db, "daily_fixture", header, lines)


# ------------------------------------------------------------------ akşam özeti
def evening_results(db: Session) -> bool:
    """Gün içinde biten maçların skor özeti."""
    if _already_today(db, "results_roundup"):
        return False
    start, _ = timeutil.tr_day_bounds_utc()
    matches = (
        db.query(models.Match)
        .join(models.League, models.Match.league_id == models.League.id)
        .filter(
            models.Match.status == "finished",
            models.Match.kickoff >= start,
            models.League.enabled == True,  # noqa: E712
        )
        .order_by(models.League.priority, models.Match.kickoff)
        .limit(MAX_MATCHES)
        .all()
    )
    if not matches:
        return False
    lines = [
        f"{m.home_team} {m.home_score}-{m.away_score} {m.away_team}"
        for m in matches
    ]
    header = templates.render("results_roundup", {"detail": ""}).strip()
    return _queue_thread(db, "results_roundup", header, lines)


# ------------------------------------------------------------------ puan durumu
def standings(db: Session) -> bool:
    """Haftada bir, en öncelikli açık ligin puan durumu (ilk 6)."""
    if _already_today(db, "standings"):
        return False
    league = (
        db.query(models.League)
        .filter(models.League.enabled == True)  # noqa: E712
        .order_by(models.League.priority)
        .first()
    )
    if not league or not league.provider_id or ":" not in league.provider_id:
        return False
    utid, season_id = league.provider_id.split(":", 1)
    rows = ss.get_standings(int(utid), int(season_id))
    if not rows:
        return False
    lines = []
    for i, r in enumerate(rows[:6], 1):
        lines.append(f"{i}. {r['team']} — {r['points']} puan")
    text = templates.render("standings", {
        "league": league.name, "detail": "\n".join(lines),
    })
    return _queue(db, "standings", text)
