# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Contabilidade::PagamentoDaRetencao, type: :model do
  describe '#associação belongs to' do
    %i[ retencao conta_origem conta_destino ].each do |model|
      it { is_expected.to belong_to model }
    end
  end

  describe '#associação has one' do 
    %i[ despesa_extra_orcamentaria talao_de_receita pagamento liquidacao ].each do |model|
      it { is_expected.to have_one model }
    end
  end

  describe '#validação de presença' do
    describe 'valida presenças sem condições' do
      %i[ retencao_id ].each do |atributo|
        it { is_expected.to validate_presence_of atributo }
      end
    end

    describe 'valida presença quando for retenção pagar' do 
      before { allow(subject).to receive(:exige_despesa_extra?).and_return(true) }

      it { is_expected.to validate_presence_of :conta_origem_id }
    end

    describe 'valida presença quando for retenção pagar/recolher' do
      before { allow(subject).to receive(:exige_talao_extra?).and_return(true) }
      before { allow(subject).to receive(:exige_despesa_extra?).and_return(true) }

      %i[ conta_origem_id conta_destino_id ].each do |atributo|
        it { is_expected.to validate_presence_of atributo }
      end
    end
  end

  describe '#conta_origem_deve_possuir_saldo' do 
    subject { FactoryBot.build(:pagamento_da_retencao_iss) }

    describe 'quando é valido' do 
      it 'Quando saldo da conta for superior ao valor da retenção não deve retornar o error de saldo insuficiente' do
        subject.validate

        expect(subject.errors[:conta_origem_id]).to_not include 'Não possui saldo'
      end
    end

    describe 'inválido' do 
      it 'Quando saldo da conta for inferior ao valor da retencao deve retornar o error de saldo insuficiente' do 
        # Colocando saldo na conta
        subject.conta_origem.contas_bancarias_por_unidade_orcamentaria.update_all(saldo_atual: 1)
        subject.validate

        expect(subject.errors[:conta_origem_id]).to include 'Não possui saldo'
      end
    end
  end

  describe '#exige_despesa_extra' do
    describe 'quando é uma retenção PAGAR, PAGAR/RECOLHER' do
      describe 'Pagar' do 
        subject { FactoryBot.build(:pagamento_da_retencao_iss) }
        it { is_expected.to be_exige_despesa_extra }
      end

      describe 'Pagar/Recolher' do
        subject { FactoryBot.build(:pagamento_da_retencao_iss, :pagar_recolher) }
        it { is_expected.to be_exige_despesa_extra } 
      end

    end

    describe 'quando não é uma retenção PAGAR, PAGAR/RECOLHER' do
      %i[transferir nao_selecionar].each do |trait|
        subject { FactoryBot.build(:pagamento_da_retencao_iss, trait) }
        it { is_expected.to_not be_exige_despesa_extra }
      end
    end
  end

  describe '#exige_talao_extra' do 
    describe 'quando é Pagar/Recolher' do 
      subject { FactoryBot.build(:pagamento_da_retencao_iss, :pagar_recolher) }
      it { is_expected.to be_exige_talao_extra } 
    end

    describe 'quando é Pagar' do 
      subject { FactoryBot.build(:pagamento_da_retencao_iss) }
      it { is_expected.to_not be_exige_talao_extra }
    end

    describe 'outros tipos' do 
      %i[transferir nao_selecionar].each do |trait|
        subject { FactoryBot.build(:pagamento_da_retencao_iss, trait) }
        it { is_expected.to_not be_exige_talao_extra }
      end
    end
  end

  describe '#gera_despesa_extra' do 
    describe 'apos salvar' do
      subject { FactoryBot.build(:pagamento_da_retencao_iss) }
      it 'deve gerar uma despesa' do
        expect { subject.save }.to change(Contabilidade::DespesaExtraOrcamentaria, :count).by 1
        expect(Contabilidade::DespesaExtraOrcamentaria.last.pagamento_da_retencao_id).to eq subject.id
      end
    end
  end

  describe '#gera_talao_de_receita' do 
    describe 'apos salvar' do 
      subject { FactoryBot.build(:pagamento_da_retencao_iss, :pagar_recolher) }
      it 'deve gerar um talão de receita' do 
        subject.save
        expect(Contabilidade::TalaoDeReceita.last.pagamento_da_retencao_id).to eq subject.id
      end
    end
  end
end
