# encoding=utf-8
class ShixunsService
  include ApplicationHelper
  include GamesHelper
  LIMIT = 10

  # reuturn star_info打星情况
  def show_shixun params, current_user
    shixun = Shixun.select([:id, :identifier, :name, :fork_from, :user_id, :myshixuns_count, :trainee, :can_copy, :status, :propaedeutics]).find_by_identifier(params[:identifier])
    star_info = shixun.shixun_preference_info
    image_url = url_to_avatar(current_user)
    username = current_user.try(:show_name)
    is_certification_teacher = current_user.is_certification_teacher
    manager = current_user.manager_of_shixun?(shixun, current_user)
    owner = shixun.owner
    watched = owner.watched_by?(current_user)
    myshixun = Myshixun.select([:id, :user_id, :identifier, :shixun_id, :status]).where(:user_id => current_user, :shixun_id => shixun.id).first
    if shixun.fork_from
      fork_shixun = Shixun.select([:id, :name, :user_id]).find(shixun.fork_from)
      fork_info = {:name => fork_shixun.name, :username => fork_shixun.owner.try(:show_name)}
    end
    current_user = {:image_url => image_url, :username => username, :is_certification_teacher=> is_certification_teacher, :manager => manager,
                    :admin => current_user.admin?, :mail => current_user.try(:mail), :login => current_user.try(:login)}
    creator = {:owner_id => owner.id, :image_url => url_to_avatar(owner), :username => owner.show_name, :watching => owner.watcher_users.count,
               :shixun_count => owner.shixuns.count, :login => owner.login}
    fork_count = Shixun.where(:fork_from => shixun.id).count

    recommends = []
    recommend_shixuns = recommend_shixun(shixun)
    recommend_shixuns.each do |rec|
      recommends << {:name => rec.name, :myshixuns_count => rec.myshixuns_count, :trainee => rec.trainee, :image_url => url_to_avatar(rec), :identifier => rec.identifier}
    end

    return {:current_user => current_user, :shixun => shixun.try(:attributes), :fork_info => fork_info, :creator => creator, :star_info => star_info,
            :myshixuns_count => shixun.myshixuns_count, :shixun_score  => shixun.shixun_score, :shixun_level => shixun.shixun_level,
            :fork_count => fork_count, :recommend_shixuns => recommends, :myshixun => myshixun.try(:attributes), :watched => watched}
  end

  # 实训讨论帖子
  def shixun_discuss params, current_user
    page = params[:page].to_i
    offset = page * LIMIT
    dis_id = params[:container_id] # 如:shixun_id
    dis = Shixun.select([:id, :user_id]).find(dis_id)
    dis_type = params[:container_type] # 如:"Shixun"
    # 总数,分页使用
    if current_user.admin?
      disscuss_count = Discuss.where(dis_id: dis_id, dis_type: dis_type, root_id: nil).count
      discusses = Discuss.where(dis_id: dis_id, dis_type: dis_type, root_id: nil)
                    .includes(:user, :praise_tread).limit(LIMIT).offset(offset)
    else
      disscusses = Discuss.where(
        'dis_id = :dis_id and dis_type = :dis_type and root_id is null and (hidden = :hidden or user_id = :user_id)',
        dis_id: dis_id, dis_type: dis_type, hidden: false, user_id: current_user.id
      )

      disscuss_count = disscusses.count
      discusses = disscusses.includes(:user, :praise_tread).limit(LIMIT).offset(offset)
    end

    base_data discusses, dis, current_user

    { children_list: @children_list, disscuss_count: disscuss_count }
  end

  # 获取某条消息的具体位置(比如在分页中的某一页)
  def anchor params, current_user
    discuss_id = params[:discuss_id].to_i
    dis_id = params[:container_id] # 如:shixun_id
    dis = Shixun.select([:id, :user_id]).find(dis_id)
    dis_type = params[:container_type] # 如:"Shixun"
    # 注意:此处查询的条件必须和列表的条件一致,否则结果定位可能会有问题
    position_discusses = Discuss.find_by_sql("SELECT @rowno:=@rowno+1 as rowno, r.id from discusses r,(select @rowno:=0) m where root_id is null and
                                     dis_id=#{dis_id} and dis_type='#{dis_type}' order by created_at desc")
    disscuss_count = position_discusses.size
    # 标记是否找到评论
    find_status = false
    if disscuss_count > 0
      position = position_discusses.select{|discuss| discuss.id == discuss_id}.first.try(:rowno)
      page = position.to_i / LIMIT
      offset = page * LIMIT
      find_status = true if position
    end
    discusses = Discuss.limit(LIMIT).where(:dis_id => dis_id, :dis_type => dis_type, :root_id => nil).includes(:user, :praise_tread).offset(offset)

    base_data discusses, dis, current_user
    Myshixun.find(params[:myshixun_id]).update_attribute(:onclick_time, Time.now)
    return {:children_list => @children_list, :disscuss_count => disscuss_count, :page => page.to_i, :find_status => find_status}
  end

  # 判断当前用户是否有新的评论消息
  def new_message params, current_user
    onclick_time = Myshixun.find(params[:myshixun_id]).try(:onclick_time)
    dis_id = params[:container_id]
    dis_type = params[:container_type]
    # 获取当前用户发布的帖子,如果帖子有非自己的回复则通知我
    ids = Discuss.where("user_id =? and dis_id =? and dis_type =? and root_id is null", current_user.id, dis_id, dis_type).pluck(:id)
    user_discuss = Discuss.where("user_id !=? and created_at >?",  current_user.id, onclick_time).where(:root_id => ids, :dis_id => dis_id, :dis_type => dis_type).first

    return {:new_message => user_discuss}
  end

  # 公共数据结构
  # 注意:shixun_id如果是非实训类型的,一定要主要其中的权限判断(目前只适用于实训)
  def base_data discusses, dis, current_user
    @children_list = []
    # 目前只取十个,不多N+1问题不大
    # 需要彻底解决则需要改数据路结构,比如Nested算法可以解决
    if discusses.present?
      discusses.each do |d|
        # 总点赞数
        praise_count = d.praise_tread.where(:praise_or_tread => 1).count
        user_praise= d.praise_tread.select{|pt| pt.user_id == current_user.id}.length > 0 ? true : false
        manager = current_user.manager_of_shixun?(dis, current_user)
        game_url =
            if manager
              position = d.position.nil? ? 1 : d.position
              challenge_id = dis.challenges.where(position: position).pluck(:id).first
              game_identifier = Game.where(user_id: current_user,
                                           challenge_id: challenge_id).pluck(:identifier).first
              "/tasks/#{game_identifier}"
            else
              ""
            end
        p_content =
            if d.hidden
              manager ? d.content : "违规评论已被屏蔽!"
            else
              d.content
            end
        # 实训(TPM)的管理员可以看到隐藏的评论
        parents = {:id => d.id, :content => p_content, :time => time_from_now(d.created_at), :position => d.position,
                   :reward => d.reward, :user => d.user, :shixun_id => dis.id, :hidden => d.hidden, game_url: game_url,
                   :manager => manager, :praise_count => praise_count, :user_praise => user_praise, :admin => current_user.admin?}

        # 现在没有二级回复,所以查询的时候直接从root_id取
        children =
          if current_user.admin?
            Discuss.where(root_id: d.id).includes(:user).reorder("created_at asc")
          else
            Discuss.where('root_id = :root_id and (hidden = :hidden or user_id = :user_id)',
                          root_id: d.id, hidden: false, user_id: current_user.id).includes(:user).reorder("created_at asc")
          end

        @children_list << parents.merge(
            {:children => (children.map{|child|
              [:content => (child.hidden ? (manager ? child.content : "违规评论已被屏蔽!") : child.content),
               :time => time_from_now(child.created_at), :position => child.position ,
               :reward => child.reward,:hidden => child.hidden, :user => d.user,
               :can_delete => child.can_deleted?(current_user),
               :id => child.id]}.flatten if children.present?)
            })
      end
    end
  end
end