class Admin::Covid::ScreeningsController < Admin::Covid::Controller
  include DateRangeHelper

  def index
    items = screenings
      .includes(:student, answers: :options)
      .by_grades(params[:grades])
      .by_date_range(datetime_range(params[:date_range]))
      .by_classroom(params[:classroom_ids])
      .map { |s| screening_props(s) }
    render_success :ok, json: { headers: form_headers, items: items }
  end

  def new
    render_success :ok, json: Covid::ScreeningForm.call(current_school)
  end

  def create
    form = student.covid_screenings.build(date: params[:date])
    form_questions.each do |question|
      answer = params[:answers].find { |a| a[:field_id] == question.id }[:value]
      if question.has_options?
        form_answer = form.answers.build(question: question)
        form_answer.options = options_by_question[question.id]
      else
        form.answers.build(question: question, value: answer)
      end
    end

    if form.save
      render_success :ok
    else
      render_error :unprocessable_entity, errors: form
    end
  end

  def destroy
    if screening.destroy
      render_success :ok
    else
      render_error :unprocessable_entity, errors: screening
    end
  end

  def student_count
    count = screenings.by_date(params[:date]).count
    total = students.current_status(current_school, :current).count

    render_success :ok, json: { count: count, total: total }
  end

  def student_search
    data = students
      .current_status(current_school, :current)
      .by_grade(params[:grades])
      .by_covid_screening_submissions(params[:submitted]&.to_bool, params[:date])
      .map { |s| student_props(s) }

    render_success :ok, json: data
  end

  def export
    Reporting::Covid::ScreeningJob.perform_async(
      current_school.id,
      current_user.id,
      date_range: params[:date_range],
      grades: params[:grades],
      classroom_ids: params[:classroom_ids]
    )
  end

  def google_export
    Google::Covid::ScreeningJob.perform_async(
      current_school.id,
      current_user.id,
      date_range: params[:date_range],
      grades: params[:grades],
      classroom_ids: params[:classroom_ids]
    )
  end

  private
    def screenings
      current_school.covid_screenings
    end

    def screening
      @screening ||= screenings.find_by(id: params[:id])
    end

    def students
      current_school.students
    end

    def student
      @student ||= students.find_by(id: params[:student_id])
    end

    def submitted_screenings_by_student_id
      @submitted_screenings_by_student_id ||= screenings.by_date(params[:date]).pluck(:student_id)
    end

    def form_headers
      attributes = [
        { text: 'Date/Time', value: 'datetime' },
        { text: 'Last Name', value: 'last_name' },
        { text: 'First Name', value: 'first_name' },
        { text: 'Grade', value: 'grade' },
        { text: 'DOB', value: 'date_of_birth' },
        { text: 'Age', value: 'age' }
      ]
      attributes + questions.map { |i| { text: i.title, value: i.id.to_s } }
    end

    def form_questions
      questions.where(id: params[:answers].pluck(:field_id))
    end

    def questions
      @questions ||= current_school.covid_form_questions
        .by_employee_field(false)
        .order('covid_form_sections.sequence ASC', :sequence)
    end

    def options_by_question
      @options_by_question ||= current_school.covid_form_options
        .where(id: params[:answers].pluck(:value).flatten)
        .group_by(&:field_id)
    end

    def screening_props(screening)
      {}.tap do |prop|
        prop[:id] = screening.id
        prop[:datetime] = screening.created_at
        prop[:first_name] = screening.student.first_name
        prop[:last_name] = screening.student.last_name
        prop[:grade] = grade_label(screening.student)
        prop[:date_of_birth] = screening.student.date_of_birth
        prop[:age] = screening.student.decorate.age
        questions.map do |question|
          answers = screening.answers.find { |a| a.question_id == question.id }
          prop[question.id] = if question.has_options?
            answers&.options&.map(&:value)&.join(' ')
          else
            answers&.value
          end
        end
      end
    end

    def student_props(student)
      {
        date: params[:date],
        full_name: student.full_name(:reverse),
        grade: grade_label(student),
        grade_id: student.grade,
        submitted: submitted_screenings_by_student_id.include?(student.id)
      }
    end

    def grade_label(student)
      grade_levels[student.grade]
    end

    def permissions
      ['write', 'manage']
    end
end
