from snek.system.model import BaseModel, ModelField


class UserModel(BaseModel):

    username = ModelField(
        name="username",
        required=True,
        min_length=2,
        max_length=20,
        regex=r"^[a-zA-Z0-9_-+/]+$",
    )
    nick = ModelField(
        name="nick",
        required=True,
        min_length=2,
        max_length=20,
        regex=r"^[a-zA-Z0-9_-+/]+$",
    )
    color = ModelField(
        name="color", required=True, regex=r"^#[0-9a-fA-F]{6}$", kind=str
    )
    email = ModelField(
        name="email",
        required=False,
        regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
    )
    password = ModelField(name="password", required=True, min_length=1)

    last_ping = ModelField(name="last_ping", required=False, kind=str)

    is_admin = ModelField(name="is_admin", required=False, kind=bool)

    country_short = ModelField(name="country_short", required=False, kind=str)
    country_long = ModelField(name="country_long", required=False, kind=str)
    city = ModelField(name="city", required=False, kind=str)
    latitude = ModelField(name="latitude", required=False, kind=float)
    longitude = ModelField(name="longitude", required=False, kind=float)
    region = ModelField(name="region", required=False, kind=str)
    ip = ModelField(name="ip", required=False, kind=str)

    async def get_property(self, name):
        prop = await self.app.services.user_property.find_one(
            user_uid=self["uid"], name=name
        )
        if prop:
            return prop["value"]

    async def has_property(self, name):
        return await self.app.services.user_property.exists(
            user_uid=self["uid"], name=name
        )

    async def set_property(self, name, value):
        if not await self.has_property(name):
            await self.app.services.user_property.insert(
                user_uid=self["uid"], name=name, value=value
            )
        else:
            await self.app.services.user_property.update(
                user_uid=self["uid"], name=name, value=value
            )

    async def get_channel_members(self):
        async for channel_member in self.app.services.channel_member.find(
            user_uid=self["uid"], is_banned=False, deleted_at=None
        ):
            yield channel_member
