# encoding=utf-8
class MemosService
  include ApplicationHelper
  LIMIT = 10

  def new current_user, session
    csrf_token =  session[:_csrf_token] ||= SecureRandom.base64(32)
    tidding_count = unviewed_tiddings(current_user)
    tag_list = object_to_hash TagRepertoire.field_for_list.order("name asc")
    #tag_list = tag_list reps
    current_user_info = format_for_current_user current_user
    # csrf_token = SecureRandom.base64(32)
    {tag_list: tag_list, current_user: current_user_info, :csrf_token => csrf_token, :tidding_count => tidding_count}

  end

  # params 直接传params[:memo][:subject]
  #       subject标题
  #       content内容
  #       forum_id 话题类型
  #       sticky 是否置顶(创建时没入口)
  #       repertoire_name + language 技术标签
  #       attachments 附件
  #       tags 标签数组
  def create params, current_user
    return nil if params[:memo][:subject].blank? || params[:memo][:content].blank? || params[:memo][:forum_id].blank?
    memo = Memo.new(params[:memo])
    memo.author = current_user
    memo.save_attachments(params[:attachments]) if params[:attachments].present?
    memo.save!
    params[:tags].each do |tag|
      MemoTagRepertoire.create(:memo_id => memo.id, :tag_repertoire_id => tag)
    end
    {status: 0, message: "帖子创建成功!", memo_id: memo.id}
  end

  # params
  #       :id 帖子id
  # return
  #       :memo 帖子
  #       :memo_replies 帖子的回复
  #       :recommend_shixun 推荐实训
  #       :admin 当前用户是否是管理员
  #       :author_info 表示当前帖子用户的信息
  #
  def show params, current_user
    current_user ||= User.find(2)
    memo = Memo.find params[:id]
    # 消息总数
    tidding_count = unviewed_tiddings(current_user) if current_user
    attachments_list = acttachements_info memo.attachments

    memo_praise_count = memo.praise_tread.liker.count
    user_praise = PraiseTread.where(:praise_tread_object_id => memo.id, :praise_tread_object_type => "Memo",
                                    :user_id => current_user.try(:id), :praise_or_tread => 1).present? ? true : false

    unless memo.children.blank?
      memo.children.each do |child|
        child.memo_messages.each do |memo_message|
          memo_message.update_attributes(:viewed => true) if current_user.try(:id) == memo_message.user_id
        end
      end
    end

    query_memo_messages = memo.memo_messages
    unless query_memo_messages
      query_memo_messages.each do |query_memo_message|
        query_memo_message.update_attributes(:viewed => true) if current_user.try(:id) == query_memo_message.user_id
      end
    end
    memo.update_column(:viewed_count, memo.viewed_count + 1)
    replies_count = memo.all_replies
    # 帖子的回复
    memos = memo.reply_for_memo.includes(:praise_tread, :author).order("created_at desc").limit(LIMIT)
    watched = memo.author.watched_by?(current_user)
    list = memo_list memos, current_user

    is_md = memo.is_md
    author_info = {username: memo.author.show_name,
                   watched: watched,
                   image_url: url_to_avatar(memo.author),
                   identity: memo.author.identity,
                   login: memo.author.login,
                   user_id: memo.author.id}

    tags = memo.tag_repertoires.map(&:name)
    memo = {id: memo.id,
            subject: memo.subject,
            is_md: is_md,
            content: memo.content,
            time: memo.created_at,
            tag: tags,  # 标签是一个数组
            sticky: memo.sticky, # 置顶 1
            viewed_count: memo.viewed_count,
            replies_count: replies_count,
            praise_count: memo_praise_count,
            reward: memo.reward,
            attachment_url: attachments_list,
            user_praise: user_praise}
    current_user_info = format_for_current_user current_user
    { memo: memo, memo_replies: list, recommend_shixuns: recommends, author_info: author_info,
      current_user: current_user_info, tidding_count: tidding_count}
  end

  def more_reply params, current_user
    page = params[:page].to_i
    offset = page * LIMIT
    memo_id = params[:id]
    # 总数,分页使用
    memos_count =  Memo.where(:parent_id => memo_id).count
    memos = Memo.limit(LIMIT).where(:parent_id => memo_id).includes(:author, :praise_tread).order("created_at desc").offset(offset)
    list = memo_list memos, current_user
    return {:memo_replies => list, :memos_count => memos_count}
  end

  # 隐藏评论功能
  def hidden params, current_user
    memo = Memo.select([:id, :hidden]).find(params[:id])
    if current_user.admin?
      if params[:hidden] == "1"
        memo.update_attribute(:hidden, true)
      elsif params[:hidden] == "0"
        memo.update_column("hidden", false)
      end
    else
      raise("你没有权限")
    end
  end

  # return: tag_list 技术标签的所有数据, current_user 当前用户信息, attachments_url : 附件信息, tag: 帖子选中标签的信息
  def edit params, current_user
      #reps = Repertoire.field_for_list.order("updated_at asc")
      #tag_list = tag_list reps
      tag_list = object_to_hash TagRepertoire.field_for_list.order("name asc")
      memo = Memo.select([:id, :subject, :content, :forum_id, :repertoire_name]).find params[:id]
      tags = memo.tag_repertoires.map{|tag| {id:tag.id, name: tag.name}}
      attachments_list = acttachements_info memo.attachments
      current_user_info = format_for_current_user current_user
      memo.attributes.merge({tag_list: tag_list, current_user: current_user_info, attachments_url: attachments_list, tag: tags})
  end

  # params[:tags] 类型:数组(标签的id)
  def update params
    memo = Memo.find params[:id]
    if(memo.update_attributes(params[:memo]))
      # 为了将旧数据的KE转换为MD
      if !memo.is_md && params[:content_changed]
        memo.update_column(:is_md, true)
      end
      memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
    end
    memo.tag_repertoires.destroy_all
    params[:tags].each do |tag|
      MemoTagRepertoire.create(:memo_id => memo.id, :tag_repertoire_id => tag)
    end

    memo.save!
    {status: 0, message: "帖子更新成功!"}
  end

  # params
  #        排序:order -> 类型:字符串;值:replies_count最热  created_at 最新
  #        搜索:search -> 类型:字符串;
  #        类型:forum -> 类型:整型; 值:3 操作指南 5 技术分享
  #        用户:user_id -> 搜索那个用户的帖子(目前主要用来显示我的帖子)。
  #        标签:tag_repertoire_id -> 热门标签的tag_repertoire表的id
  # return:
  #        memo_list 列表
  #        memo_count 帖子的总数
  #        current_user 用户信息
  #        hot_memos 热门帖子
  #        recommend_shixuns 推荐实训
  #        hot_tags 热门标签
  #        my_memos_count 我的帖子数
  def get_memos_list params, current_user
    current_user ||= User.find(2)
    # all_replies_count 表示所有回复(一级+二级回复数) , replies_count表示帖子的回复(只包含一级回复)
    s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at"
    tidding_count = unviewed_tiddings(current_user) if current_user.present?
    page = params[:page].to_i
    offset = page * 15
    search = params[:search]
    forum_id = params[:forum]
    user_id = params[:user_id]
    if user_id.to_i == -1
      user_id = current_user.try(:id)
    end
    tag_repertoire_id = params[:tag_repertoire_id]
    sql =
        if forum_id
          search ?  "forum_id = #{forum_id} and root_id is null and subject like '%#{search}%'"
          : "forum_id = #{forum_id} and root_id is null"
        elsif search
          user_id ? "author_id=#{user_id.to_i} and forum_id in(3,5) and root_id is null and subject like '%#{search}%'"
          : "forum_id in(3,5) and root_id is null and subject like '%#{search}%'"
        else
          user_id ? "author_id=#{user_id.to_i} and forum_id in(3,5) and root_id is null"
          : "forum_id in(3,5) and root_id is null"
        end
    if tag_repertoire_id
      #language = Base64.urlsafe_decode64("#{language}")
      # 下面Memo表关联user表了,两个表中都包含language字段,因此 才在tag_repertoire_id前加入表名查询
      memo_ids = MemoTagRepertoire.where(:tag_repertoire_id => tag_repertoire_id).pluck(:memo_id)
      memo_ids = memo_ids ? memo_ids.join(",") : -1
      sql += " and #{Memo.table_name}.id in (#{memo_ids})"
    end
    # REDO:最新回复,不需要查看所有回复数为0的帖子
    if params[:order] == "updated_at"
     sql += " and all_replies_count != 0"
    end

    memos = Memo.field_for_list.includes(:praise_tread, :author).where("#{sql}")

    memos_count = memos.count # 帖子的总数
    memos = memos.order("sticky=1 desc, #{Memo.table_name}.#{s_order} desc").offset(offset).limit(15)
    memo_list = memo_data memos

    my_memos_count = Memo.user_posts(current_user.try(:id)).count
    # 标签只有forum_id = 5才有
    #hot_tags = Memo.find_by_sql("select distinct language from memos where forum_id = 5 and root_id is NULL and language is not NULL order by replies_count desc, created_at desc limit 9").map(&:language)
    tags_info = MemoTagRepertoire.find_by_sql("SELECT tag_repertoire_id, tr.name,count(*) cnt
                                               FROM `memo_tag_repertoires` mtr
                                               join tag_repertoires tr on tr.id = mtr.tag_repertoire_id
                                               group by tag_repertoire_id order by cnt desc, tag_repertoire_id desc limit 9")
    hot_tags = tags_info.map{|o| o.attributes.dup.except("cnt")}
    hot_memos = hot_memo_info Memo.field_for_recommend.posts.hot.limit(4)

    current_user_info = format_for_current_user current_user
    {memo_list: memo_list, memo_count: memos_count, hot_memos: hot_memos,
     hot_tags: hot_tags, recommend_shixuns: recommends, my_memos_count: my_memos_count,
     current_user: current_user_info, tidding_count: tidding_count}
  end

  # params
  #       parent_id: 给谁的回复(id)
  #       content: 回复的内容
  def reply params, current_user
    ActiveRecord::Base.transaction do
      memo = Memo.find params[:parent_id]
      reply = Memo.new
      reply.content = params[:content]
      reply.author = current_user
      reply.forum_id = memo.forum_id
      reply.subject = memo.subject
      reply.root_id = memo.root_id || memo.id
      memo.children << reply
      m = Memo.find reply.root_id
      m.increment!(:all_replies_count)
      reply
    end
  end

  # params:
  #        order:   排序
  #        forum_id: 3.技术分享; 5操作指南
  #        sticky:   1 置顶,0 取消置顶
  #        id:      帖子ID
  def set_top_or_down params
    s_order = params[:order] || "updated_at"
    forum_id = params[:forum_id]
    sql = forum_id ? "forum_id = #{forum_id} and root_id is null" : "forum_id in(3,5) and root_id is null"
    Memo.find(params[:id]).update_attribute(:sticky, params[:sticky])
    memos = Memo.field_for_list.includes(:praise_tread, :author).where("#{sql}").order("sticky=1 desc, #{s_order} desc").limit(15)
    memo_list = memo_data memos
    {status: 0, message: "操作成功!", memo_list: memo_list}
  end


  protected
  # 推荐实训 = 2个热门实训 + 2个最新实训
  def recommends
    hot_shixuns = Shixun.field_for_recommend.published.order("myshixuns_count desc").limit(2)
    newest_shixuns = Shixun.field_for_recommend.published.order("created_at desc").limit(2)
    recommend_shixuns = []
    hot_shixuns.each do |hs|
      myshixun_count = hs.myshixuns.count
      recommend_shixuns << {:id => hs.id, :name => hs.name, :identifier => hs.identifier, :myshixuns_count => myshixun_count, :image_url => url_to_avatar(hs)}
    end
    newest_shixuns.each do |ns|
      myshixun_count = ns.myshixuns.count
      recommend_shixuns << {:id => ns.id, :name => ns.name, :identifier => ns.identifier, :myshixuns_count => myshixun_count, :image_url => url_to_avatar(ns)}
    end
    return recommend_shixuns
  end

  def unviewed_tiddings current_user
    new_tidings_count = current_user.tidings.where("created_at > '#{current_user.onclick_time.onclick_time}'").count
    new_pri_message_count = current_user.private_messages.where("created_at > '#{current_user.onclick_time.onclick_time}'").count
    count = new_tidings_count + new_pri_message_count
    return count
  end

  def find_memo params
    if params[:id].blank?
      @memo = Memo.new
    else
      @memo = Memo.find params[:id]
    end
  end

  def format_for_current_user current_user
    {username: current_user.show_name, login: current_user.login,
     user_id: current_user.id, image_url: url_to_avatar(current_user),
     admin: current_user.admin?, is_teacher: current_user.user_extensions.try(:identity) == 0 }
  end

  # 将数据库对象转换成哈希对象
  def object_to_hash objects
    objects.map{|o| o.attributes.dup}
  end

  # 将memos对象添加额外信息
  def memo_data memos
    memo_list = []
    memos.each do |m|
      praise_count = m.praise_tread.where(:praise_or_tread => 1).count
      replies_count = m.all_replies
      tag = m.tag_repertoires.map(&:name)
      user_info = {username: m.author.show_name, login: m.author.login, image_url: url_to_avatar(m.author), praise_count: praise_count, replies_count: replies_count, tag: tag}
      memo_list << m.attributes.dup.merge(user_info)
    end
    memo_list
  end

  def hot_memo_info memos
    memo_info = []
    memos.each do |m|
      praise_count = m.praise_tread.where(:praise_or_tread => 1).count
      replies_count = m.all_replies
      tag = m.tag_repertoires.map(&:name)
      memo_info <<  m.attributes.dup.merge({replies_count: replies_count, praise_count: praise_count, tag: tag})
    end
    memo_info
  end

  # 权限
  def permission memo, current_user
    if current_user.admin?
      1
    elsif memo.author_id == current_user.id
      2
    else
      3
    end
  end

  def tag_list reps
    rep_list = []
    reps.each do |r|
      sub_ids = SubRepertoire.where(:repertoire_id => r.id).pluck(:id)
      tag = object_to_hash TagRepertoire.where(:sub_repertoire_id => sub_ids).field_for_list.order("name asc")
      rep_list << {:rep => r, :tag => tag}
    end
    return rep_list
  end

  def memo_list memos, current_user
    return nil if memos.blank?
    list = [] # 贴子的回复
    memos.each do |memo|
      # 总赞数
      praise_count = memo.praise_tread.liker.count
      # 用户是否点赞
      user_praise = memo.praise_tread.select{|pt| pt.user_id == current_user.id}.length > 0 ? true : false
      # 实训(TPM)的管理员可以看到隐藏的评论
      replies = {:id => memo.id, :content => memo.content, :time => time_from_now(memo.created_at), :user_id => memo.author_id,
                 :image_url => url_to_avatar(memo.author), :username => memo.author.show_name, :reward => memo.reward, :hidden => memo.hidden,
                 :permission => current_user.manager_of_memo?(memo), :praise_count => praise_count, :user_praise => user_praise,
                 :user_login => memo.author.try(:login), :admin => current_user.admin}
      # 现在没有二级回复,所以查询的时候直接从root_id取
      childrens = Memo.where(:parent_id => memo.id).includes(:author).reorder("created_at asc")
      children_list = [] # 子回复
      
      # :reward => child.reward,
      childrens.each do |child|
        children_list << {:id => child.id, :content => child.content, :time => time_from_now(child.created_at),
                          :image_url => url_to_avatar(child.author), :username => child.author.show_name, :hidden => child.hidden,
                          :permission => current_user.manager_of_memo?(memo), :user_login => child.author.try(:login), :user_id => child.author.try(:id)}
      end
      list << replies.merge({children: children_list})
    end
    list
  end

  # 帖子附件信息
  def acttachements_info attachments
    attachments_list = []
    if attachments.present?
      attachments.each do |attach|
        attachments_list << {:id => attach.id,
                             :filename => attach.filename,
                             :url => "/attachments/download/" + "#{attach.id}" + "/" + "#{attach.filename}",
                             :filesize => attach.filesize}
      end
    end
    return attachments_list
  end

  # 判断编辑器存储的内容是否是html类型的(ke),目的为了区分ke和markdown
  def editor_html update_time
    # str.include?("<p>" || "<div>" || "<span>" || "<img>" || "<strong>") && update_time < "2018-06-23"
    update_time < "2018-06-23"
  end

end