# frozen_string_literal: true

#  Copyright (c) 2012-2021, CVP Schweiz. This file is part of
#  hitobito_cvp and licensed under the Affero General Public License version 3
#  or later. See the COPYING file at the top-level directory or at
#  https://github.com/hitobito/hitobito.

require "spec_helper"

describe MessagesController do
  let(:list) { mailing_lists(:leaders) }
  let(:nesting) { {group_id: list.group_id, mailing_list_id: list.id} }
  let(:top_leader) { people(:top_leader) }

  before { sign_in(top_leader) }

  context "GET#index" do
    it "is present for current year" do
      get :index, params: nesting
      expect(assigns(:messages)).to be_present
    end

    it "is empty for previous year" do
      travel_to 1.year.ago do
        get :index, params: nesting
      end
      expect(assigns(:messages)).to be_empty
    end
  end

  context "GET#new" do
    before do
      Fabricate(:subscription, mailing_list: list, subscriber: top_leader)
    end

    it "builds new Letter" do
      get :new, params: nesting.merge(message: {type: "Message::Letter"})
      expect(assigns(:message)).to be_kind_of(Message::Letter)
    end

    it "builds new LetterWithInvoice" do
      get :new, params: nesting.merge(message: {type: "Message::LetterWithInvoice"})
      expect(assigns(:message)).to be_kind_of(Message::LetterWithInvoice)
    end
  end

  context "POST#create" do
    it "saves Letter" do
      post :create, params: nesting.merge(
        message: {subject: "Mitgliedsbeitrag", body: "body", type: "Message::Letter"}
      )
      expect(assigns(:message)).to be_persisted
      expect(response).to redirect_to group_mailing_list_message_path(id: assigns(:message).id)
    end

    it "saves LetterWithInvoice with invoice_items attributes" do
      Subscription.create!(mailing_list: list, subscriber: top_leader)

      post :create, params: nesting.merge(
        message: {
          subject: "Mitgliedsbeitrag",
          type: "Message::LetterWithInvoice",
          body: "Bitte einzahlen",
          invoice_attributes: {
            invoice_items_attributes: {
              "1" => {"name" => "Mitgliedsbeitrag", "unit_cost" => 42, "_destroy" => "false"}
            }
          }
        }
      )
      expect(assigns(:message)).to be_persisted
      expect(assigns(:message).invoice.invoice_items.first.name).to eq "Mitgliedsbeitrag"
      expect(response).to redirect_to group_mailing_list_message_path(id: assigns(:message).id)
    end

    it "keeps invoice_items attributes if missing body for LetterWithInvoice" do
      post :create, params: nesting.merge(
        message: {
          subject: "Mitgliedsbeitrag",
          type: "Message::LetterWithInvoice",
          invoice_attributes: {
            invoice_items_attributes: {
              "1" => {"name" => "Mitgliedsbeitrag", "unit_cost" => 42, "_destroy" => "false"}
            }
          }
        }
      )
      expect(assigns(:message)).to be_invalid
      expect(assigns(:message).invoice.invoice_items.first.name).to eq "Mitgliedsbeitrag"
      expect(response).to render_template :new
    end

    it "validates presence of subject" do
      Subscription.create!(mailing_list: list, subscriber: top_leader)

      post :create, params: nesting.merge(
        message: {
          subject: "",
          type: "Message::LetterWithInvoice",
          body: "Bitte einzahlen",
          invoice_attributes: {
            invoice_items_attributes: {
              "1" => {"name" => "Mitgliedsbeitrag", "unit_cost" => 42, "_destroy" => "false"}
            }
          }
        }
      )
      expect(assigns(:message)).to be_invalid
      expect(response).to render_template :new
    end

    it "validates invoice_item attributes" do
      post :create, params: nesting.merge(
        message: {
          subject: "Mitgliedsbeitrag",
          body: "Very good price!",
          type: "Message::LetterWithInvoice",
          invoice_attributes: {
            invoice_items_attributes: {
              "1" => {"name" => "", "unit_cost" => "", "_destroy" => "false"}
            }
          }
        }
      )
      expect(assigns(:message)).to be_invalid
      expect(response).to render_template :new
    end

    it "creates Text Message" do
      post :create, params: nesting.merge(
        message: {text: "Long live SMS!", type: "Message::TextMessage"}
      )
      expect(assigns(:message)).to be_persisted
      expect(response).to redirect_to group_mailing_list_message_path(id: assigns(:message).id)
    end
  end

  context "preview" do
    let(:bottom_member) { people(:bottom_member) }

    context "letter" do
      let(:message) { messages(:letter) }

      it "redirects to message when recipients are empty" do
        get :show, format: :pdf,
          # rubocop:todo Layout/LineLength
          params: {preview: true, id: message.id, mailing_list_id: message.mailing_list.id, group_id: message.mailing_list.group.id}
        # rubocop:enable Layout/LineLength
        expect(response).to redirect_to message.path_args
        expect(flash[:alert]).to eq "Empfängerliste ist leer, kann kein PDF erstellen."
      end

      it "renders file" do
        expect(Export::Pdf::Messages::Letter).to receive(:new).with(anything,
          {background: Settings.messages.pdf.preview}).and_call_original
        Subscription.create!(mailing_list: message.mailing_list, subscriber: bottom_member)
        get :show, format: :pdf,
          # rubocop:todo Layout/LineLength
          params: {preview: true, id: message.id, mailing_list_id: message.mailing_list.id, group_id: message.mailing_list.group.id}
        # rubocop:enable Layout/LineLength
        expect(response.header["Content-Disposition"]).to match(/preview-information.pdf/)
        expect(response.media_type).to eq("application/pdf")
      end
    end

    context "letter_with_invoice" do
      let(:message) { messages(:with_invoice) }

      it "renders file" do
        invoice_configs(:top_layer).update(payment_slip: :qr)
        Subscription.create!(mailing_list: message.mailing_list, subscriber: bottom_member)
        get :show, format: :pdf,
          # rubocop:todo Layout/LineLength
          params: {preview: true, id: message.id, mailing_list_id: message.mailing_list.id, group_id: message.mailing_list.group.id}
        # rubocop:enable Layout/LineLength
        expect(response.header["Content-Disposition"]).to match(/preview-rechnung-mitgliedsbeitrag.pdf/)
        expect(response.media_type).to eq("application/pdf")
      end
    end
  end
end
