require 'rails_helper'

RSpec.describe Base::ContaBancaria, type: :model do
	[:agencia, :funcao].each do |campo|
		it{ is_expected.to belong_to campo }
	end

	it{ is_expected.to have_many(:fontes_de_recursos).through(:fontes_de_recursos_da_conta_bancaria).class_name('Base::FonteDeRecursos') }
	it{ is_expected.to have_many(:contas_bancarias_por_unidade_orcamentaria).dependent(:destroy) }
	it{ is_expected.to have_many(:unidades_orcamentarias).through(:contas_bancarias_por_unidade_orcamentaria).class_name('Loa::UnidadeOrcamentaria') }
	it{ is_expected.to have_many(:empenhos).inverse_of(:conta_credor).class_name('Contabilidade::Empenho').with_foreign_key(:conta_credor_id) }
	it{ is_expected.to have_many(:contas_unidade_por_empenho).with_foreign_key(:conta_unidade_id).dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:contas_bancarias_por_pagamento).with_foreign_key(:conta_bancaria_id).dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:transferencias).class_name('Obra::Transferencia') }

	it{ is_expected.to accept_nested_attributes_for :agencia }

	it{ is_expected.to validate_presence_of :numero_da_conta }

	it{ is_expected.to validate_uniqueness_of(:numero_da_conta).scoped_to(:agencia_id) }

	it{ is_expected.to validate_length_of(:numero_da_conta).is_at_most(12) }
	it{ is_expected.to validate_length_of(:operacao).is_at_most(4) }
	it{ is_expected.to validate_length_of(:descricao_do_vinculo).is_at_most(255) }


	context 'quando conta bancária pertence a uma unidade orçamentária' do
		subject {
			FactoryBot.build(:conta_bancaria, :de_unidade)
		}
		it{ is_expected.to validate_presence_of :data_de_abertura }
		it{ is_expected.to validate_presence_of :tipo_de_conta }
		it{ is_expected.to validate_presence_of :saldo_inicial }


		it { is_expected.to allow_value('01/01/2016').for(:data_de_abertura) }
		it { is_expected.to_not allow_value('').for(:data_de_abertura) }
		it { is_expected.to_not allow_value('00/').for(:data_de_abertura) }
	end

	context "quando é uma conta vinculada" do
		subject {
			FactoryBot.build(:conta_bancaria, :vinculada)
		}
		it{ is_expected.to validate_presence_of :funcao_id }
		it{ is_expected.to validate_presence_of :descricao_do_vinculo }
	end

	describe '#substitui_agencia_caso_ja_exista' do
		context 'quando agencia é passada como atributo aninhado' do
			context 'e não existe agencia com esse número' do
				it 'salva agencia' do
					conta = Base::ContaBancaria.create(numero_da_conta: Faker::Number.number(digits: 5).to_s, agencia_attributes: FactoryBot.attributes_for(:agencia_banco_do_brasil, numero_da_agencia: "54321"))

					expect(conta).to be_persisted
					expect(conta.agencia).to be_persisted
				end
			end
			context 'e existe agencia com esse número' do
				it 'utiliza a agencia que já existe' do
					agencia = FactoryBot.create(:agencia_banco_do_brasil, numero_da_agencia: "54321")
					conta = Base::ContaBancaria.create(numero_da_conta: Faker::Number.number(digits: 5).to_s, agencia_attributes: FactoryBot.attributes_for(:agencia_banco_do_brasil, numero_da_agencia: "54321") )
					expect(conta).to be_persisted
					expect(conta.agencia).to eq agencia
				end
			end
		end
	end

	describe "#vinculada?" do
		context "quando tem o tipo de conta bancária 'Conta Vinculada'" do
			it "retorna true" do
				conta_bancaria = FactoryBot.build(:conta_bancaria, :vinculada)
				expect( conta_bancaria ).to be_vinculada
			end
		end

		context "quando tem o tipo de conta bancária 'Conta Não Vinculada'" do
			it "retorna false" do
				conta_bancaria = FactoryBot.build(:conta_bancaria)
				expect( conta_bancaria ).to_not be_vinculada
			end
		end
	end

	# describe "#valida_se_esta_sendo_passado_saldo_inicial" do
	# 	it "retorna mensagem de erro" do
	# 		conta_bancaria = FactoryBot.create(:conta_bancaria, :de_unidade)
	# 		conta_bancaria.update(saldo_inicial: 885)
	# 		expect( conta_bancaria.errors[:base] ).to include 'não é possível atualizar o saldo inicial'
	# 	end
	# end

	it "#unidade_orcamentaria_principal" do
		conta_bancaria_por_unidade_orcamentaria = FactoryBot.create(:conta_bancaria_por_unidade_orcamentaria)
		conta_bancaria_por_unidade_orcamentaria_da_seduc = FactoryBot.create(:conta_bancaria_por_unidade_orcamentaria_da_seduc)
		conta_bancaria_por_unidade_orcamentaria_da_seduc.definir_como_principal

		expect(conta_bancaria_por_unidade_orcamentaria.conta_bancaria.unidade_orcamentaria_principal.id).to eq conta_bancaria_por_unidade_orcamentaria_da_seduc.unidade_orcamentaria.id
	end

	describe 'atualiza_saldo' do
		context 'quando a conta não possui nenhum saldo' do
			it 'e é adicionado 10 reais ao saldo' do
				conta_bancaria = FactoryBot.create(:conta_bancaria)
				conta_bancaria.atualiza_saldo(10)
				expect(conta_bancaria.saldo_atual.to_f).to eq 10.0
			end

			it 'e é subtraído 10 reais do saldo' do
				conta_bancaria = FactoryBot.create(:conta_bancaria)
				conta_bancaria.atualiza_saldo(-10)
				expect(conta_bancaria.saldo_atual.to_f).to eq 0.0
			end
		end

		context 'quando a conta possui saldo inicial de 50' do
			it 'e é adicionado 10 reais ao saldo' do
				conta_bancaria = FactoryBot.create(:conta_bancaria, :com_unidade_orcamentaria, saldo_inicial: 50)
				conta_bancaria.atualiza_saldo(10)
				expect(conta_bancaria.saldo_atual.to_f).to eq 60.0
			end

			it 'e é subtraído 10 reais do saldo' do
				conta_bancaria = FactoryBot.create(:conta_bancaria, :com_unidade_orcamentaria, saldo_inicial: 50)
				conta_bancaria.atualiza_saldo(-10)
				expect(conta_bancaria.saldo_atual.to_f).to eq 40.0
			end
		end
	end

	describe 'atualiza_saldo_inicial' do
		# a função é executada ao salvar a conta_bancaria
		context 'quando é cadastro sem valor inicial' do
			it 'retorna zero' do
				conta_bancaria = FactoryBot.create(:conta_bancaria, :com_unidade_orcamentaria, saldo_inicial: 0)

				expect(conta_bancaria.saldo_atual.to_f).to eq 0
			end
		end

		context 'quando é cadastro com valor inicial' do
			it 'retorna 50' do
				conta_bancaria = FactoryBot.create(:conta_bancaria, :com_unidade_orcamentaria, saldo_inicial: 50)

				expect(conta_bancaria.saldo_atual.to_f).to eq 50
			end
		end

		context 'quando é cadastro com valor inicial e depois é alterado o valor inicial' do
			it 'retorna 30' do
				conta_bancaria = FactoryBot.create(:conta_bancaria, :com_unidade_orcamentaria, saldo_inicial: 50)
				conta_bancaria.saldo_inicial = 30
				conta_bancaria.save
				expect(conta_bancaria.reload.saldo_atual.to_f).to eq 30
			end
		end
	end
end
