# By: Riasat Ullah
# This file contains code for serving informational web pages.

from constants import api_paths, label_names as lnm, pages, static_vars, var_names
from context_manager import components_context, info_context
from django.core import exceptions
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.views.decorators.http import require_http_methods
from taskcallweb import settings
from translators import label_translator as lt
from utils import helpers
from validations import request_validator
import configuration as configs
import json


@require_http_methods(['GET'])
def get_home_page(request):
    if request.method == 'GET':
        return redirect(settings.REDIRECT_INFO_SITE)


@require_http_methods(['GET'])
def get_privacy_policy_page(request):
    if request.method == 'GET':
        return redirect(settings.REDIRECT_INFO_SITE + api_paths.info_site_privacy_policy)


@require_http_methods(['GET'])
def get_register_page(request):
    if request.method == 'GET':
        lang = request_validator.get_user_language(request)
        if 'step' in request.GET and var_names.registration_site_identifier in request.COOKIES:
            step = int(request.GET.get('step'))
            if step == 1:
                context = info_context.get_register_step_one_subdomain_region_context(lang)
                context[var_names.user_lang_items] = components_context.get_languages_content(context)
                if settings.TEST_MODE:
                    context[var_names.taskcall_domain] = static_vars.regional_test_server_urls[settings.REGION][
                        var_names.domain]
                else:
                    context[var_names.taskcall_domain] = static_vars.regional_urls[settings.REGION][var_names.domain]
                return render(request, pages.register_org_step_1_page, context=context)
            elif step == 2:
                context = info_context.get_register_step_two_owner_info_context(lang)
                if 'error' in request.GET:
                    context[var_names.error_message] = request.GET.get('error')
                context[var_names.country_code] = helpers.get_info_from_ip_address(
                    request.META.get(static_vars.ip_address_attribute), static_vars.ip_country_code_attribute)
                context[var_names.user_lang_items] = components_context.get_languages_content(context)
                return render(request, pages.register_org_step_2_page, context=context)
            elif step == 3:
                context = info_context.get_register_step_three_owner_verification_context(lang)
                context[var_names.user_lang_items] = components_context.get_languages_content(context)
                return render(request, pages.register_org_step_3_page, context=context)
            elif step == 4:
                context = info_context.get_register_step_four_organization_info_context(lang)
                context[var_names.country_code] = helpers.get_info_from_ip_address(
                    request.META.get(static_vars.ip_address_attribute), static_vars.ip_country_code_attribute)
                context[var_names.user_lang_items] = components_context.get_languages_content(context)
                return render(request, pages.register_org_step_4_page, context=context)

        context = info_context.get_register_initiate_context(lang)
        context[var_names.user_lang_items] = components_context.get_languages_content(context)
        return render(request, pages.register_org_page, context=context)


@require_http_methods(['GET'])
def get_register_member_page(request):
    if request.method == 'GET':
        lang = request_validator.get_user_language(request)
        if 'step' in request.GET and var_names.registration_site_identifier in request.COOKIES:
            step = int(request.GET.get('step'))
            if step == 1:
                context = info_context.get_register_member_personal_info_context(lang)
                context[var_names.country_code] = helpers.get_info_from_ip_address(
                    request.META.get(static_vars.ip_address_attribute), static_vars.ip_country_code_attribute)
                context[var_names.user_lang_items] = components_context.get_languages_content(context)
                return render(request, pages.register_member_step_1_page, context=context)

        context = info_context.get_register_member_initiate_context(lang)
        context[var_names.user_lang_items] = components_context.get_languages_content(context)
        return render(request, pages.register_member_page, context=context)


@require_http_methods(['GET'])
def get_auto_provision_member_page(request):
    if request.method == 'GET':
        # The 'state' parameter must be provided and must match the session key
        if 'state' in request.GET and request.GET.get('state') == request.session.session_key:
            lang = request_validator.get_user_language(request)
            context = info_context.get_member_auto_provision_context(lang)
            context[var_names.country_code] = helpers.get_info_from_ip_address(
                request.META.get(static_vars.ip_address_attribute), static_vars.ip_country_code_attribute)
            context[var_names.user_lang_items] = components_context.get_languages_content(context)
            context['state'] = request.GET.get('state')
            return render(request, pages.auto_provision_member_page, context=context)
        else:
            raise exceptions.PermissionDenied


@require_http_methods(['POST'])
def set_language_preference(request):
    if request.method == 'POST':
        curr_lang = request_validator.get_user_language(request)
        new_lang = json.loads(request.body.decode())[var_names.language]
        resp = JsonResponse(lnm.msg_success, safe=False)

        if curr_lang != new_lang and new_lang in [static_vars.lang_en, static_vars.lang_es]:
            request.session[var_names.language] = new_lang
            resp.set_cookie(var_names.language, new_lang, max_age=configs.DEFAULT_COOKIE_LIFETIME, secure=True,
                            domain=static_vars.base_domain, httponly=True, samesite='None')

        return resp


@require_http_methods(['POST'])
def switch_data_center_region(request, page_name=None):
    '''
    Switch the data center region.
    :param request: Http request
    :param page_name: name of the page to redirect to
    :return: Http response
    '''
    if request.method == 'POST':
        new_region = json.loads(request.body.decode())[var_names.host_region]

        if settings.REGION != new_region:
            rdr_url = helpers.get_redirect_url_for_switching_region(request, new_region, page_name)
            if rdr_url is not None:
                resp = JsonResponse(rdr_url, status=200, safe=False)
                resp.set_cookie(var_names.host_region, new_region, max_age=configs.DEFAULT_COOKIE_LIFETIME, secure=True,
                                domain=static_vars.base_domain, httponly=True, samesite='None')
                return resp

        return JsonResponse(lnm.msg_success, status=200, safe=False)


@require_http_methods(['GET'])
def handler403(request, exception):
    '''
    Handles 403 errors
    :param request: Http request
    :return: Http response
    '''
    lang = request_validator.get_user_language(request)
    context = {
        var_names.error_code: 403,
        var_names.error_message: lt.get_label(lnm.err_unauthorized_access, lang)
    }
    return render(request, pages.error_page, context=context)


@require_http_methods(['GET'])
def handler404(request, exception):
    '''
    Handles 404 errors
    :param request: Http request
    :return: Http response
    '''
    lang = request_validator.get_user_language(request)
    context = {
        var_names.error_code: 404,
        var_names.error_message: lt.get_label(lnm.err_unknown_resource, lang)
    }
    return render(request, pages.error_page, context=context)


@require_http_methods(['GET'])
def handler500(request):
    '''
    Handles 500 errors
    :param request: Http request
    :return: Http response
    '''
    lang = request_validator.get_user_language(request)
    context = {
        var_names.error_code: 500,
        var_names.error_message: lt.get_label(lnm.err_system_error, lang)
    }
    return render(request, pages.error_page, context=context)
