# -*- coding: utf-8 -*-
#
import ipaddress
from datetime import datetime, timedelta
from urllib.parse import urljoin, urlparse

from django.conf import settings
from django.shortcuts import reverse
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _

from audits.models import UserLoginLog
from common.utils import get_ip_city, get_request_ip
from common.utils import get_logger, get_object_or_none
from common.utils import static_or_direct
from users.models import User
from .notifications import DifferentCityLoginMessage

logger = get_logger(__file__)


def check_different_city_login_if_need(user, request):
    if not settings.SECURITY_CHECK_DIFFERENT_CITY_LOGIN:
        return

    ip = get_request_ip(request) or '0.0.0.0'
    city_white = [_('LAN'), 'LAN']
    is_private = ipaddress.ip_address(ip).is_private
    if is_private:
        return
    usernames = [user.username, f"{user.name}({user.username})"]
    last_user_login = UserLoginLog.objects.exclude(
        city__in=city_white
    ).filter(username__in=usernames, status=True).first()
    if not last_user_login:
        return

    city = get_ip_city(ip)
    last_cities = UserLoginLog.objects.filter(
        datetime__gte=datetime.now() - timedelta(days=7),
        username__in=usernames,
        status=True
    ).exclude(city__in=city_white).values_list('city', flat=True).distinct()

    if city in last_cities:
        return

    DifferentCityLoginMessage(user, ip, city).publish_async()


def build_absolute_uri(request, path=None):
    """ Build absolute redirect """
    if path is None:
        path = '/'
    site_url = urlparse(settings.SITE_URL)
    scheme = site_url.scheme or request.scheme
    host = request.get_host()
    url = f'{scheme}://{host}'
    redirect_uri = urljoin(url, path)
    return redirect_uri


def build_absolute_uri_for_oidc(request, path=None):
    """ Build absolute redirect uri for OIDC """
    if path is None:
        path = '/'
    if settings.BASE_SITE_URL:
        # OIDC 专用配置项
        redirect_uri = urljoin(settings.BASE_SITE_URL, path)
        return redirect_uri
    return build_absolute_uri(request, path=path)


def check_user_property_is_correct(username, **properties):
    user = get_object_or_none(User, username=username)
    for attr, value in properties.items():
        if getattr(user, attr, None) != value:
            user = None
            break
    return user


def get_auth_methods():
    return [
        {
            'name': 'OpenID',
            'enabled': settings.AUTH_OPENID,
            'url': reverse('authentication:openid:login'),
            'logo': static('img/login_oidc_logo.png'),
            'auto_redirect': True  # 是否支持自动重定向
        },
        {
            'name': 'CAS',
            'enabled': settings.AUTH_CAS,
            'url': reverse('authentication:cas:cas-login'),
            'logo': static('img/login_cas_logo.png'),
            'auto_redirect': True
        },
        {
            'name': 'SAML2',
            'enabled': settings.AUTH_SAML2,
            'url': reverse('authentication:saml2:saml2-login'),
            'logo': static('img/login_saml2_logo.png'),
            'auto_redirect': True
        },
        {
            'name': settings.AUTH_OAUTH2_PROVIDER,
            'enabled': settings.AUTH_OAUTH2,
            'url': reverse('authentication:oauth2:login'),
            'logo': static_or_direct(settings.AUTH_OAUTH2_LOGO_PATH),
            'auto_redirect': True
        },
        {
            'name': _('WeCom'),
            'enabled': settings.AUTH_WECOM,
            'url': reverse('authentication:wecom-qr-login'),
            'logo': static('img/login_wecom_logo.png'),
        },
        {
            'name': _('DingTalk'),
            'enabled': settings.AUTH_DINGTALK,
            'url': reverse('authentication:dingtalk-qr-login'),
            'logo': static('img/login_dingtalk_logo.png')
        },
        {
            'name': _('FeiShu'),
            'enabled': settings.AUTH_FEISHU,
            'url': reverse('authentication:feishu-qr-login'),
            'logo': static('img/login_feishu_logo.png')
        },
        {
            'name': 'Lark',
            'enabled': settings.AUTH_LARK,
            'url': reverse('authentication:lark-qr-login'),
            'logo': static('img/login_lark_logo.png')
        },
        {
            'name': _('Slack'),
            'enabled': settings.AUTH_SLACK,
            'url': reverse('authentication:slack-qr-login'),
            'logo': static('img/login_slack_logo.png')
        },
        {
            'name': _("Passkey"),
            'enabled': settings.AUTH_PASSKEY,
            'url': reverse('api-auth:passkey-login'),
            'logo': static('img/login_passkey.png')
        }
    ]