"""
  @author: LinTao
  @time: 2022/9/11 15:05
  @desc:
"""
import time

from flask import session
from sqlalchemy import Table, func

from common.database import dbconnect
from module.users import Users

dbsession, md, DBase = dbconnect()


class Article(DBase):
    __table__ = Table('article', md, autoload=True)

    def find_all(self):
        """
        查询所有文章
        :return:
        """
        result = dbsession.query(Article).all()

    def find_by_id(self, articleid):
        """
        根据id查询文章
        :param articleid:
        :return:
        """
        row = dbsession.query(Article, Users.nickname) \
            .join(Users, Users.userid == Article.userid) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1,
                    Article.articleid == articleid).first()
        return row

    def find_limit_with_users(self, start, count):
        """
        指定分页的limit和offset的参数值，同时与用户表做连接查询
        :param start: 第几页
        :param count: 每页的数量
        :return:
        """
        result = dbsession.query(Article, Users.nickname) \
            .join(Users, Users.userid == Article.userid) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1) \
            .order_by(Article.articleid.asc()) \
            .limit(count).offset(start).all()
        return result

    def get_total_count(self):
        """
        统计一下当前文章的总数量
        :return:  文章的总数量
        """
        count = dbsession.query(Article).count()
        return count

    def find_by_type(self, type, start, count):
        """
        根据文章类型获取文章
        :param count:
        :param start:
        :param type:
        :return:
        """
        result = dbsession.query(Article, Users.nickname) \
            .join(Users, Users.userid == Article.userid) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1, Article.category == type) \
            .order_by(Article.articleid.asc()) \
            .limit(count).offset(start).all()
        return result

    def get_count_by_type(self, type):
        """
        根据文章类型来获取总数量
        :param type:
        :return:
        """
        count = dbsession.query(Article) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1, Article.category == type).count()
        return count

    def find_by_headline(self, headline, start, count):
        """
        根据文章标题进行模糊搜索
        :param headline:
        :return:
        """
        result = dbsession.query(Article, Users.nickname) \
            .join(Users, Users.userid == Article.userid) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1,
                    Article.headline.like('%' + headline + '%')) \
            .order_by(Article.articleid.desc()) \
            .limit(count).offset(start).all()
        return result

    def get_count_by_headline(self, headline):
        """
        根据文章标题进行模糊搜索后，统计搜索的总数量
        :param headline:
        :return:
        """
        count = dbsession.query(Article) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1,
                    Article.headline.like('%' + headline + '%')) \
            .count()
        return count

    def find_last_9(self):
        """
        最新文章
        :return:
        """
        result = dbsession.query(Article.articleid, Article.headline) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1) \
            .order_by(Article.articleid.desc()) \
            .limit(9).all()
        return result

    def find_most_9(self):
        """
        最多阅读
        :return:
        """
        result = dbsession.query(Article.articleid, Article.headline) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1) \
            .order_by(Article.readcount.desc()) \
            .limit(9).all()
        return result

    def find_recommended_9(self):
        """
        特别推荐，如果超过9篇可以考虑 order by rand() 的方式随机选择9篇
        :return:
        """
        result = dbsession.query(Article.articleid, Article.headline) \
            .filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1, Article.recommended == 1) \
            .order_by(func.rand()) \
            .limit(9).all()
        return result

    def find_last_most_recommended(self):
        """
        一次性返回三个推荐数据
        :return:
        """
        last = self.find_last_9()
        most = self.find_most_9()
        recommended = self.find_recommended_9()
        return last, most, recommended

    def update_read_count(self, articleid):
        """每阅读一次文章，阅读次数+1"""
        article = dbsession.query(Article).filter_by(articleid=articleid).first()
        article.readcount += 1
        dbsession.commit()

    def find_headline_by_id(self, articleid):
        """根据文章编号查询文章标题"""
        row = dbsession.query(Article.headline).filter_by(articleid=articleid).first()
        return row.headline

    def find_prev_next_by_id(self, articleid):
        """获取当前文章的上一篇和下一篇"""
        dict = {}

        # 查询比当前编号小的当中最大的一个
        row = dbsession.query(Article).filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1,
                                              Article.articleid < articleid) \
            .order_by(Article.articleid.desc()).limit(1).first()

        # 如果当前已经是第一篇，上一篇也是当前文章
        if row is None:
            prev_id = articleid
        else:
            prev_id = row.articleid
        dict['prev_id'] = prev_id
        dict['prev_headline'] = self.find_headline_by_id(prev_id)

        # 查询比当前编号大的当中最小的一个
        row = dbsession.query(Article).filter(Article.hide == 0, Article.drafted == 0, Article.checked == 1,
                                              Article.articleid > articleid) \
            .order_by(Article.articleid).limit(1).first()

        # 如果当前已经是最后一篇，下一篇也是当前文章
        if row is None:
            next_id = articleid
        else:
            next_id = row.articleid

        dict['next_id'] = next_id
        dict['next_headline'] = self.find_headline_by_id(next_id)

        return dict

    def update_replycount(self, articleid):
        """当发表或回复评论后，为文章表字段replycount加1"""
        row = dbsession.query(Article).filter_by(articleid=articleid).first()
        row.replycount += 1
        dbsession.commit()

    def insert_artice(self, type, headline, content, thumbnail, credit, drafted=0, checked=1):
        """插入一篇新的文章"""
        now = time.strftime('%Y-%m-%d %H:%M:%S')
        userid = session.get('userid')

        article = Article(userid=userid, category=type, headline=headline, content=content,
                          thumbnail=thumbnail, credit=credit, drafted=drafted,
                          checked=checked, createtime=now, updatetime=now)
        dbsession.add(article)
        dbsession.commit()
        return article.articleid  # 返回文章编号，用于前端跳转

    def update_artice(self, articleid, type, headline, content, thumbnail, credit, drafted=0, checked=1):
        """根据文章编号更新文章内容，可用于文章编辑或草稿修改，以及基于草稿得发布"""
        now = time.strftime('%Y-%m-%d %H:%M:%S')
        row = dbsession.query(Article).filter_by(articleid=articleid).first()
        row.type = type
        row.headline = headline
        row.content = content
        row.thumbnail = thumbnail
        row.credit = credit
        row.drafted = drafted
        row.checked = checked
        row.updatetime = now
        dbsession.commit()
        return articleid  # 返回文章编号，用于前端跳转


