class Admin::Admissions::FamiliesController < Admin::Admissions::Controller
  def index
    objects = families
      .joins(admission_applicants: :application)
      .where(admission_applications: { school_year: school_year })
      .distinct
      .order(:name)
    render_success :ok, json: objects.map { |o| family_props(o) }
  end

  def show
    render_success :ok, json: family_props(family)
  end

  def update
    if family.update(family_params)
      render_success :ok, object: :general_fields, json: family_props(family)
    else
      render_error :unprocessable_entity, errors: family
    end
  end

  def export
    Reporting::Admissions::FamilyJob.perform_async(
      current_school.id,
      current_user.id,
      school_year_id: params[:school_year_id]
    )
  end

  def payment_export
    Reporting::Admissions::FamilyPaymentJob.perform_async(
      current_school.id,
      current_user.id,
      school_year_id: params[:school_year_id],
      payment_status: params[:payment_status],
      tag_ids: params[:tag_ids]
    )
  end

  def invite
    reset = family.user.nil? || !family.user.active
    family.activate_user_login
    if family.save
      url = token_url(family.user, reset)
      family.primary_contacts.each { |c| send_admissions_invite_email(c, family.user, url) }
      render_success :ok, message: 'Email has been sent.'
    else
      render_error :unprocessable_entity, errors: family
    end
  end

  def batch_invite
    families.where(id: params[:ids]).includes(:primary_contacts, :user).each do |family|
      reset = family.user.nil? || !family.user.active
      family.activate_user_login
      if family.save
        url = token_url(family.user, reset)
        family.primary_contacts.each { |c| send_admissions_invite_email(c, family.user, url) }
      end
    end
    render_success :ok, message: 'Emails have been sent.'
  end

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

    def families
      current_school.families
    end

    def family
      @family ||= families.find_by(id: params[:id])
    end

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

    def admission_families
      @admission_families ||= school_year.admission_families.includes(:tags).order('tags.name')
    end

    def family_payment
      @family_payment ||= admission_families.index_by(&:family_id)
    end

    def family_tags
      @family_tags ||= admission_families
        .map { |f| [f.family_id, f.tags] }
        .to_h
    end

    def send_admissions_invite_email(contact, user, url)
      return if contact.email.blank?

      Mailgun::TemplateService.call(
        'Sycamore School <noreply@sycamoreschool.com>',
        contact.email,
        "#{current_school.name} invite to Admissions Application",
        'admissions-family-invite',
        variables: {
          first_name: contact.first_name,
          last_name: contact.last_name,
          school_name: current_school.name,
          school_id: current_school.id,
          username: user.username,
          school_phone: current_school.phone,
          token_url: url
        },
        tags: [current_school.id.to_s, 'admissions', 'family-invite']
      )
    end

    def token_url(user, reset)
      sycamore_url = Rails.application.secrets.vue_base_url
      return "#{sycamore_url}/login?school_id=#{current_school.id}" unless reset

      time = DateTime.now
      user.update(pw_recovery_time: time)
      payload = { uid: user.id, pw_recovery_time: time }.to_json
      token = JWT.encode(payload, Rails.application.secrets.secret_key_base)

      "#{sycamore_url}/password_recovery?token=#{token}"
    end

    def family_params
      params.permit(Admission::FamilyRevision::FAMILY_ATTRIBUTES)
    end

    def family_props(family)
      {}.tap do |props|
        props[:id] = family.id
        props[:name] = family.name
        props[:code] = family.code
        props[:address] = family.address
        props[:address_ext] = family.address_ext
        props[:city] = family.city
        props[:county] = family.county
        props[:state] = family.state
        props[:zip] = family.zip
        props[:country_id] = family.country_id
        props[:address_2] = family.address_2
        props[:address_ext_2] = family.address_ext_2
        props[:city_2] = family.city_2
        props[:state_2] = family.state_2
        props[:zip_2] = family.zip_2
        props[:country_2_id] = family.country_2_id
        props[:directory] = family.directory?
        props[:directory_address] = family.directory_address?
        props[:directory_phone] = family.directory_phone?
        props[:directory_email] = family.directory_email?
        props[:directory_cell] = family.directory_cell?
        props[:payment_status] = family_payment[family.id]&.payment_status || :not_paid
        return props if school_year.nil?

        props[:tags] = tag_props(family.id)
      end
    end

    def tag_props(family_id)
      return [] if (tags = family_tags[family_id]).nil?

      tags.map { |t| { id: t.id, name: t.name, color: t.color } }
    end
end
