from django.http.response import JsonResponse
from django.core.paginator import Paginator

from BookStore import error
from BookStore.function import check_method

from store.models import Store, Book, Tag

import jieba

NUM_PER_PAGE = 6
DEFAULT_SORT = 'hot'


# Create your views here.

def search_book(query, key='all', store=None):

    # 所有包含query的书本，此处未实现，只是返回所有书籍
    if key == 'all':
        books = Book.objects.all()
        if store:
            books = books.filter(store=store, off=False)

    # title包含query的书本
    elif key == 'title':
        books = Book.objects.filter(title__icontains=query)
        if store:
            books = books.filter(store=store, off=False)

    # author包含query的书本
    elif key == 'author':
        books = Book.objects.filter(author__icontains=query)
        if store:
            books = books.filter(store=store, off=False)

    # tag包含query的书本
    elif key == 'tag':
        books = [tag.book for tag in Tag.objects.filter(tag__icontains=query)]
        if store:
            temp = []
            for book in books:
                if book.store == store and book.off is False:
                    temp.append(book)
            books = temp

    # content包含query的书本
    elif key == 'content':
        books = Book.objects.filter(content__icontains=query)
        if store:
            books = books.filter(store=store, off=False)

    # book_intro包含query的书本
    elif key == 'book_intro':
        books = Book.objects.filter(bookIntro__icontains=query)
        if store:
            books = books.filter(store=store, off=False)

    # 不满足上述key则返回空列表
    else:
        books = []

    return books


def search_store(query, key='all'):

    # 所有包含query的store，此处未实现，只是返回所有店铺
    if key == 'all':
        stores = Store.objects.all()

    # title包含query的书本
    elif key == 'store_id':
        stores = Store.objects.filter(storeName__icontains=query)

    # author包含query的书本
    elif key == 'address':
        stores = Store.objects.filter(address__icontains=query)

    # 不满足上述key则返回空列表
    else:
        stores = []

    return stores


def sort_and_page(result, sort, page):
    result = list(result)

    if sort == 'latest':
        sorted(result, key=lambda x: x.createDate, reverse=True)
    elif sort == 'hot':
        sorted(result, key=lambda x: x.sold, reverse=True)
    else:
        pass

    paginator = Paginator(result, NUM_PER_PAGE)
    page_num = paginator.num_pages
    page = 1 if page < 1 else page
    page = page_num if page > paginator.num_pages else page

    result = paginator.page(page)

    return page_num, result


@check_method('GET')
def global_book_search_view(request):
    get = request.GET
    key = get.get('key')
    query = get.get('q')
    sort = get.get('sort', DEFAULT_SORT)
    page = int(get.get('page', 1))

    queries = list(jieba.cut(query))

    result = set(search_book(query, key))
    for query in queries:
        books = search_book(query, key)
        result = result & set(books)

    page_num, result = sort_and_page(result, sort, page)

    return JsonResponse({
        'message': 'ok',
        'num': len(result),
        'page_num': page_num,
        'books': [book.info_simple_json() for book in result]
    })


@check_method('GET')
def global_store_search_view(request):
    get = request.GET
    key = get.get('key')
    query = get.get('q')
    sort = get.get('sort', DEFAULT_SORT)
    page = int(get.get('page', 1))

    queries = list(jieba.cut(query))

    result = set(search_store(query, key))
    for query in queries:
        stores = search_store(query, key)
        result = result & set(stores)

    page_num, result = sort_and_page(result, sort, page)

    return JsonResponse({
        'message': 'ok',
        'num': len(result),
        'page_num': page_num,
        'stores': [store.info_json() for store in result]
    })


@check_method('GET')
def store_book_search_view(request):
    get = request.GET
    store_name = get.get('store_id')
    key = get.get('key', 'title')
    query = get.get('q', '')
    sort = get.get('sort', DEFAULT_SORT)
    page = int(get.get('page', 1))

    # 若无参数
    if store_name is None:
        code, message = error.invalid_parameter()
        return JsonResponse({
            'message': message,
        }, status=code)

    # 获取store
    try:
        store = Store.objects.get(storeName=store_name)
    except Store.DoesNotExist:
        code, message = error.store_id_doesnt_exist(store_name)
        return JsonResponse({
            'message': message,
        }, status=code)
    except Exception as e:
        print(e)
        code, message = error.database_error()
        return JsonResponse({
            'message': message,
        }, code)

    queries = list(jieba.cut(query))

    result = set(search_book(query, key, store))
    for query in queries:
        books = search_book(query, key, store)
        result = result & set(books)

    result = list(result)

    if sort == 'latest':
        sorted(result, key=lambda x: x.createDate, reverse=True)
    elif sort == 'hot':
        sorted(result, key=lambda x: x.sold, reverse=True)
    else:
        pass

    paginator = Paginator(result, NUM_PER_PAGE)
    page_num = paginator.num_pages
    page = 1 if page < 1 else page
    page = page_num if page > paginator.num_pages else page

    result = paginator.page(page)

    return JsonResponse({
        'message': 'ok',
        'books_page': page,
        'books_page_num': page_num,
        'book_num': len(result),
        'books': [book.info_simple_json() for book in result]
    })