import json

from django.views.decorators.http import require_http_methods

from staff.lib.decorators import (
    responding_json,
    use_request_lang,
    available_for_external,
)
from staff.lib.forms.staff_form_grid import StaffFormGrid

from ..controllers import duties as ctl
from ..forms.duties import DutyForm
from staff.lib.forms.errors import (
    invalid_json_error,
    form_data_error,
    default_error,
)
from ..permissions.utils import observer_has_perm
from ..views.candidate_info_view import candidate_info

import logging
logger = logging.getLogger('person_profile.edit_views.edit_duties_view')

FORM_NAME = 'duties'


@responding_json
@available_for_external
@require_http_methods(['GET', 'POST'])
@observer_has_perm('edit_duties')
@use_request_lang
def edit_duties(request, login):
    if request.method == 'GET':
        return {
            FORM_NAME: (
                StaffFormGrid(DutyForm, initial=[ctl.get_duties_initial(login)])
                .as_front_dict()
            )
        }

    try:
        form_data = json.loads(request.body)[FORM_NAME][0]
    except ValueError:
        logger.exception('Wrong JSON: %s', request.body)
        return invalid_json_error(request.body), 400
    except (KeyError, IndexError):
        logger.exception('Cannot find form data: %s', FORM_NAME)
        return form_data_error(FORM_NAME), 400

    grid = StaffFormGrid(DutyForm, data=[form_data])
    if not grid.is_valid():
        return {'errors': {FORM_NAME: grid.errors()}}

    try:
        ctl.update_duties(login, grid.cleaned_data[0], request.user)
    except ctl.DutiesError:
        return default_error(), 500

    if request.permissions_ctl.is_available('candidate_info', login):
        return candidate_info(request, login)
    return {}
