from typing import Dict

from core.config import CoreConfig
from titles.mai2.buddies import Mai2Buddies
from titles.mai2.const import Mai2Constants
from titles.mai2.config import Mai2Config


class Mai2BuddiesPlus(Mai2Buddies):
    def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
        super().__init__(cfg, game_cfg)
        self.version = Mai2Constants.VER_MAIMAI_DX_BUDDIES_PLUS

    async def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
        user_data = await super().handle_cm_get_user_preview_api_request(data)

        # hardcode lastDataVersion for CardMaker
        user_data["lastDataVersion"] = "1.45.00"
        return user_data

    async def handle_get_game_weekly_data_api_request(self, data: Dict) -> Dict:
        return {
            "gameWeeklyData": {
                "missionCategory": 0,
                "updateDate": "2024-03-21 09:00:00",
                "beforeDate": "2099-12-31 00:00:00"
            }
        }

    async def handle_create_token_api_request(self, data: Dict) -> Dict:
        return {
            "Bearer": "ARTEMiSTOKEN" # duplicate of handle_user_login_api_request from Mai2Festival
        }

    async def handle_remove_token_api_request(self, data: Dict) -> Dict:
        return {}

    async def handle_get_user_friend_bonus_api_request(self, data: Dict) -> Dict:
        return {
            "userId": data["userId"],
            "returnCode": 1,
            "getMiles": 0
        }
    
    async def handle_get_user_shop_stock_api_request(self, data: Dict) -> Dict:
        return {
            "userId": data["userId"],
            "userShopStockList": []
        }

    async def handle_get_user_mission_data_api_request(self, data: Dict) -> Dict:
        return {
            "userId": data["userId"],
            "userMissionDataList": [],
            "userWeeklyData": {
                "lastLoginWeek": "2024-03-21 09:00:00",
                "beforeLoginWeek": "2099-12-31 00:00:00",
                "friendBonusFlag": False
            }
        }

    async def handle_get_user_friend_check_api_request(self, data: Dict) -> Dict:
        user1rivalList = await self.data.profile.get_rivals(data["userId1"])
        user2rivalList = await self.data.profile.get_rivals(data["userId2"])

        is_user2_in_user1_rivals = any(rival["rival"] == data["userId2"] for rival in user1rivalList)
        is_user1_in_user2_rivals = any(rival["rival"] == data["userId1"] for rival in user2rivalList)

        if is_user2_in_user1_rivals and is_user1_in_user2_rivals:
            return {"returnCode": 0}
        else:
            return {"returnCode": 1}

    async def handle_user_friend_regist_api_request(self, data: Dict) -> Dict:
        user1rivalList = await self.data.profile.get_rivals(data["userId1"]) or []
        user2rivalList = await self.data.profile.get_rivals(data["userId2"]) or []

        is_user2_in_user1_rivals = any(row.rival == data["userId2"] for row in user1rivalList)
        is_user1_in_user2_rivals = any(row.rival == data["userId1"] for row in user2rivalList)
        user1_show_count = sum(1 for row in user1rivalList if row.show is True)
        user2_show_count = sum(1 for row in user2rivalList if row.show is True)

        # initialize returnCode
        returnCode1 = 2
        returnCode2 = 2

        # Case1 no rival
        if not is_user2_in_user1_rivals and not is_user1_in_user2_rivals:
            if user1_show_count >= 3 and user2_show_count >= 3:
                returnCode1, returnCode2 = 1, 1
            elif user1_show_count >= 3:
                returnCode1, returnCode2 = 1, 2
            elif user2_show_count >= 3:
                returnCode1, returnCode2 = 2, 1

        # Case2 has single rival
        elif is_user2_in_user1_rivals != is_user1_in_user2_rivals:
            if user1_show_count >= 3 and user2_show_count >= 3:
                returnCode1, returnCode2 = 1, 1
            elif user1_show_count >= 3:
                returnCode1, returnCode2 = 1, 2
            elif user2_show_count >= 3:
                returnCode1, returnCode2 = 2, 1

        # execute add_rival and show_rival
        if not is_user2_in_user1_rivals:
            await self.data.profile.add_rival(data["userId1"], data["userId2"])
            if returnCode1 == 2 and user1_show_count < 3:
                await self.data.profile.set_rival_shown(data["userId1"], data["userId2"], True)

        if not is_user1_in_user2_rivals:
            await self.data.profile.add_rival(data["userId2"], data["userId1"])
            if returnCode2 == 2 and user2_show_count < 3:
                await self.data.profile.set_rival_shown(data["userId2"], data["userId1"], True)

        return {
            "returnCode1": returnCode1,
            "returnCode2": returnCode2
        }