"""
Handling groups
"""

import uuid
from collections.abc import AsyncIterator
from datetime import datetime, timedelta
from typing import TYPE_CHECKING

from slixmpp.exceptions import XMPPError

from slidge.group.bookmarks import LegacyBookmarks
from slidge.group.participant import LegacyParticipant
from slidge.group.room import LegacyMUC
from slidge.util.types import (
    Avatar,
    Hat,
    HoleBound,
    MucType,
    SpaceMetadata,
    XMPPMessage,
)

if TYPE_CHECKING:
    from .session import Session


from .contact import Contact


class Participant(LegacyParticipant[Contact]):
    pass


class Bookmarks(LegacyBookmarks["MUC"]):
    async def fill(self) -> None:
        for i in "aaa", "bbb":
            muc = await self.by_legacy_id(i)
            await muc.add_to_bookmarks()

    async def fetch_space_metadata(self, legacy_id: str) -> SpaceMetadata:
        if legacy_id == "555":
            return SpaceMetadata(
                name="The cool super space",
                creator_legacy_id="111",
                owner_legacy_ids=["111", "666"],
            )
        raise XMPPError("item-not-found", f"This space is not a space: {legacy_id}")


class MUC(LegacyMUC[Participant]):
    session: "Session"
    type = MucType.GROUP

    async def update_info(self) -> None:
        info = await self.session.legacy_client.get_group_info(self.legacy_id)
        self.space_legacy_id = "555"
        self.name = info.name
        await self.set_avatar(Avatar(path=info.avatar, unique_id=info.avatar_unique_id))

    async def fill_participants(self) -> AsyncIterator["Participant"]:
        # in a real case, this would probably call something like
        # self.session.legacy_client.fetch_group_members(self.legacy_id)
        for i in "0", "111", "222":
            part = await self.get_participant_by_legacy_id(i)
            if i == "111":
                part.role = "moderator"
                part.affiliation = "owner"
                part.set_hats([Hat("test", "test"), Hat("prout", "prout")])
            yield part
        me = await self.get_user_participant()
        me.role = "moderator"
        me.affiliation = "owner"
        yield me

    async def backfill(
        self,
        after: HoleBound | None = None,
        before: HoleBound | None = None,
    ) -> None:
        # in a real case, this would probably call something like
        # self.session.legacy_client.fetch_group_history(self.legacy_id)
        for i in range(10):
            part = await self.get_participant_by_legacy_id("0")
            part.send_text(
                f"History message #{i}",
                when=datetime.now() - timedelta(hours=i),
                legacy_msg_id=f"{i}--{uuid.uuid4().hex}",
                archive_only=True,
            )

    async def on_message(self, message: XMPPMessage) -> str | None:
        if message.body:
            return (
                await self.session.legacy_client.send_group_msg(
                    message.body, self.legacy_id
                )
            ).id
        return None
