class RegistrationsController < ApplicationController
  skip_before_action :authenticate_request!
  skip_before_action :enforce_password_reset!
  skip_before_action :enforce_terms_of_service_agreement!

  def create
    registration = registrations.build(registration_params)
    if registration.save
      render_success :ok
    else
      render_error :unprocessable_entity, errors: registration
    end
  end

  def show
    render_success :ok, json: registration_fields
  end

  def valid
    id = Admission::Registration.decode(params[:token])
    registration = Admission::Registration.find_by(id: id)
    data = {
      id: registration.id,
      school_id: registration.school_id,
      first_name: registration.first_name,
      last_name: registration.last_name,
      email: registration.email,
      country_id: registration.school.country_id
    }
    if registration.expired?
      render_error :unprocessable_entity, json: { school_id: registration.school_id }
    else
      render_success :ok, json: data
    end
  end

  def create_account
    school = registration.school
    family = school.families.build

    first_contact = school.contacts.build(contact_params(params[:contact_one]))
    first_contact_family =
      family.contact_families.build(contact_family_params(params[:contact_one]))
    first_contact_family.contact = first_contact
    first_contact_family.primary = true

    family.name = [first_contact.last_name, first_contact.first_name].join(', ')
    [:address, :address_ext, :city, :state, :zip, :country_id].each do |prop|
      family[prop] = first_contact[prop]
    end

    if params[:contact_two]
      second_contact = school.contacts.build(contact_params(params[:contact_two]))
      second_contact_family =
        family.contact_families.build(contact_family_params(params[:contact_two]))
      second_contact_family.contact = second_contact
      second_contact_family.primary = true
      if first_contact.last_name == second_contact.last_name
        family.name << " & #{second_contact.first_name}"
      end
    end

    user = school.users.build(password_params)
    user.family = family
    user.last_name, user.first_name = family.name.split(', ')
    user.active = true
    user.terms_of_service_date = Time.zone.now

    user.add_custom_error(:terms_of_service, 'must be agreed to') unless params[:terms_of_service]

    unless params[:encrypted_password] == params[:encrypted_password_confirmation]
      user.add_custom_error(:password_confirmation, 'must match password')
    end

    if family.save
      token = user.tokens.build
      token.create_token
      token.save
      response.headers.merge!(token.auth_headers)
      registration.delete
      contacts = [first_contact]
      contacts << second_contact if params[:contact_two]
      contacts.each do |contact|
        Mailgun::TemplateJob.perform_async(
          'Sycamore School <noreply@sycamoreschool.com>',
          contact.email,
          "New Account Created for #{school.name}",
          'admissions-new-account-welcome',
          variables: {
            first_name: contact.first_name,
            last_name: contact.last_name,
            email_address: contact.email,
            username: user.username,
            school_id: school.id,
            school_name: school.name,
            school_phone: school.phone
          },
          tags: [school.id.to_s, 'admissions', 'account-welcome']
        )
      end
      render_success :ok
    else
      errors = {
        user: user.errors,
        first_contact: first_contact.errors,
        first_contact_family: first_contact_family.errors,
        second_contact: params[:contact_two] ? second_contact.errors : {},
        second_contact_family: params[:contact_two] ? second_contact_family.errors : {}
      }
      render_error :unprocessable_entity, errors: errors
    end
  end

  private
    def school
      @school ||= School.find(params[:school_id])
    end

    def registrations
      school.admission_registrations
    end

    def registration
      @registration ||= Admission::Registration.find_by(id: params[:id])
    end

    def registration_fields
      registration.admission_registration_fields
        .by_display_fields
        .pluck(:field)
    end

    def registration_params
      params.permit(:first_name, :last_name, :email)
    end

    def contact_params(param)
      param.permit(
        :first_name,
        :last_name,
        :email,
        :country_id,
        :address,
        :address_ext,
        :city,
        :state,
        :zip,
        :work_phone,
        :home_phone,
        :cell_phone,
        :title_id
      ).merge(admission: true)
    end

    def contact_family_params(param)
      param.permit(:relationship_id).merge(admission: true)
    end

    def password_params
      params.permit(:encrypted_password)
    end
end
