class Admin::Accounting::PaymentsController < Admin::Accounting::Controller
  def index
    render_success :ok, json: current_school.decorate.payment_methods
  end

  def create
    @payment = payments.build(payment_params)
    transaction_service.build_details(subcategories, params[:distribution])
    @payment.process_payment(params, action: 'CHARGE')
    validate_payment_amount

    if @payment.save
      allocate_funds
      render_success :ok, json: { id: @payment.id }
    else
      render_error :unprocessable_entity, errors: @payment
    end
  end

  def receipt
    if params[:email].to_bool
      payment.family.primary_contact_emails.each { |e| send_payment_receipt_email(e) }
      render_success :ok, message: 'Email has been sent.'
    else
      Reporting::Accounting::ReceiptJob.perform_async(
        current_school.id,
        current_user.id,
        id: payment.id
      )
    end
  end

  private
    def payments
      (family || current_school).accounting_decreases
    end

    def payment
      @payment ||= payments.find_by(id: params[:id]).decorate
    end

    def subcategories
      @subcategories ||= current_school.accounting_subcategories
    end

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

    def validate_payment_amount
      return if params[:total].to_d == @payment.amount.to_d

      @payment.add_custom_error(:base, 'Total must equal payment amount')
    end

    def allocate_funds
      subcategories.each do |subcategory|
        AllocationJob.perform_now(family, subcategory, audit_user: current_user)
      end
    end

    def transaction_service
      Accounting::TransactionsService.new(family, @payment)
    end

    def payment_params
      params.permit(:amount, :memo, :posted_on).merge(action: :payment)
    end

    def template_variables
      @template_variables ||= {
        family_name: payment.family.name,
        payment_date: payment.posted_date,
        payment_amount: payment.currency,
        school_name: current_school.name
      }
    end

    def send_payment_receipt_email(contact_email)
      Mailgun::TemplateService.call(
        'Sycamore School <noreply@sycamoreschool.com>',
        contact_email,
        "Receipt for Payment to #{current_school.name}",
        'account-receipt',
        template_variables,
        payment_receipt_pdf
      )
    end
end
