import json
from datetime import datetime, timedelta

from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from django.urls import reverse
from django.utils import timezone

import blog
from blog import models
from system.error.ServerException import ServerException


@login_required(login_url='/login')
def article(request):
    page = request.GET.get('page')
    search_title = request.GET.get('search_title')
    search_content = request.GET.get('search_content')
    search_category = request.GET.get('search_category')
    if page is None:
        page = 0
    articles = blog.controller.article.get_article(is_paginator=True, page=int(page), search_title=search_title,
                                                   search_content=search_content, search_category=search_category,draft=False)
    return render(request, 'management/article/article.html', context={'articles': articles})


@login_required(login_url='/login')
def draft(request):
    page = request.GET.get('page')
    search_title = request.GET.get('search_title')
    search_content = request.GET.get('search_content')
    search_category = request.GET.get('search_category')
    if page is None:
        page = 0
    articles = blog.controller.article.get_article(is_paginator=True, page=int(page), search_title=search_title,
                                                   search_content=search_content, search_category=search_category,
                                                   draft=True)
    return render(request, 'management/article/draft.html', context={'articles': articles})

@login_required(login_url='/login')
def set_status(request,pk):

    article = models.Article.objects.filter(id=int(pk)).first()
    if article is not None:
        if article.status == 0:
            article.status = 1
        else:
            article.status = 0
        article.save()
        # 把所有 GET 参数重新编码(可能包含 page,也可能不包含)
        query = request.GET.urlencode()  # e.g. "page=2&foo=bar" 或者 ""

        # 构造基础列表页 URL
        base = '/management/article'  # 或者直接 '/management/article'

        # 如果有任何查询参数,就拼接 ?xxx,否则直接跳
        redirect_url = f'{base}?{query}' if query else base
        return redirect(redirect_url)


@login_required(login_url='/login')
def cancel_show_index(request, pk):
    article = models.Article.objects.get(id=int(pk))
    article.is_top = False
    article.save()
    return HttpResponseRedirect('/')  # 跳转到主界面

@login_required(login_url='/login')
def show_show_index(request, pk):
    article = models.Article.objects.get(id=int(pk))
    article.is_top = True
    article.save()
    return HttpResponseRedirect('/')  # 跳转到主界面


def new(request):
    return render(request, 'management/article/new_article.html')


def show_article(request, pk):
    article = models.Article.objects.filter(id=int(pk)).values('id', 'title', 'intro', 'category',
                                                               'user', 'created_time', 'type',
                                                               'cover__file_net_path',
                                                               'music__file_net_path', 'status',
                                                               'category__name',
                                                               'user__first_name', 'user_id',
                                                               'user__last_name', 'markdown_text', 'is_top',
                                                               'html_text').first()
    comments = models.Comment.objects.filter(article_id=article['id'])
    # request.session['msg'] = ''
    from blog.views import get_record_and_tags
    result = get_record_and_tags()



    return render(request, 'blog.html', context={'article': article, 'records': result['records'],
                                                 'tags': result['tags'], 'comments': comments})


@login_required(login_url='/')
def to_edit(request, pk):
    article = models.Article.objects.filter(id=int(pk)).values('id', 'title', 'intro', 'category',
                                                               'user', 'created_time', 'type',
                                                               'cover__file_net_path',
                                                               'music__file_net_path', 'status',
                                                               'category__name',
                                                               'user__first_name', 'user_id',
                                                               'user__last_name', 'markdown_text', 'html_text',
                                                               'is_top').first()
    tags = models.Tags.objects.raw(
        'select * from blog_tags left join blog_article_tags bat on blog_tags.id = bat.tags_id where  bat.article_id = {0}'.format(
            int(pk)))
    tags_str = []
    for tag in tags:
        tags_str.append(tag.name)
    return render(request, 'management/article/edit_article.html',
                  context={'article': article, 'tags': ','.join(tags_str)})


@login_required(login_url='/')
def edit_article(request):
    if request.method == 'POST':
        title = request.POST['title']
        intro = request.POST['intro']
        category = request.POST['category']
        html_text = request.POST['html']
        markdown_text = request.POST['markdown']
        type_ = request.POST['type']
        status = request.POST['status']
        tags = request.POST['tags']
        pk = request.POST['pk']
        is_top = request.POST['is_top']
        category_obj = models.Category.objects.get(id=category)

        article_obj = models.Article.objects.get(id=int(pk))
        tags_id = []
        for tag in str(tags).split(','):
            if tag == '':
                break
            else:
                tag_obj = models.Tags.objects.filter(name=tag).first()
                if tag_obj is None:
                    obj = models.Tags(name=tag)
                    obj.save()
                    tags_id.append(obj.pk)
                else:
                    tags_id.append(tag_obj.pk)
        if len(tags_id) > 0:
            article_obj.tags.set(tags_id)
        # models.Article.objects.filter(id=int(pk)).update(title=title, intro=intro, category=category_obj,
        #                                                  html_text=html_text,
        #                                                  markdown_text=markdown_text,
        #                                                  type=type_, status=status,
        #                                                  tags=str(tags).split(',')
        #                                                  )
        article_obj.title = title
        article_obj.intro = intro
        article_obj.category = category_obj
        article_obj.html_text = html_text
        article_obj.markdown_text = markdown_text
        article_obj.type = type_
        article_obj.status = status
        article_obj.is_top = is_top
        article_obj.save()
        return JsonResponse({"success": True, "message": "修改成功"})
    else:
        raise ServerException("错误的请求")


@login_required(login_url='/')
def add_article(request):
    if request.method == 'POST':
        title = request.POST['title']
        intro = request.POST['intro']
        category = request.POST['category']
        html_text = request.POST['html']
        markdown_text = request.POST['markdown']
        type_ = request.POST['type']
        status = request.POST['status']
        tags = request.POST['tags']
        is_top = request.POST['is_top']

        category_obj = models.Category.objects.get(id=category)

        article_obj = models.Article.objects.create(title=title, intro=intro, category=category_obj,
                                                    html_text=html_text,
                                                    markdown_text=markdown_text,
                                                    type=type_, status=status, user=request.user,
                                                    created_time=datetime.now() ,
                                                    is_top=is_top
                                                    )
        now_utc = timezone.now()
        plus_eight = now_utc + timedelta(hours=8)

        article_obj.created_time = plus_eight
        article_obj.save(update_fields=['created_time'])
        tags_id = []
        for tag in str(tags).split(','):
            if tag == '':
                break
            else:
                tag_obj = models.Tags.objects.filter(name=tag).first()
                if tag_obj is None:
                    obj = models.Tags(name=tag)
                    obj.save()
                    tags_id.append(obj.pk)
                else:
                    tags_id.append(tag_obj.pk)
        if len(tags_id) > 0:
            article_obj.tags.set(tags_id)
        return JsonResponse({"success": True, "message": "添加成功"})
    else:
        raise ServerException("错误的请求")


@login_required(login_url='/')
def add_media(request):
    if request.method == 'POST':
        title = request.POST['title']
        category = request.POST['category']
        type_ = request.POST['type']
        status = request.POST['status']
        tags = request.POST['tags']
        cover = request.POST['cover_id']
        music_id = request.POST['music_id']
        cover_obj = models.FileRecord.objects.get(id=cover)
        music_obj = models.FileRecord.objects.get(id=music_id)

        category_obj = models.Category.objects.get(id=category)
        article_obj = models.Article.objects.create(title=title, category=category_obj,
                                                    type=type_, status=status, user=request.user,
                                                    created_time=datetime.now() + timedelta(hours=8),
                                                    cover=cover_obj, music=music_obj
                                                    )
        if tags != 'null':
            article_obj.tags.set(str(tags).split(','))
        return JsonResponse({"success": True, "message": "添加成功"})
    else:
        raise ServerException("错误的请求")


@login_required(login_url='/')
def add_music(request):
    if request.method == 'POST':
        title = request.POST['title']
        category = request.POST['category']
        type_ = request.POST['type']
        status = request.POST['status']
        tags = request.POST['tags']
        cover = request.POST['cover_id']
        music_id = request.POST['music_id']
        cover_obj = models.FileRecord.objects.get(id=cover)
        music_obj = models.FileRecord.objects.get(id=music_id)

        category_obj = models.Category.objects.get(id=category)
        article_obj = models.Article.objects.create(title=title, category=category_obj,
                                                    type=type_, status=status, user=request.user,
                                                    created_time=datetime.now(),
                                                    cover=cover_obj, music=music_obj
                                                    )
        if tags != 'null':
            article_obj.tags.set(str(tags).split(','))
        return JsonResponse({"success": True, "message": "添加成功"})
    else:
        raise ServerException("错误的请求")


def set_tag(articles):
    for i in range(len(articles)):
        tags = models.Tags.objects.raw(
            'select * from blog_tags left join blog_article_tags bat on blog_tags.id = bat.tags_id where  bat.article_id = {0}'.format(
                articles[i]['id']))
        tags_field = []
        for item in tags:
            tags_field.append(item.name)
        articles[i]['tags'] = tags_field


def get_article(top: int = -1, page: int = -1, is_paginator: bool = False, category: models.Category = None,
                tag: models.Tags = None, search_category: str = None, search_title: str = None,
                search_content: str = None, date_record: str = None,
                draft: bool = False):
    if category is None and tag is None and date_record is None and draft == False:
        search_dict = dict()
        search_dict['status'] = 1
        if search_title:
            search_dict['title__contains'] = search_title
        if search_content:
            search_dict['markdown_text__contains'] = search_content
        if search_category:
            search_dict['category'] = search_category
        articles = models.Article.objects.filter(**search_dict).order_by('-created_time').values(
            'id', 'title', 'intro', 'category',
            'user', 'created_time', 'type',
            'cover__file_net_path',
            'music__file_net_path', 'status',
            'category__name',
            'user__first_name', 'user_id',
            'user__last_name',
            'is_top', 'html_text')
    elif date_record is not None:
        date_format = "%Y-%m"
        date = datetime.strptime(date_record, date_format)
        articles = models.Article.objects.filter(created_time__year=date.year, created_time__month=date.month).order_by(
            '-created_time').values('id', 'title',
                                    'intro',
                                    'category',
                                    'user',
                                    'created_time',
                                    'type',
                                    'cover__file_net_path',
                                    'music__file_net_path',
                                    'status',
                                    'category__name',
                                    'user__first_name',
                                    'user_id',
                                    'user__last_name',
                                    'is_top',
                                    'html_text').distinct()
    elif tag is not None:
        articles = models.Article.objects.filter(tags__name=tag.name).order_by('-created_time').values('id', 'title',
                                                                                                       'intro',
                                                                                                       'category',
                                                                                                       'user',
                                                                                                       'created_time',
                                                                                                       'type',
                                                                                                       'cover__file_net_path',
                                                                                                       'music__file_net_path',
                                                                                                       'status',
                                                                                                       'category__name',
                                                                                                       'user__first_name',
                                                                                                       'user_id',
                                                                                                       'user__last_name',
                                                                                                       'tags__name',
                                                                                                       'is_top',
                                                                                                       'html_text')
    elif draft:
        search_dict = dict()
        search_dict['status'] = 0

        if search_title:
            search_dict['title__contains'] = search_title
        if search_content:
            search_dict['markdown_text__contains'] = search_content
        if search_category:
            search_dict['category'] = search_category
        articles = models.Article.objects.filter(**search_dict).order_by('-created_time').values('id', 'title',
                                                                                                 'intro',
                                                                                                 'category',
                                                                                                 'user',
                                                                                                 'created_time',
                                                                                                 'type',
                                                                                                 'cover__file_net_path',
                                                                                                 'music__file_net_path',
                                                                                                 'status',
                                                                                                 'category__name',
                                                                                                 'user__first_name',
                                                                                                 'user_id',
                                                                                                 'user__last_name',
                                                                                                 'is_top',
                                                                                                 'html_text').distinct()
    else:
        articles = models.Article.objects.filter(category=category).order_by('-created_time').values('id', 'title',
                                                                                                     'intro',
                                                                                                     'category',
                                                                                                     'user',
                                                                                                     'created_time',
                                                                                                     'type',
                                                                                                     'cover__file_net_path',
                                                                                                     'music__file_net_path',
                                                                                                     'status',
                                                                                                     'category__name',
                                                                                                     'user__first_name',
                                                                                                     'user_id',
                                                                                                     'user__last_name',
                                                                                                     'is_top',
                                                                                                     'html_text')

    if is_paginator:
        if page <= 0:
            page = 1
        paginator = Paginator(articles, 15)
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        set_tag(articles=articles)

        return articles
    else:
        articles = list(articles)
    if top > -1:
        articles = articles[:top]
    set_tag(articles=articles)
    return articles
    # return JsonResponse({'all_article': json.loads(json.dumps(articles, default=str))})


@login_required(login_url='/')
def get_all_article(request):
    articles = models.Article.objects.order_by('-created_time').values('id', 'title',
                                                                       'intro',
                                                                       'category',
                                                                       'user',
                                                                       'created_time',
                                                                       'type',
                                                                       'cover__file_net_path',
                                                                       'music__file_net_path',
                                                                       'status',
                                                                       'category__name',
                                                                       'user__first_name', 'user_id',
                                                                       'user__last_name')
    return JsonResponse(json.loads(json.dumps(list(articles), default=str)), safe=False)


@login_required(login_url='/')
def delete_article(request):
    if request.method == 'GET':
        id = request.GET.get("id")
        article = models.Article.objects.get(id=int(id))
        article.tags.clear()
        article.delete()

        return HttpResponseRedirect('/management/article')  # 跳转到主界面
    else:
        raise ServerException("错误的请求")