from api.route import Route
from api_graphql.abc.mutation_abc import MutationABC
from api_graphql.field.mutation_field_builder import MutationFieldBuilder
from api_graphql.input.user_setting_input import UserSettingInput
from core.logger import APILogger
from core.string import first_to_lower
from data.schemas.public.user_setting import UserSetting
from data.schemas.public.user_setting_dao import userSettingDao
from data.schemas.system.setting_dao import settingDao
from service.permission.permissions_enum import Permissions

logger = APILogger(__name__)


class UserSettingMutation(MutationABC):
    def __init__(self):
        MutationABC.__init__(self, "UserSetting")
        self.field(
            MutationFieldBuilder("change")
            .with_resolver(self.resolve_change)
            .with_change_broadcast(
                f"{first_to_lower(self.name.replace("Mutation", ""))}Change"
            )
            .with_input(UserSettingInput, "input")
            .with_require_any([], [self._check_user])
        )

    @staticmethod
    async def _check_user(ctx):
        return ctx.user.id == (await Route.get_user()).id

    @staticmethod
    async def resolve_change(obj: UserSettingInput, *_):
        logger.debug(f"create new setting: {input}")
        user = await Route.get_user_or_default()
        if user is None:
            logger.debug("user not authorized")
            return None

        setting = await userSettingDao.find_single_by(
            [{UserSetting.user_id: user.id}, {UserSetting.key: obj.key}]
        )
        if setting is None:
            await userSettingDao.create(UserSetting(0, user.id, obj.key, obj.value))
        else:
            setting.value = obj.value
            await userSettingDao.update(setting)

        return await userSettingDao.find_by_key(user, obj.key)
