import json
import random
import pytz
import string

from pyrogram.enums import ChatMemberStatus
from persiantools.jdatetime import JalaliDateTime, timedelta

import app
from app.config import ADMINS

letters = string.ascii_lowercase + string.ascii_uppercase + string.digits
timezone = pytz.timezone("Asia/Tehran")

class Utils:
    @property
    def timestamp(self: "app.App") -> int:
        timestamp = JalaliDateTime.now(tz=timezone).timestamp()
        return round(timestamp)
    
    @property
    def start_of_day(self: "app.App"):
        now = JalaliDateTime.now()
        start_day = JalaliDateTime(now.year, now.month, now.day)
        return start_day.timestamp()

    @property
    def start_of_week(self: "app.App"):
        now = JalaliDateTime.now()
        start_week = now - timedelta(days=now.weekday())
        start_week = JalaliDateTime(start_week.year, start_week.month, start_week.day)
        return start_week.timestamp()

    @property
    def start_of_month(self: "app.App"):
        now = JalaliDateTime.now()
        start_month = JalaliDateTime(now.year, now.month, 1)
        return start_month.timestamp()

    @property
    def start_of_year(self: "app.App"):
        now = JalaliDateTime.now()
        start_year = JalaliDateTime(now.year, 1, 1)
        return start_year.timestamp()
    
    def string_generator(self: "app.App") -> str:
        letters = string.ascii_uppercase + string.ascii_lowercase + string.digits
        generate = ''.join(random.choices(letters, k=10))
        return generate
    
    async def is_join(self: "app.App", channel, user) -> bool:
        try:
            get_member = await self.client.get_chat_member(channel, user)
            return get_member.status != ChatMemberStatus.LEFT
        except:
            pass
    
    async def bot_admin(self: "app.App", channel) -> bool:
        try:
            get_member = await self.client.get_chat_member(channel, self.client.me.id)
            return get_member.status == ChatMemberStatus.ADMINISTRATOR
        except:
            pass
        
    def jalali_date(self: "app.App", timestamp: int, reverse: bool = False) -> str:
        dt = JalaliDateTime.fromtimestamp(timestamp, timezone)
        
        if reverse:
            format = '%Y/%m/%d %H:%M'
        else:
            format = '%H:%M %Y/%m/%d'
        
        return dt.strftime(format)
    
    def channel_id_format(self: "app.App", id):
        try:
            return int(id)
        except:
            return id

    def convert_if_round(self: "app.App", value):
        if value == int(value):
            return int(value)
        else:
            return value

    def encode(self, d: dict) -> str:
        return json.dumps(d)
    
    def decode(self, string: str, int_c = True) -> dict:
        if int_c:
            decode = json.loads(string, object_hook=lambda d: {int(k) if k.isnumeric() else k: v for k, v in d.items()})
    
        else:
            decode = json.loads(string)
        
        return decode
    
    async def is_admin(self: "app.App", user_id: int, right: str = None) -> bool:
        if right:
            if user_id in ADMINS:
                return True
            else:
                get_admin = await self.database.get_admin(user_id=user_id)
                rights = self.decode(get_admin.rights)
                return right in rights
        else:
            return user_id in ADMINS or await self.database.get_admin(user_id=user_id)
        
    async def admin_rights(self: "app.App", user_id: int):
        admin = await self.database.get_admin(user_id=user_id)
        
        if admin:
            return self.decode(admin.rights)

        return None
    
    def channel_type(self, ct):
        if int(ct) == 1:
            return "چنل وطنی"
        elif int(ct) == 2:
            return "چنل اونلی فنز"
        elif int(ct) == 3:
            return "چنل اخلاقی"
        elif int(ct) == 4:
            return "چنل زیرنویس"
        
    def schedule_text(self, date: str, stype: int, reverse: bool = False):
        if stype == 1:
            return self.jalali_date(int(date), reverse)
        elif stype == 2:
            return f"{date} دقیقه"
        elif stype == 3:
            return date
        else:
            return f"♻️ {date}"