import json
import logging

import formencode

from pyramid.httpexceptions import HTTPFound
from rhodecode.apps._base import BaseAppView
from rhodecode.apps._base.navigation import navigation_list
from rhodecode.apps.ai_agents.ai_service import get_ai_service
from rhodecode.apps.ai_agents.ai_settings import AIModelName
from rhodecode.apps.ai_agents.models.base import AIService
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired
from rhodecode.lib import helpers as h
from rhodecode.model.db import User
from rhodecode.model.forms import AiSettingsForm, AiSettingsModelVersionUpdateForm, UserQuotasSettingsForm
from rhodecode.model.quota_model import UserQuotaModel
from rhodecode.model.settings import SettingsModel
from rhodecode.model.meta import Session

log = logging.getLogger(__name__)


class AdminUserQuotasView(BaseAppView):
    def load_default_context(self):
        c = self._get_local_tmpl_context()
        return c

    @LoginRequired()
    @HasPermissionAllDecorator("hg.admin")
    def admin_settings_user_quotas(self):
        c = self.load_default_context()
        c.active = "user_quotas"
        c.navlist = navigation_list(self.request)

        app_settings = c.rc_config
        c.user_quotas_enabled = app_settings.get("rhodecode_user_quotas_enabled", UserQuotaModel.DEFAULT_QUOTAS_ENABLED)
        c.global_user_repo_quotas = app_settings.get(
            "rhodecode_global_user_repo_quotas", UserQuotaModel.DEFAULT_REPO_QUOTA
        )

        return self._get_template_context(c)

    @CSRFRequired()
    @LoginRequired()
    @HasPermissionAllDecorator("hg.admin")
    def admin_settings_user_quotas_update(self):
        c = self.load_default_context()
        c.active = "user_quotas"
        c.navlist = navigation_list(self.request)
        _ = self.request.translate

        parsed_form = self._parse_form(_)
        self._save_settings(_, parsed_form)

        return HTTPFound(h.route_path("admin_settings_user_quotas"))

    def _save_settings(self, _, data):
        try:
            repo_quotas_key = "rhodecode_global_user_repo_quotas"
            apply_user_quotas = False

            settings = [
                ("user_quotas_enabled", "rhodecode_user_quotas_enabled", "bool"),
                ("global_user_repo_quotas", repo_quotas_key, "int"),
            ]
            for setting, form_key, type_ in settings:
                sett = SettingsModel().create_or_update_setting(setting, data[form_key], type_)
                if setting == "user_quotas_enabled" and isinstance(data[form_key], bool):
                    apply_user_quotas = data[form_key]

                Session().add(sett)

            Session().commit()
            SettingsModel().invalidate_settings_cache()
            if apply_user_quotas:
                h.flash(_(f"Applying user quotas, value: {data[repo_quotas_key]}"), category="success")
                self._apply_user_repo_quotas()

            h.flash(_("User Quotas settings saved"), category="success")
        except Exception as e:
            log.exception("Exception saving User Quotas settings: %s", e)
            h.flash(_(f"Error occurred during saving User Quotas settings, error: {str(e)}"), category="error")

    def _parse_form(self, _):
        try:
            form = UserQuotasSettingsForm()()
            data = form.to_python(self.request.POST)
        except formencode.Invalid as errors:
            error = errors
            h.flash(_(f"Invalid form error: {error}"), category="error")
            raise HTTPFound(h.route_path("admin_settings_user_quotas"))
        return data

    def _apply_user_repo_quotas(self):
        for user in User.get_all():
            UserQuotaModel(user).init_quotas()
