# models/forum.py
from snek.system.model import BaseModel, ModelField


class ForumModel(BaseModel):
    """Forum categories"""
    name = ModelField(name="name", required=True, kind=str, min_length=3, max_length=100)
    description = ModelField(name="description", required=False, kind=str, max_length=500)
    slug = ModelField(name="slug", required=True, kind=str, regex=r"^[a-z0-9-]+$", unique=True)
    icon = ModelField(name="icon", required=False, kind=str)
    position = ModelField(name="position", required=True, kind=int, value=0)
    is_active = ModelField(name="is_active", required=True, kind=bool, value=True)
    created_by_uid = ModelField(name="created_by_uid", required=True, kind=str)
    thread_count = ModelField(name="thread_count", required=True, kind=int, value=0)
    post_count = ModelField(name="post_count", required=True, kind=int, value=0)
    last_post_at = ModelField(name="last_post_at", required=False, kind=str)
    last_thread_uid = ModelField(name="last_thread_uid", required=False, kind=str)

    async def get_threads(self, limit=50, offset=0):
        async for thread in self.app.services.thread.find(
            forum_uid=self["uid"], 
            deleted_at=None,
            _limit=limit,
            _offset=offset,
            order_by="-last_post_at"
            #order_by="is_pinned DESC, last_post_at DESC"
        ):
            yield thread

    async def increment_thread_count(self):
        self["thread_count"] += 1
        await self.save()

    async def increment_post_count(self):
        self["post_count"] += 1
        await self.save()


# models/thread.py
class ThreadModel(BaseModel):
    """Forum threads"""
    forum_uid = ModelField(name="forum_uid", required=True, kind=str)
    title = ModelField(name="title", required=True, kind=str, min_length=5, max_length=200)
    slug = ModelField(name="slug", required=True, kind=str, regex=r"^[a-z0-9-]+$")
    created_by_uid = ModelField(name="created_by_uid", required=True, kind=str)
    is_pinned = ModelField(name="is_pinned", required=True, kind=bool, value=False)
    is_locked = ModelField(name="is_locked", required=True, kind=bool, value=False)
    view_count = ModelField(name="view_count", required=True, kind=int, value=0)
    post_count = ModelField(name="post_count", required=True, kind=int, value=0)
    last_post_at = ModelField(name="last_post_at", required=False, kind=str)
    last_post_by_uid = ModelField(name="last_post_by_uid", required=False, kind=str)

    async def get_posts(self, limit=50, offset=0):
        async for post in self.app.services.post.find(
            thread_uid=self["uid"],
            deleted_at=None,
            _limit=limit,
            _offset=offset,
            order_by="created_at"
        ):
            yield post

    async def increment_view_count(self):
        self["view_count"] += 1
        await self.save()

    async def increment_post_count(self):
        self["post_count"] += 1
        self["last_post_at"] = self.app.services.get_timestamp()
        await self.save()


# models/post.py  
class PostModel(BaseModel):
    """Forum posts"""
    thread_uid = ModelField(name="thread_uid", required=True, kind=str)
    forum_uid = ModelField(name="forum_uid", required=True, kind=str)
    content = ModelField(name="content", required=True, kind=str, min_length=1, max_length=10000)
    created_by_uid = ModelField(name="created_by_uid", required=True, kind=str)
    edited_at = ModelField(name="edited_at", required=False, kind=str)
    edited_by_uid = ModelField(name="edited_by_uid", required=False, kind=str)
    is_first_post = ModelField(name="is_first_post", required=True, kind=bool, value=False)
    like_count = ModelField(name="like_count", required=True, kind=int, value=0)
    
    async def get_author(self):
        return await self.app.services.user.get(uid=self["created_by_uid"])

    async def is_liked_by(self, user_uid):
        return await self.app.services.post_like.exists(
            post_uid=self["uid"],
            user_uid=user_uid
        )


# models/post_like.py
class PostLikeModel(BaseModel):
    """Post likes"""
    post_uid = ModelField(name="post_uid", required=True, kind=str)
    user_uid = ModelField(name="user_uid", required=True, kind=str)
