#xy: Django博客信号处理器模块
import _thread
import logging

import django.dispatch
from django.conf import settings
from django.contrib.admin.models import LogEntry
from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.core.mail import EmailMultiAlternatives
from django.db.models.signals import post_save
from django.dispatch import receiver

from comments.models import Comment
from comments.utils import send_comment_email
from djangoblog.spider_notify import SpiderNotify
from djangoblog.utils import cache, expire_view_cache, delete_sidebar_cache, delete_view_cache
from djangoblog.utils import get_current_site
from oauth.models import OAuthUser

logger = logging.getLogger(__name__)

#xy: 自定义信号定义
oauth_user_login_signal = django.dispatch.Signal(['id'])
send_email_signal = django.dispatch.Signal(
    ['emailto', 'title', 'content'])


@receiver(send_email_signal)
def send_email_signal_handler(sender, **kwargs):
    """#xy: 邮件发送信号处理器"""
    emailto = kwargs['emailto']
    title = kwargs['title']
    content = kwargs['content']

    #xy: 创建邮件消息
    msg = EmailMultiAlternatives(
        title,
        content,
        from_email=settings.DEFAULT_FROM_EMAIL,
        to=emailto)
    msg.content_subtype = "html"

    #xy: 记录邮件发送日志
    from servermanager.models import EmailSendLog
    log = EmailSendLog()
    log.title = title
    log.content = content
    log.emailto = ','.join(emailto)

    try:
        result = msg.send()
        log.send_result = result > 0
    except Exception as e:
        logger.error(f"失败邮箱号: {emailto}, {e}")
        log.send_result = False
    log.save()


@receiver(oauth_user_login_signal)
def oauth_user_login_signal_handler(sender, **kwargs):
    """#xy: OAuth用户登录信号处理器"""
    id = kwargs['id']
    try:
        oauthuser = OAuthUser.objects.get(id=id)
        site = get_current_site().domain
        #xy: 处理用户头像
        if oauthuser.picture and not oauthuser.picture.find(site) >= 0:
            from djangoblog.utils import save_user_avatar
            oauthuser.picture = save_user_avatar(oauthuser.picture)
            oauthuser.save()

        delete_sidebar_cache()
    except OAuthUser.DoesNotExist:
        logger.warning(f"OAuth用户不存在: {id}")


@receiver(post_save)
def model_post_save_callback(
        sender,
        instance,
        created,
        raw,
        using,
        update_fields,
        **kwargs):
    """#xy: 模型保存后的回调函数"""
    clearcache = False

    #xy: 跳过LogEntry模型的保存处理
    if isinstance(instance, LogEntry):
        return

    #xy: 处理具有完整URL的模型
    if 'get_full_url' in dir(instance):
        is_update_views = update_fields == {'views'}
        if not settings.TESTING and not is_update_views:
            try:
                notify_url = instance.get_full_url()
                SpiderNotify.baidu_notify([notify_url])
            except Exception as ex:
                logger.error("notify sipder", ex)
        if not is_update_views:
            clearcache = True

    #xy: 处理评论保存
    if isinstance(instance, Comment):
        if instance.is_enable:
            path = instance.article.get_absolute_url()
            site = get_current_site().domain
            if site.find(':') > 0:
                site = site[0:site.find(':')]

            #xy: 清除相关缓存
            expire_view_cache(
                path,
                servername=site,
                serverport=80,
                key_prefix='blogdetail')
            if cache.get('seo_processor'):
                cache.delete('seo_processor')
            comment_cache_key = 'article_comments_{id}'.format(
                id=instance.article.id)
            cache.delete(comment_cache_key)
            delete_sidebar_cache()
            delete_view_cache('article_comments', [str(instance.article.pk)])

            #xy: 异步发送评论邮件
            _thread.start_new_thread(send_comment_email, (instance,))

    #xy: 清除缓存
    if clearcache:
        cache.clear()


@receiver(user_logged_in)
@receiver(user_logged_out)
def user_auth_callback(sender, request, user, **kwargs):
    """#xy: 用户登录/登出回调函数"""
    if user and user.username:
        logger.info(f"用户认证操作: {user.username}")
        delete_sidebar_cache()
        # cache.clear()