# -*- coding: utf-8 -*-
from django.conf import settings
from typing import List

from events.surveyme.models import Survey
from events.v3.perms import check_perm, change_permissions, get_permissions_out
from events.v3.schemas import (
    SurveyOut, VariableInfoOut, VariableCategoryInfoOut, RendererInfoOut,
    PermissionIn, PermissionOut,
)
from events.v3.types import SurveyId
from events.v3.views.hooks import get_hooks_out
from events.v3.utils import get_survey, set_master_db
from events.surveyme_integration.variables import variables_list


class SurveyParams:
    def __init__(self, survey):
        self.survey = survey

    @property
    def id(self):
        return self.survey.pk

    @property
    def name(self):
        return self.survey.get_name()

    @property
    def dir_id(self):
        return self.survey.get_dir_id()

    @property
    def is_published(self):
        return self.survey.is_published_external

    @property
    def is_public(self):
        return self.survey.is_public

    @property
    def language(self):
        return self.survey.language

    @property
    def hooks(self):
        return get_hooks_out(self.survey)

    def as_dict(self, fields: List[str] = None):
        fields = fields or SurveyOut.__fields__
        params = {
            field: getattr(self, field, None)
            for field in fields
        }
        if 'id' not in params:
            params['id'] = self.id
        return params


def get_survey_out(survey: Survey, fields: List[str] = None) -> SurveyOut:
    params = SurveyParams(survey).as_dict(fields)
    return SurveyOut(**params)


def get_survey_view(
    request,
    survey_id: SurveyId,
    fields: str = None,
) -> SurveyOut:
    model_fields = [
        'pk', 'name', 'translations', 'language',
        'is_published_external', 'is_public',
    ]
    survey = get_survey(survey_id, user=request.user, orgs=request.orgs, only=model_fields)
    check_perm(request.user, survey)
    if isinstance(fields, str):
        fields = fields.split(',')
    return get_survey_out(survey, fields=fields)


def get_variable_out(survey: Survey, variable_class) -> VariableInfoOut:
    if settings.IS_BUSINESS_SITE and survey.org_id is None and variable_class.connect_only:
        return
    params = {
        'type': variable_class.name,
        'name': str(variable_class.title),
    }
    if variable_class.category:
        params['category'] = VariableCategoryInfoOut(
            type=variable_class.category.name,
            name=str(variable_class.category.title),
        )
    if isinstance(variable_class.filters, dict):
        if variable_class.filters:
            params['filters'] = variable_class.filters
    if isinstance(variable_class.arguments, list):
        if variable_class.arguments:
            params['arguments'] = variable_class.arguments
    if variable_class.renderer_classes:
        params['renderers'] = [
            RendererInfoOut(
                type=renderer_class.format_name,
                name=str(renderer_class.format_title),
            )
            for renderer_class in variable_class.renderer_classes
        ]
    if settings.IS_BUSINESS_SITE:
        params['connect_only'] = variable_class.connect_only
    return VariableInfoOut(**params)


def get_variables_view(request, survey_id: SurveyId) -> List[VariableInfoOut]:
    survey = get_survey(survey_id, user=request.user, orgs=request.orgs, only=['pk'])
    check_perm(request.user, survey)
    result = []
    for variable_class in variables_list:
        out = get_variable_out(survey, variable_class)
        if out:
            result.append(out)
    return result


def get_survey_access_view(request, survey_id: SurveyId) -> List[PermissionOut]:
    survey = get_survey(survey_id, user=request.user, orgs=request.orgs, only=['pk', 'user_id'])
    check_perm(request.user, survey)
    return get_permissions_out(survey)


def post_survey_access_view(request, survey_id: SurveyId, data: List[PermissionIn]) -> List[PermissionOut]:
    survey = get_survey(survey_id, user=request.user, orgs=request.orgs, only=['pk', 'user_id'])
    check_perm(request.user, survey)
    with set_master_db():
        change_permissions(request.user, survey, data)
        return get_permissions_out(survey)
