class Admin::Legacy::Student::Students::StateProgramsController < Admin::Legacy::Student::Controller
  include EdFi::IndianaHelper

  def index
    render_success :ok, json: {
      programs: programs.ordered.map { |p| program_props(p) },
      environment: current_school.find_or_build_ed_fi_indiana_environment.environment
    }
  end

  def show
    render_success :ok, json: program_props(program)
  end

  def create
    program = programs.build(program_params)

    if program.save
      render_success :ok, json: program_props(program)
    else
      render_error :unprocessable_entity, errors: program
    end
  end

  def update
    if program.update(program_params)
      render_success :ok, json: program_props(program)
    else
      render_error :unprocessable_entity, errors: program
    end
  end

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

  def available_program_types
    render_success :ok, json: student.available_state_programs(params[:all])
  end

  private
    def permissions
      if [:index, :show, :export, :available_program_types].include?(action_name.to_sym)
        ['read', 'write', 'manage']
      else
        ['write', 'manage']
      end
    end

    def school_year
      @school_year ||= current_school.school_years.find_by(id: params[:school_year_id])
    end

    def programs
      student.ed_fi_state_programs
        .by_year(school_year)
        .by_program(params[:program])
    end

    def program
      @program ||= programs.find_by(id: params[:id])
    end

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

    def program_descriptors
      @program_descriptors ||= descriptor_service(
        current_school_year.id,
        descriptor: :programs
      ).index_by { |d| d['id'] }
    end

    def exit_descriptors
      @exit_descriptors ||= descriptor_service(
        current_school_year.id,
        descriptor: :reasonExitedDescriptors
      ).index_by { |d| d['id'] }
    end

    def associations
      {}.tap do |props|
        props[:school_year] = school_year if params.key?(:school_year_id)
      end
    end

    def endpoints
      [
        'studentprogramassociations',
        'studentcurricularmaterialprogramassociations',
        'studentspecialeducationprogramassociations'
      ]
    end

    def ed_fi_ids
      @ed_fi_ids ||= current_school_year.ed_fi_ids
        .where(endpoint: endpoints)
        .index_by(&:associated_id)
    end

    def program_params
      params.permit(
        :program_descriptor,
        :start_date,
        :end_date,
        :exit_descriptor,
        :program,
        :disability_descriptor,
        :disability_2_descriptor,
        :service_descriptor
      ).merge(associations)
    end

    def program_props(program)
      program_descriptor = program_descriptors[program.program_descriptor]
      exit_descriptor = exit_descriptors[program.exit_descriptor]

      {}.tap do |props|
        props[:id] = program.id
        props[:school_year_id] = program.school_year_id
        props[:program] = program.program
        props[:program_descriptor] = program.program_descriptor
        props[:program_name] = program_descriptor['name'] || program_descriptor['programName']
        props[:program_type] = program.program.titleize
        props[:abbreviation] = program.decorate.abbreviation
        props[:start_date] = program.start_date
        props[:end_date] = program.end_date
        props[:exit_descriptor] = program.exit_descriptor
        props[:exit_reason] = exit_descriptor['description'] if exit_descriptor
        props[:disability_descriptor] = program.disability_descriptor
        props[:disability_2_descriptor] = program.disability_2_descriptor
        props[:service_descriptor] = program.service_descriptor
        props[:current_ed_fi_id] = ed_fi_ids[program.id].present?
        return props unless action_name.to_sym == :show

        props[:school_year_name] = program.school_year.name
      end
    end
end
