class Competitions::CompetitionsController < Competitions::BaseController
  include CompetitionsHelper

  skip_before_action :require_login
  before_action :allow_visit, except: [:index]
  before_action :require_admin, only: [:update, :update_inform]
  before_action :chart_visible, only: [:charts, :chart_rules]

  def index
    # 已上架 或者 即将上架
    competitions = Competition.where(status: true).or(Competition.where.not(published_at: nil))

    competitions =
      case params[:category]
      when 'nearly_published' then competitions.where(status: false)
      when 'progressing' then competitions.where('end_time > NOW()')
      when 'ended'       then competitions.where('end_time < NOW()')
      else competitions
      end

    @count = competitions.count

    competitions = competitions.order(published_at: :desc, online_time: :desc)
    @competitions = paginate(competitions.includes(current_stage_section: :competition_stage))

    ids = @competitions.map(&:id)
    @member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count
    @stage_count_map  = CompetitionStage.where(competition_id: ids).group(:competition_id).count
  end

  def show
    @competition = current_competition
  end

  def update
    @competition.update_attributes!(introduction: params[:introduction])
    Attachment.associate_container(params[:attachment_ids], @competition.id, @competition.class) if params[:attachment_ids]
    normal_status("更新成功")
  end

  def common_header
    @competition = current_competition
    @competition_modules = @competition.unhidden_competition_modules
    @user = current_user
  end

  def informs
    status = params[:status] || 1
    @informs = current_competition.informs.where(status: status)
  end

  def update_inform
    tip_exception("标题和内容不能为空") if params[:name].blank? || params[:description].blank?
    tip_exception("status参数有误") if params[:status].blank? || ![1, 2].include?(params[:status].to_i)
    ActiveRecord::Base.transaction do
      if params[:inform_id]
        inform = current_competition.informs.find_by!(id: params[:inform_id])
        inform.update_attributes!(name: params[:name], description: params[:description])
      else
        inform = current_competition.informs.create!(name: params[:name], description: params[:description], status: params[:status])
      end
      Attachment.associate_container(params[:attachment_ids], inform.id, inform.class) if params[:attachment_ids]
      normal_status("更新成功")
    end
  end

  def md_content
    @md_content = CompetitionModuleMdContent.find_by!(id: params[:md_content_id])
  end

  def update_md_content
    tip_exception("标题和内容不能为空") if params[:name].blank? || params[:content].blank?
    ActiveRecord::Base.transaction do
      if params[:md_content_id]
        md_content = CompetitionModuleMdContent.find_by!(id: params[:md_content_id])
        md_content.update_attributes!(name: params[:name], content: params[:content])
      else
        md_content = CompetitionModuleMdContent.create!(name: params[:name], content: params[:content])
      end
      Attachment.associate_container(params[:attachment_ids], md_content.id, md_content.class) if params[:attachment_ids]
      normal_status("更新成功")
    end
  end

  def chart_rules
    @competition = current_competition
    @stages = @competition.competition_stages
    @rule_contents = @competition.chart_rules
  end

  def update_chart_rules
    tip_exception("内容不能为空") if params[:content].blank?
    @competition = current_competition
    @stage = @competition.competition_stages.find_by!(id: params[:stage_id]) if params[:stage_id]
    chart_rule = @competition.chart_rules.where(competition_stage_id: @stage&.id).first
    if chart_rule
      chart_rule.update_attributes!(content: params[:content])
    else
      @competition.chart_rules.create!(competition_stage_id: @stage&.id, content: params[:content])
    end
    normal_status("更新成功")
  end

  def charts
    @competition = current_competition
    if params[:stage_id]
      @stage = @competition.competition_stages.find_by(id: params[:stage_id])
    end

    @records = @competition.competition_teams.joins(:competition_scores).where(competition_scores: {competition_stage_id: @stage&.id.to_i})
                 .select("competition_teams.*, score, cost_time").order("score desc, cost_time desc")

    current_team_ids = @competition.team_members.where(user_id: current_user.id).pluck(:competition_team_id).uniq
    @user_ranks = @records.select{|com_team| current_team_ids.include?(com_team.id)}
    @records = @records.where("score > 0")
    if params[:format] == "xlsx"
      @records = @records.includes(user: [user_extension: :school], team_members: :user)
      respond_to do |format|
        format.xlsx{
          set_export_cookies
          chart_to_xlsx(@records, @competition)
          exercise_export_name = "#{@competition.name}比赛成绩"
          render xlsx: "#{exercise_export_name.strip}",template: "competitions/competitions/chart_list.xlsx.axlsx",locals:
            {table_columns: @competition_head_cells, chart_lists: @competition_cells_column}
        }
      end
    else
      @records = @records.includes(:user, :team_members).limit(@competition.awards_count)
    end
  end

  private

  def current_competition
    @_current_competition ||= Competition.find_by!(identifier: params[:id])
  end

  def allow_visit
    render_forbidden unless current_competition.published? || admin_or_business?
  end

  def chart_visible
    chart_module = current_competition.competition_modules.find_by(name: "排行榜")
    render_forbidden unless (chart_module.present? && !chart_module.hidden) || admin_or_business?
  end

  # 竞赛成绩导出
  def chart_to_xlsx records, competition
    @competition_head_cells = []
    @competition_cells_column = []

    max_staff = competition.competition_staffs.sum(:maximum)
    if max_staff < 2  # 个人赛
      @competition_head_cells = %w(序号 姓名 学校 学号)
    else # 战队赛
      @competition_head_cells = %w(序号 战队名 指导老师 队员 学校)
    end

    statistic_stages = competition.competition_stages.where("score_rate > 0")
    statistic_stages.each do |stage|
      @competition_head_cells += ["#{stage.name}得分", "#{stage.name}用时"]
    end
    @competition_head_cells += ["总得分", "总用时"] if statistic_stages.size > 1
    competition_scores = competition.competition_scores

    records.each_with_index do |record, index|
      row_cells_column = []
      row_cells_column << index + 1
      record_user = record.user
      if max_staff < 2
        row_cells_column << record_user.real_name
        row_cells_column << record_user.school_name
        row_cells_column << record_user.student_id
      else
        row_cells_column << record.name
        row_cells_column << record.teachers_name
        row_cells_column << record.members_name
        row_cells_column << chart_school_str(record.team_members.select{|member| !member.is_teacher}.pluck(:user_id))
      end

      statistic_stages.each do |stage|
        stage_score = competition_scores.select{|score| score.competition_stage_id == stage.id && score.competition_team_id == record.id}.first
        row_cells_column << stage_score&.score.to_f.round(2)
        row_cells_column << com_spend_time(stage_score&.cost_time.to_i)
      end

      if statistic_stages.size > 1
        row_cells_column << record&.score.to_f.round(2)
        row_cells_column << com_spend_time(record&.cost_time.to_i)
      end

      @competition_cells_column.push(row_cells_column)
    end
  end
end