# retoor <retoor@molodetz.nl>

from devplacepy.database import (
    db,
    get_table,
    get_setting,
    get_site_stats,
    get_top_authors,
    get_featured_news,
    get_gist_languages,
    get_daily_topic,
    get_streaks,
    get_user_stars,
    get_user_rank,
)
from devplacepy.utils import format_date


def _count(table: str, **criteria) -> int:
    if table not in db.tables:
        return 0
    return get_table(table).count(**criteria)


def _recent(table: str, user_uid: str, limit: int = 5) -> list:
    if table not in db.tables:
        return []
    return list(
        get_table(table).find(user_uid=user_uid, order_by=["-created_at"], _limit=limit)
    )


def _user_facts(user: dict) -> dict:
    uid = user["uid"]

    posts = _recent("posts", uid)
    gists = _recent("gists", uid)
    projects = _recent("projects", uid)
    badges = (
        [b.get("badge_name", "") for b in get_table("badges").find(user_uid=uid)]
        if "badges" in db.tables
        else []
    )
    languages = sorted(
        {
            g.get("language")
            for g in (
                get_table("gists").find(user_uid=uid) if "gists" in db.tables else []
            )
            if g.get("language")
        }
    )

    return {
        "username": user.get("username", ""),
        "member_since": format_date(user.get("created_at", ""))
        if user.get("created_at")
        else "",
        "level": user.get("level", 1),
        "xp": user.get("xp", 0),
        "stars": get_user_stars(uid),
        "rank": get_user_rank(uid),
        "streak": get_streaks(uid),
        "badges": badges,
        "languages": languages,
        "counts": {
            "posts": _count("posts", user_uid=uid),
            "gists": _count("gists", user_uid=uid),
            "projects": _count("projects", user_uid=uid),
            "comments": _count("comments", user_uid=uid),
            "followers": _count("follows", following_uid=uid),
            "following": _count("follows", follower_uid=uid),
            "bookmarks": _count("bookmarks", user_uid=uid),
            "unread_notifications": _count("notifications", user_uid=uid, read=False),
            "unread_messages": _count("messages", receiver_uid=uid, read=False),
        },
        "recent_posts": [
            {
                "title": (
                    p.get("title") or (p.get("content") or "")[:60] or "Untitled"
                ),
                "url": f"/posts/{p.get('slug') or p['uid']}",
            }
            for p in posts
        ],
        "recent_gists": [
            {
                "title": g.get("title", "Untitled"),
                "language": g.get("language", ""),
                "url": f"/gists/{g.get('slug') or g['uid']}",
            }
            for g in gists
        ],
        "recent_projects": [
            {
                "title": p.get("title", "Untitled"),
                "status": p.get("status", ""),
                "url": f"/projects/{p.get('slug') or p['uid']}",
            }
            for p in projects
        ],
    }


def build_live_facts(user: dict | None) -> dict:
    stats = get_site_stats()
    facts = {
        "site": {
            "name": get_setting("site_name", "DevPlace"),
            "tagline": get_setting("site_tagline", ""),
            "total_members": stats.get("total_members", 0),
            "posts_today": stats.get("posts_today", 0),
            "total_projects": stats.get("total_projects", 0),
            "total_gists": stats.get("total_gists", 0),
        },
        "top_authors": [
            {"username": a.get("username", ""), "stars": a.get("stars", 0)}
            for a in get_top_authors(10)
        ],
        "languages": sorted(get_gist_languages()),
        "news": get_featured_news(5),
        "topic": get_daily_topic(),
        "user": _user_facts(user) if user else None,
    }
    return facts


def live_text(facts: dict) -> str:
    parts: list[str] = []
    site = facts["site"]
    parts += [
        site["name"],
        site["tagline"],
        "members",
        str(site["total_members"]),
        "posts today",
        str(site["posts_today"]),
        "projects",
        str(site["total_projects"]),
        "gists",
        str(site["total_gists"]),
        "top authors leaderboard",
    ]
    parts += [f"{a['username']} {a['stars']} stars" for a in facts["top_authors"]]
    parts += ["trending languages"] + facts["languages"]
    parts += ["developer news"] + [n.get("title", "") for n in facts["news"]]
    parts += [facts["topic"].get("title", "")]

    user = facts.get("user")
    if user:
        counts = user["counts"]
        parts += [
            "your dashboard account stats",
            user["username"],
            "member since",
            user["member_since"],
            "level",
            str(user["level"]),
            "xp",
            str(user["xp"]),
            "stars",
            str(user["stars"]),
            "rank",
            str(user["rank"]),
            "current streak",
            str(user["streak"].get("current", 0)),
            "longest streak",
            str(user["streak"].get("longest", 0)),
            "posts",
            str(counts["posts"]),
            "gists",
            str(counts["gists"]),
            "projects",
            str(counts["projects"]),
            "comments",
            str(counts["comments"]),
            "followers",
            str(counts["followers"]),
            "following",
            str(counts["following"]),
            "bookmarks saved",
            str(counts["bookmarks"]),
            "unread notifications",
            str(counts["unread_notifications"]),
            "unread messages",
            str(counts["unread_messages"]),
            "badges",
        ]
        parts += user["badges"]
        parts += ["languages you use"] + user["languages"]
        parts += ["your recent posts"] + [p["title"] for p in user["recent_posts"]]
        parts += ["your gists"] + [g["title"] for g in user["recent_gists"]]
        parts += ["your projects"] + [p["title"] for p in user["recent_projects"]]

    return " ".join(str(part) for part in parts if part)
