from urllib.parse import urlparse

from django.forms import ModelForm
from django.http import HttpRequest, HttpResponse, HttpResponseForbidden
from pyrogram import Chat as PyrogramChat
from pyrogram.api.types.chat import Chat as MTProtoChat
from pyrogram.api.types.user import User as MTProtoUser
from pyrogram.api.types.channel import Channel as MTProtoChannel


def parse_mtproto_chat(client, chat):
    if isinstance(chat, MTProtoChat):
        return PyrogramChat._parse_chat_chat(client, chat)
    elif isinstance(chat, MTProtoUser):
        return PyrogramChat._parse_user_chat(client, chat)
    return PyrogramChat._parse_channel_chat(client, chat)


def same_origin(current_uri, redirect_uri):
    a = urlparse(current_uri)
    if not a.scheme:
        return True
    b = urlparse(redirect_uri)
    return (a.scheme, a.hostname, a.port) == (b.scheme, b.hostname, b.port)


def turbolinks(request: HttpRequest):
    ctx = {}
    if request.META.get('HTTP_TURBOLINKS_REFERRER') is not None:
        ctx['is_turbolinks'] = True
    return ctx


class TurbolinksMiddleware:
    def process_request(self, request: HttpRequest):
        referrer = request.META.get('HTTP_TURBOLINKS_REFERRER')
        if referrer:
            request.META['HTTP_REFERER'] = referrer
        return

    def process_response(self, request: HttpRequest, response: HttpResponse):
        referrer = request.META.get('HTTP_TURBOLINKS_REFERRER')
        if referrer is None:
            return response

        if response.has_header('Location'):
            loc = response['Location']
            request.session['_turbolinks_redirect_to'] = loc

            if referrer and not same_origin(loc, referrer):
                return HttpResponseForbidden()
        else:
            if request.session.get('_turbolinks_redirect_to'):
                loc = request.session.pop('_turbolinks_redirect_to')
                response['Turbolinks-Location'] = loc

        return response


def get_config_form(mdl):
    class ConfigForm(mdl.CONFIG_FORM_CLASS if hasattr(mdl, 'CONFIG_FORM_CLASS') else ModelForm):
        prefix = 'config'

        class Meta:
            model = mdl
            exclude = mdl.EXCLUDE_FIELDS if hasattr(mdl, 'EXCLUDE_FIELDS') else ()
            widgets = mdl.CUSTOM_WIDGETS if hasattr(mdl, 'CUSTOM_WIDGETS') else {}
    return ConfigForm


class AllowCORSMixin(object):
    def add_access_control_headers(self, response):
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Methods"] = "GET, OPTIONS"
        response["Access-Control-Max-Age"] = "1000"
        response["Access-Control-Allow-Headers"] = "X-Requested-With, Content-Type"

    def options(self, request, *args, **kwargs):
        response = HttpResponse()
        self.add_access_control_headers(response)
        return response
