import os
from uuid import UUID
from base64 import b64encode
from binascii import hexlify
from time import time as timestamp
from typing import BinaryIO, Union

from .sockets import Wss
from .lib.objects import *
from .lib.sessions import sessionClass

class Client(Wss, sessionClass):
    def __init__(self, deviceId: str = None, proxies: dict = None, trace: bool = False):
        self.trace = trace
        self.proxies = proxies
        self.deviceId = deviceId

        Wss.__init__(self, self, trace = self.trace)
        sessionClass.__init__(self, proxies = self.proxies, staticDevice = self.deviceId)

    def change_lang(self, lang: str = "ar-SY"):
        self.updateHeaders(lang = lang)

    def sid_login(self, sid: str):
        finalSessionId = sid if "sid=" in sid else f"sid={sid}"
        
        info = self.get_account_info()
        self.settings(settingsUser = info.userId, settingsSid = finalSessionId,)
        self.launch()

        return info

    def login(self, email: str = None, password: str = None, secret: str = None, socket: bool = False):
        data = {
            "clientType": 100,
            "action": "normal",
            "deviceID": self.deviceId,
            "v": 2,
            "timestamp": int(timestamp() * 1000)
        }

        if password and email and not secret:
            data["email"] = email
            data["secret"] = f"0 {password}"
        elif secret: data["secret"] = secret
        else: raise ValueError("Please provide VALID login info")

        req = self.postRequest("/g/s/auth/login", data)

        self.settings(
            settingsUser = req["auid"],
            settingsSid = f'sid={req["sid"]}',
            settingsSecret = req["secret"]
        )

        if socket: self.launch()
        return Login(req)

    def logout(self):
        data = {
            "deviceID": self.deviceId,
            "clientType": 100,
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest("/g/s/auth/logout", data)
        self.settings() # Resets the sid and uid and secret to None in sessions.py

        if self.isOpened: self.close()
        return Json(req)

    def check_device(self, deviceId: str) -> str:
        data = {
            "deviceID": deviceId,
            "timestamp": int(timestamp() * 1000),
            "clientType": 100
        }
        self.headers["NDCDEVICEID"] = deviceId
        req = self.postRequest("/g/s/device/", data)
        return req

    def upload_image(self, image: BinaryIO):
        data = image.read()
        newHeaders = {
            "content-type": "image/jpg",
            "content-length": str(len(data))
        }
        
        req = self.postRequest("/g/s/media/upload", data, newHeaders)
        return req["mediaValue"]

    def send_verify_code(self, email: str):
        data = {
            "identity": email,
            "type": 1,
            "deviceID": self.deviceId,
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest("/g/s/auth/request-security-validation", data)
        return Json(req)

    def accept_host(self, requestId: str, chatId: str):
        req = self.postRequest(f"/g/s/chat/thread/{chatId}/transfer-organizer/{requestId}/accept")
        return Json(req)

    def verify_account(self, email: str, code: str):
        data = {
            "type": 1,
            "identity": email,
            "data": {"code": code},
            "deviceID": self.deviceId
        }
        req = self.postRequest("/g/s/auth/activate-email", data)
        return Json(req)

    def restore(self, email: str, password: str):
        data = {
            "secret": f"0 {password}",
            "deviceID": self.deviceId,
            "email": email,
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest("/g/s/account/delete-request/cancel", data)
        return Json(req)

    def delete_account(self, password: str = None):
        data = {
            "deviceID": self.deviceId,
            "secret": f"0 {password}",
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest("/g/s/account/delete-request", data)
        return Json(req)

    def get_account_info(self):
        req = self.getRequest("/g/s/account")
        return Account(req["account"])

    def claim_coupon(self):
        req = self.postRequest("/g/s/coupon/new-user-coupon/claim")
        return Json(req)

    def change_amino_id(self, aminoId: str = None):
        data = {"aminoId": aminoId, "timestamp": int(timestamp() * 1000)}
        req = self.postRequest("/g/s/account/change-amino-id", data)
        return Json(req)

    def get_my_communities(self, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/community/joined?v=1&start={start}&size={size}")
        return CommunityList(req["communityList"]).CommunityList

    def get_chat_threads(self, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/chat/thread?type=joined-me&start={start}&size={size}")
        return ThreadList(req["threadList"]).ThreadList

    def get_chat_info(self, chatId: str):
        req = self.getRequest(f"/g/s/chat/thread/{chatId}")
        return Thread(req["thread"]).Thread

    def leave_chat(self, chatId: str):
        req = self.deleteRequest(f"/g/s/chat/thread/{chatId}/member/{self.uid}")
        return Json(req)

    def join_chat(self, chatId: str):
        req = self.postRequest(f"/g/s/chat/thread/{chatId}/member/{self.uid}")
        return Json(req)

    def start_chat(self, userId: Union[str, list], title: str = None, message: str = None, content: str = None,
                   chatType: int = 0):

        if type(userId) is list: userIds = userId
        elif type(userId) is str: userIds = [userId]
        else: raise TypeError("Please put a str or list of userId")

        data = {
            "title": title,
            "inviteeUids": userIds,
            "initialMessageContent": message,
            "content": content,
            "type": chatType,
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest(f"/g/s/chat/thread", data)
        return Json(req)

    def get_from_link(self, link: str):
        req = self.getRequest(f"/g/s/link-resolution?q={link}")
        return FromCode(req["linkInfoV2"]["extensions"]).FromCode

    def edit_profile(self, nickname: str = None, content: str = None, icon: BinaryIO = None,
                     backgroundColor: str = None, backgroundImage: str = None, defaultBubbleId: str = None):
        data = {
            "address": None,
            "latitude": 0,
            "longitude": 0,
            "mediaList": None,
            "eventSource": "UserProfileView",
            "timestamp": int(timestamp() * 1000)
        }

        if content: data["content"] = content
        if nickname: data["nickname"] = nickname
        if icon: data["icon"] = self.upload_image(icon)
        if backgroundColor: data["extensions"]["style"] = {"backgroundColor": backgroundColor}
        if defaultBubbleId: data["extensions"] = {"defaultBubbleId": defaultBubbleId}
        if backgroundImage: 
            data["extensions"]["style"] = {
                "backgroundMediaList": [
                    [100, backgroundImage, None, None, None]
                ]}
        
        req = self.postRequest(f"/g/s/user-profile/{self.uid}", data)
        return Json(req)

    def flag_community(self, comId: str, reason: str, flagType: int):
        data = {
            "objectId": comId,
            "objectType": 16,
            "flagType": flagType,
            "message": reason,
            "timestamp": int(timestamp() * 1000)
        }
        req = self.postRequest(f"/x{comId}/s/g-flag", data)
        return Json(req)

    def leave_community(self, comId: str):
        req = self.postRequest(f"x/{comId}/s/community/leave")
        return Json(req)

    def join_community(self, comId: str, InviteId: str = None):
        data = {"timestamp": int(timestamp() * 1000)}
        if InviteId: data["invitationId"] = InviteId
        
        req = self.postRequest(f"/x{comId}/s/community/join", data)
        return Json(req)

    def flag(self, reason: str, type: str = "spam", userId: str = None, wikiId: str = None, blogId: str = None):
        types = {
            "violence": 106,
            "hate": 107,
            "suicide": 108,
            "troll": 109,
            "nudity": 110,
            "bully": 0,
            "off-topic": 4,
            "spam": 2
        }

        data = {
            "message": reason,
            "timestamp": int(timestamp() * 1000)
        }

        if type in types: data["flagType"] = types.get(type)
        else: raise TypeError("choose a certain type to report")

        if userId:
            data["objectId"] = userId
            data['objectType'] = 0
        elif blogId:
            data["objectId"] = blogId
            data['objectType'] = 1
        elif wikiId:
            data["objectId"] = wikiId
            data["objectType"] = 2
        else: raise TypeError("Please put blog or user or wiki Id")

        req = self.postRequest("/g/s/flag", data)
        return Json(req)

    def unfollow(self, userId: str):
        req = self.postRequest(f"/g/s/user-profile/{userId}/member/{self.uid}")
        return Json(req)

    def follow(self, userId: Union[str, list]):
        data = {
            "timestamp": int(timestamp() * 1000)
        }

        if type(userId) is str: link = f"/g/s/user-profile/{userId}/member"
        elif type(userId) is list:
            data["targetUidList"] = userId
            link = f"/g/s/user-profile/{self.uid}/joined"
        else: raise TypeError("Please put a str or list of userId")

        req = self.postRequest(link, data)
        return Json(req)

    def get_member_following(self, userId: str, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/user-profile/{userId}/joined?start={start}&size={size}")
        return UserProfileList(req["userProfileList"]).UserProfileList

    def get_member_followers(self, userId: str, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/user-profile/{userId}/member?start={start}&size={size}")
        return UserProfileList(req["userProfileList"]).UserProfileList

    def get_member_visitors(self, userId: str, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/user-profile/{userId}/visitors?start={start}&size={size}")
        return VisitorsList(req["visitors"]).VisitorsList

    def get_blocker_users(self, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/block/full-list?start={start}&size={size}")
        return req["blockerUidList"]

    def get_blocked_users(self, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/block/full-list?start={start}&size={size}")
        return req["blockedUidList"]

    def get_wall_comments(self, userId: str, sorting: str = 'newest', start: int = 0, size: int = 25):
        sorting = sorting.lower().replace("top", "vote")
        if sorting not in ["newest", "oldest", "vote"]: raise TypeError("حط تايب يا حمار")

        req = self.getRequest(f"/g/s/user-profile/{userId}/g-comment?sort={sorting}&start={start}&size={size}")
        return CommentList(req["commentList"]).CommentList

    def get_blog_comments(self, wikiId: str = None, blogId: str = None, sorting: str = "newest", size: int = 25, start: int = 0):
        sorting = sorting.lower().replace("top", "vote")

        if sorting not in ["newest", "oldest", "vote"]: raise TypeError("Please insert a valid sorting")
        if blogId: link = f"/g/s/blog/{blogId}/comment?sort={sorting}&start={start}&size={size}"
        elif wikiId: link = f"/g/s/item/{wikiId}/comment?sort={sorting}&start={start}&size={size}"

        req = self.getRequest(link)
        return CommentList(req["commentList"]).CommentList

    def send_message(self, chatId: str, message: str = None, messageType: int = 0, file: BinaryIO = None,
                     fileType: str = None, replyTo: str = None, mentionUserIds: Union[list, str] = None, stickerId: str = None,
                     snippetLink: str = None, ytVideo: str = None, snippetImage: BinaryIO = None, embedId: str = None,
                     embedType: int = None, embedLink: str = None, embedTitle: str = None, embedContent: str = None,
                     embedImage: BinaryIO = None):
                     
        if message is not None and file is None: message = message.replace("[@", "‎‏").replace("@]", "‬‭")

        mentions = []
        if mentionUserIds:
            if type(mentionUserIds) is list:
                for mention_uid in mentionUserIds: mentions.append({"uid": mention_uid})
            mentions.append({"uid": mentionUserIds})

        if embedImage:
            if type(embedImage) is not str: embedImage = [[100, self.upload_image(embedImage), None]]
            embedImage = [[100, embedImage, None]]

        data = {
            "type": messageType,
            "content": message,
            "attachedObject": {
                "objectId": embedId,
                "objectType": embedType,
                "link": embedLink,
                "title": embedTitle,
                "content": embedContent,
                "mediaList": embedImage
            },
            "extensions": {"mentionedArray": mentions},
            "clientRefId": int(timestamp() / 10 % 100000000),
            "timestamp": int(timestamp() * 1000)
        }

        if replyTo: data["replyMessageId"] = replyTo

        if stickerId:
            data["content"] = None
            data["stickerId"] = stickerId
            data["type"] = 3

        if snippetLink and snippetImage:
            data["attachedObject"] = None
            data["extensions"]["linkSnippetList"] = [{
                "link": snippetLink,
                "mediaType": 100,
                "mediaUploadValue": b64encode(snippetImage.read()).decode(),
                "mediaUploadValueContentType": "image/png"
            }]

        if ytVideo:
            data["content"] = None
            data["mediaType"] = 103
            data["mediaValue"] = ytVideo

        if file:
            data["content"] = None
            if fileType == "audio":
                data["type"] = 2
                data["mediaType"] = 110

            elif fileType == "image":
                data["mediaType"] = 100
                data["mediaUploadValueContentType"] = "image/jpg"
                data["mediaUhqEnabled"] = False

            elif fileType == "gif":
                data["mediaType"] = 100
                data["mediaUploadValueContentType"] = "image/gif"
                data["mediaUhqEnabled"] = False

            else:
                raise TypeError(fileType)

            data["mediaUploadValue"] = b64encode(file.read()).decode()
            data["attachedObject"] = None
            data["extensions"] = None

        req = self.postRequest(f"/g/s/chat/thread/{chatId}/message", data)
        return Json(req)

    def get_community_info(self, comId: str):
        link = f"""
        /g/s-x{comId}/community/
        info?withInfluencerList=1
        &withTopicList=true
        &influencerListOrderStrategy=fansCount
        """.replace("\n", "")
        req = self.getRequest(link)
        return Community(req["community"]).Community

    def mark_as_read(self, chatId: str):
        req = self.postRequest(f"/g/s/chat/thread/{chatId}/mark-as-read")
        return Json(req)

    def delete_message(self, messageId: str, chatId: str):
        req = self.deleteRequest(f"/g/s/chat/thread/{chatId}/message/{messageId}")
        return Json(req)

    def get_chat_messages(self, chatId: str, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/chat/thread/{chatId}/message?v=2&pagingType=t&size={size}")
        return GetMessages(req["messageList"]).GetMessages

    def get_message_info(self, messageId: str, chatId: str):
        req = self.getRequest(f"/g/s/chat/thread/{chatId}/message/{messageId}")
        return Message(req["message"]).Message

    def tip_coins(self, chatId: str = None, blogId: str = None, coins: int = 0, transactionId: str = None):
        if transactionId is None: transactionId = str(UUID(hexlify(os.urandom(16)).decode("ascii")))
        data = {
            "coins": coins,
            "tippingContext": {
                "transactionId": transactionId
            },
            "timestamp": int(timestamp() * 1000)
        }

        if chatId: link = f"/g/s/blog/{chatId}/tipping"
        elif blogId: link = f"/g/s/blog/{blogId}/tipping"
        else: raise TypeError("please put chat or blog Id")

        req = self.postRequest(link, data)
        return Json(req)

    def reset_password(self, email: str, password: str, code: str, deviceId: str = None):
        if deviceId is None: deviceId = self.deviceId

        data = {
            "updateSecret": f"0 {password}",
            "emailValidationContext": {
                "data": {
                    "code": code
                },
                "type": 1,
                "identity": email,
                "level": 2,
                "deviceID": deviceId
            },
            "phoneNumberValidationContext": None,
            "deviceID": deviceId,
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest("/g/s/auth/reset-password", data)
        return Json(req)

    def change_password(self, password: str, newPassword: str):
        data = {
            "secret": f"0 {password}",
            "updateSecret": f"0 {newPassword}",
            "validationContext": None,
            "deviceID": self.deviceId
        }

        req = self.postRequest("/g/s/auth/change-password", data)
        return Json(req)

    def get_user_info(self, userId: str):
        req = self.getRequest(f"/g/s/user-profile/{userId}")
        return UserProfile(req["userProfile"]).UserProfile

    def comment(self, comment: str, userId: str = None, replyTo: str = None):
        data = {
            "content": comment,
            "stickerId": None,
            "type": 0,
            "eventSource": "UserProfileView",
            "timestamp": int(timestamp() * 1000)
        }

        if replyTo: data["respondTo"] = replyTo
        req = self.postRequest(f"/g/s/user-profile/{userId}/g-comment", data)
        return Json(req)

    def delete_comment(self, userId: str = None, commentId: str = None):
        req = self.deleteRequest(f"/g/s/user-profile/{userId}/g-comment/{commentId}")
        return Json(req)

    def invite_by_host(self, chatId: str, userId: Union[str, list]):
        data = {"uidList": userId, "timestamp": int(timestamp() * 1000)}
        req = self.postRequest(f"/g/s/chat/thread/{chatId}/avchat-members", data)
        return Json(req)

    def kick(self, chatId: str, userId: str, rejoin: bool = True):
        rejoin = 1 if rejoin else 0
        req = self.deleteRequest(f"/g/s/chat/thread/{chatId}/member/{userId}?allowRejoin={rejoin}")
        return Json(req)

    def block(self, userId: str):
        req = self.postRequest(f"/g/s/block/{userId}")
        return Json(req)

    def unblock(self, userId: str):
        req = self.deleteRequest(f"/g/s/block/{userId}")
        return Json(req)

    def get_public_chats(self, type: str = "recommended", start: int = 0, size: int = 50):
        req = self.getRequest(f"/g/s/chat/thread?type=public-all&filterType={type}&start={start}&size={size}")
        return ThreadList(req["threadList"]).ThreadList

    def get_content_modules(self, version: int = 2):
        req = self.getRequest(f"/g/s/home/discover/content-modules?v={version}")
        return Json(req)

    def get_banner_ads(self, size: int = 25, pagingType: str = "t"):
        link = f"""
        /g/s/topic/0/feed/
        banner-ads?moduleId=711f818f-da0c-4aa7-bfa6-d5b58c1464d0&adUnitId=703798&size={size}
        &pagingType={pagingType}""".replace("\n", "")

        req = self.getRequest(link)
        return ItemList(req["itemList"]).ItemList

    def get_announcements(self, lang: str = "ar", start: int = 0, size: int = 20):
        req = self.getRequest(f"/g/s/announcement?language={lang}&start={start}&size={size}")
        return BlogList(req["blogList"]).BlogList

    def get_discover(self, type: str = "discover", category: str = "customized", size: int = 25, pagingType: str = "t"):
        link = f"""
        /g/s/topic/0/feed/
        community?type={type}
        &categoryKey={category}
        &moduleId=64da14e8-0845-47bf-946a-17403bd6aa17&size={size}
        &pagingType={pagingType}""".replace("\n", "")

        req = self.getRequest(link)
        return CommunityList(req["communityList"]).CommunityList

    def search_community(self, word: str, lang: str = "ar", start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/community/search?q={word}&language={lang}&completeKeyword=1&start={start}&size={size}")
        return CommunityList(req["communityList"]).CommunityList

    def invite_to_voice_chat(self, userId: str = None, chatId: str = None):
        data = {"uid": userId, "timestamp": int(timestamp() * 1000)}
        req = self.postRequest(f"/g/s/chat/thread/{chatId}/vvchat-presenter/invite", data)
        return Json(req)

    def get_wallet_history(self, start: int = 0, size: int = 25):
        req = self.getRequest(f"/g/s/wallet/coin/history?start={start}&size={size}")
        return WalletHistory(req).WalletHistory

    def get_wallet_info(self):
        req = self.getRequest("/g/s/wallet")
        return WalletInfo(req["wallet"]).WalletInfo

    def get_all_users(self, type: str = "recent", start: int = 0, size: int = 25):
        """
        Types:
            - recent
            - banned
            - featured
            - leaders
            - curators
        """
        req = self.getRequest(f"/g/s/user-profile?type={type}&start={start}&size={size}")
        return UserProfileList(req["userProfileList"]).UserProfileList

    def get_chat_members(self, start: int = 0, size: int = 25, chatId: str = None):
        req = self.getRequest(f"/g/s/chat/thread/{chatId}/member?start={start}&size={size}&type=default&cv=1.2")
        return UserProfileList(req["memberList"]).UserProfileList

    def get_from_id(self, id: str, comId: str = None, objectType: int = 2):  # never tried
        data = {
            "objectId": id,
            "targetCode": 1,
            "objectType": objectType,
            "timestamp": int(timestamp() * 1000)
        }
        
        link = f"/g/s/link-resolution"
        if comId: link = f"/g/s-x{comId}/link-resolution"

        req = self.postRequest(link, data)
        return FromCode(req["linkInfoV2"]["extensions"]["linkInfo"]).FromCode

    def chat_settings(self, chatId: str, viewOnly: bool = None, doNotDisturb: bool = None, canInvite: bool = False,
                      canTip: bool = None, pin: bool = None):
        res = []

        if doNotDisturb:
            if doNotDisturb: opt = 2
            else: opt = 1
            data = {"alertOption": opt, "timestamp": int(timestamp() * 1000)}
            req = self.postRequest(f"/g/s/chat/thread/{chatId}/member/{self.uid}/alert", data)
            res.append(Json(req))

        if viewOnly is not None:
            if viewOnly: viewOnly = "enable"
            else: viewOnly = "disable"
            req = self.postRequest(f"/g/s/chat/thread/{chatId}/view-only/{viewOnly}")
            res.append(Json(req))

        if canInvite:
            if canInvite: canInvite = "enable"
            else: canInvite = "disable"
            req = self.postRequest(f"/g/s/chat/thread/{chatId}/members-can-invite/{canInvite}")
            res.append(Json(req))

        if canTip:
            if canTip: canTip = "enable"
            else: canTip = "disable"
            req = self.postRequest(f"/g/s/chat/thread/{chatId}/tipping-perm-status/{canTip}")
            res.append(Json(req))

        if pin:
            if pin: pin = "pin"
            else: pin = "unpin"
            req = self.postRequest(f"/g/s/chat/thread/{chatId}/{pin}")
            res.append(Json(req))

        return res

    def like_comment(self, commentId: str, userId: str = None, blogId: str = None):
        data = {"value": 4, "timestamp": int(timestamp() * 1000)}

        if userId: link = f"/g/s/user-profile/{userId}/comment/{commentId}/g-vote?cv=1.2&value=1"
        elif blogId: link = f"/g/s/blog/{blogId}/comment/{commentId}/g-vote?cv=1.2&value=1"
        else: raise TypeError("Please put blog or user Id")

        req = self.postRequest(link, data)
        return Json(req)

    def unlike_comment(self, commentId: str, blogId: str = None, userId: str = None):
        if userId: link = f"/g/s/user-profile/{userId}/comment/{commentId}/g-vote?eventSource=UserProfileView"
        elif blogId: link = f"/g/s/blog/{blogId}/comment/{commentId}/g-vote?eventSource=PostDetailView"
        else: raise TypeError("Please put blog or user Id")

        req = self.deleteRequest(link)
        return Json(req)

    def register(self, nickname: str, email: str, password: str, code: str, deviceId: str = None):
        if deviceId is None: deviceId = self.deviceId

        data = {
            "secret": f"0 {password}",
            "deviceID": deviceId,
            "email": email,
            "clientType": 100,
            "nickname": nickname,
            "latitude": 0,
            "longitude": 0,
            "address": None,
            "clientCallbackURL": "narviiapp://relogin",
            "validationContext": {
                "data": {
                    "code": code
                },"type": 1, "identity": email},
            "type": 1,
            "identity": email,
            "timestamp": int(timestamp() * 1000)
        }

        req = self.postRequest("/g/s/auth/register", data)
        return Json(req)

    def remove_host(self, chatId: str, userId: str):
        req = self.deleteRequest(f"/g/s/chat/thread/{chatId}/co-host/{userId}")
        return Json(req)

    def edit_comment(self, commentId: str, comment: str, userId: str):
        data = {"content": comment, "timestamp": int(timestamp() * 1000)}
        req = self.postRequest(f"/g/s/user-profile/{userId}/comment/{commentId}", data)
        return Comment(req).Comments

    def get_comment_info(self, commentId: str, userId: str):
        req = self.getRequest(f"/g/s/user-profile/{userId}/comment/{commentId}")
        return Comment(req).Comments

    def get_notifications(self, size: int = 25, pagingType: str = "t"):
        req = self.getRequest(f"/g/s/notification?pagingType={pagingType}&size={size}")
        return NotificationList(req).NotificationList
    
    def get_notices(self, start: int = 0, size: int = 25, type: str = "usersV2", status: int = 1):
        req = self.getRequest(f"/g/s/notice?type={type}&status={status}&start={start}&size={size}")
        return NoticeList(req).NoticeList

    def accept_promotion(self, requestId: str):
        req = self.postRequest(f"/g/s/notice/{requestId}/accept")
        return Json(req)
    
    def decline_promotion(self, requestId: str):
        req = self.postRequest(f"/g/s/notice/{requestId}/decline")
        return Json(req)
