import random
from datetime import datetime, timedelta

from gm_test import GmTestCase

from qa.models import Answer, AnswerReply, Question, AnswerTop, QuestionTag


def randstr():
    return "Text:" + str(random.randint(10000, 100000))


class QuestionTestCase(GmTestCase):

    patch_module = (
        "qa.views.answer.get_current_user",
        "qa.serializers.get_current_user"
    )

    def create_question(self):
        resp = self.call('qa/question/create', title=randstr(), content=randstr(), tags=[1], images=[])
        self.assertEqual(resp['error'], 0)
        self.assertIsInstance(resp['data']['question_id'], int)
        return resp['data']['question_id']

    def create_answer(self, question_id=None):
        if not question_id:
            question_id = self.create_question()
        resp = self.call('qa/answer/create', content=randstr(), question_id=question_id, images=[])
        self.assertEqual(resp['error'], 0)
        return resp['data']['answer_id']

    def create_answer_reply(self, answer_id=None):
        if not answer_id:
            answer_id = self.create_answer()
        resp = self.call('qa/answer/create_reply', content=randstr(), answer_id=answer_id, answer_reply_id=None)
        self.assertEqual(resp['error'], 0)
        resp = self.call('qa/answer/create_reply', content=randstr(), answer_id=answer_id,
                         answer_reply_id=resp['data']['reply_data']['reply_id'])
        return resp['data']['comment_data']['comment_id']

    def create_answer_top(self):
        question_id = self.create_question()
        answer_id = self.create_answer(question_id=question_id)
        question = Question.objects.get(pk=question_id)
        answer = Answer.objects.get(pk=answer_id)
        start = datetime.now() - timedelta(days=1)
        end = datetime.now() + timedelta(days=1)
        return AnswerTop.objects.create(question=question, answer=answer, start_time=start, end_time=end)

    def create_tag(self, question_id, tag_id):
        question = Question.objects.get(pk=question_id)
        QuestionTag.objects.create(question=question, tag=tag_id)

    def test_create_answer_reply(self):
        reply_id = self.create_answer_reply()
        self.assertTrue(int(reply_id))

    def test_vote_and_unvote(self):
        answer_id = self.create_answer()
        self.call('qa/answer/vote', answer_id=answer_id)
        answer = Answer.objects.get(pk=answer_id)
        self.assertEqual(answer.like_num, 1)
        self.call('qa/answer/unvote', answer_id=answer_id)
        answer.refresh_from_db()
        self.assertEqual(answer.like_num, 0)

    def test_answer_reply_vote_and_unvote(self):
        reply_id = self.create_answer_reply()
        self.call('qa/answer_reply/vote', answer_reply_id=reply_id)
        reply = AnswerReply.objects.get(pk=reply_id)
        self.assertEqual(reply.like_num, 1)
        self.call('qa/answer_reply/unvote', answer_reply_id=reply_id)
        reply.refresh_from_db()
        self.assertEqual(reply.like_num, 0)

    def test_list_exclude_answer(self):
        self.create_question()
        resp = self.call('qa/question/list_exclude_answer', start_num=0, count=10)
        self.assertTrue(len(resp['data']['questions']))

    def test_my_question_list(self):
        self.create_question()
        resp = self.call('qa/question/my_list', start_num=0, count=10)
        self.assertTrue(len(resp['data']))

    def test_my_answer_list(self):
        self.create_answer()
        resp = self.call('qa/answer/my_list', start_num=0, count=10)
        self.assertTrue(len(resp['data']))

    def test_related_question_info(self):
        answer_id = self.create_answer()
        resp = self.call('qa/answer/question_info', answer_id=answer_id)
        self.assertEqual(resp['data']['answer_count'], 1)

    def test_get_answer_reply(self):
        answer_id = self.create_answer()
        self.create_answer_reply(answer_id=answer_id)
        resp = self.call('qa/answer/get_answer_reply', answer_id=answer_id, start_num=0, count=10)
        self.assertTrue(len(resp['data']))

    def test_get_answer_detail(self):
        answer_id = self.create_answer()
        resp = self.call('qa/answer/get_answer_detail', answer_id=answer_id)
        self.assertEqual(resp['error'], 0)

    def test_get_nearby_answer(self):
        question_id = self.create_question()
        answer_prev_id = self.create_answer(question_id=question_id)
        answer_id = self.create_answer(question_id=question_id)
        answer_next_id = self.create_answer(question_id=question_id)
        resp = self.call('qa/answer/get_nearby_answer', answer_id=answer_id)
        self.assertEqual(resp['data']['pre_id'], answer_prev_id)
        self.assertEqual(resp['data']['next_id'], answer_next_id)

    def test_get_question_detail(self):
        question_id = self.create_question()
        self.create_answer(question_id=question_id)
        resp = self.call('qa/question/detail', question_id=question_id)
        self.assertEqual(resp['data']['answer_count'], 1)

    def test_get_question_author_detail(self):
        question_id = self.create_question()
        resp = self.call('qa/question/author', question_id=question_id)
        self.assertEqual(resp['error'], 0)

    def test_answer_detail(self):
        question_id = self.create_question()
        answer_id = self.create_answer(question_id=question_id)
        resp = self.call('qa/answer/detail', answer_id=answer_id)
        self.assertEqual(resp['data']['answer_id'], answer_id)
        self.assertEqual(resp['data']['belong_question']['question_id'], question_id)

    def test_get_question_answer_list(self):
        question_id = self.create_question()
        self.create_answer(question_id=question_id)
        self.create_answer(question_id=question_id)
        resp = self.call('qa/question/answer_list', question_id=question_id)
        self.assertEqual(len(resp['data']), 2)

    def test_user_question_list(self):
        self.create_question()
        self.create_question()
        resp = self.call('qa/question/get_user_qa_list', user_id=self.user.id)
        self.assertTrue(len(resp['data']))

    def test_question_top(self):
        self.create_answer_top()
        resp = self.call('qa/question/top', num=10)
        self.assertEqual(len(resp['data']), 1)

    def test_tag_related_question(self):
        question_id_prev = self.create_question()
        answer_id_prev = self.create_answer(question_id=question_id_prev)
        question_id_next = self.create_question()
        Question.objects.filter(pk=question_id_prev).update(is_recommend=True)
        self.create_tag(question_id_prev, 1)
        self.create_tag(question_id_next, 1)
        resp = self.call('qa/answer/tag_related_question', answer_id=answer_id_prev)

    def test_answer_reply_list(self):
        reply_id = self.create_answer_reply()
        resp = self.call('qa/answer_reply/list', pks=[reply_id])
        self.assertEqual(len(resp['data']), 1)