require 'rails_helper'

RSpec.describe Projecao::ReceitasController, type: :controller do
	sign_in_admin
	set_ppa_id_na_sessao
	cria_configuracao_default

	let(:atributos_receita) {
		FactoryBot.attributes_for(:receita, projecao_de_receita_id: Ppa::Ppa.first.projecao_de_receita.id)
	}

	let(:atributos_validos) {
		FactoryBot.attributes_for(:receita, projecao_de_receita_id: Ppa::Ppa.first.projecao_de_receita.id)
	}

	let(:atributos_invalidos) {
		{
			codigo: '2'
		}
	}

	let(:projecao_id) {
		Ppa::Ppa.first.projecao_de_receita.id
	}

	let (:projecao_receita_pai) {
		FactoryBot.create( :receita_corrente_pai, projecao_de_receita_id: Ppa::Ppa.first.projecao_de_receita.id )
	}

	describe "GET #index" do
		it "atribui a lista de receitas à @receitas" do
			receita = Projecao::Receita.create! atributos_receita
			get :index
			expect(assigns(:receitas)).to eq([receita])
		end
		context 'quando é quadro de projeção' do
			it 'renderiza a partial de quadro de projeções' do
				get :index, {quadro_de_projecao: true}
				expect(response).to render_template('quadro_de_projecao')
			end
		end
	end

	describe "GET #show" do
		it "atribui a receita requisitado(a) à @receita" do
			receita = Projecao::Receita.create! atributos_receita
			get :show, params: {id: receita.to_param}
			expect(assigns(:receita)).to eq(receita)
		end

		it "atribui exercicio_corrente requisitado(a) à @exercicio_corrente" do
			receita = Projecao::Receita.create! atributos_receita
			get :show, params: {id: receita.to_param}
			expect(assigns(:exercicio_corrente)).to eq(receita.projecao_de_receita.exercicio_corrente)
		end
	end

	describe "GET #detalhar_classificacao" do

		it "busca classificacao do codigo a ser editado" do
			receita = FactoryBot.create(:receita_corrente, :criar_niveis_acima)

			get :detalhar_classificacao, { receita_id: receita.id, projecao_id: receita.projecao_de_receita_id, format: :json }

			expect(JSON.parse(response.body)).to eq({
				"classificacao_detalhada" => [
					{"codigo" => "1.0.0.0.00.00.00", "descricao" => "Receita Corrente", "posicao_de_destaque" => 0},
					{"codigo" => "1.2.0.0.00.00.00", "descricao" => "Receita Corrente", "posicao_de_destaque" => 1},
					{"codigo" => "1.2.3.0.00.00.00", "descricao" => "Receita Corrente", "posicao_de_destaque" => 2},
					{"codigo" => "1.2.3.5.00.00.00", "descricao" => "Receita Corrente", "posicao_de_destaque" => 3},
					{"codigo" => "1.2.3.5.10.00.00", "descricao" => "Receita Corrente", "posicao_de_destaque" => 4},
					{"codigo" => "1.2.3.5.10.99.00", "descricao" => "Receita Corrente", "posicao_de_destaque" => 5}
				], "classificacao_niveis_utilizados" => "1.2.3.5.10", "classificacao_niveis_nao_utilizados" => "00", "tipo_de_orcamento" => "fiscal", "tipo_de_receita" => "primaria"
			})
		end
	end

	describe 'PUT #atualizar_calculos_por_exercicio' do
		context "com parâmetros válidos" do
				let(:atributos_calculos) {
				{
					calculo_por_exercicios_attributes: {
						"3" => {
							"id" => Projecao::CalculoPorExercicio.create!(FactoryBot.attributes_for(:calculo_do_exercicio_para_ppa_criado, :receita)).id,
							"exercicio" => 2016,
							"total" => 57.00
						}
					}
				}
			}

			it "atualiza o(a) receita requisitado(a)" do

				receita = Projecao::Receita.create! atributos_receita
				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_calculos}
				receita.reload
				expect( receita.calculo_por_exercicios.find_by(exercicio: 2016).total ).to eq 57.00
			end

			it "redireciona para o(a) receita" do
				receita = Projecao::Receita.create! atributos_receita

				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_calculos}
				expect(response).to redirect_to(receita)
			end
		end

		context "com parâmetros inválidos" do
			let(:atributos_invalidos_calculo_sem_exercicio) {
				{
					calculo_por_exercicios_attributes: {
						"3" => {
							"id" => nil,
							"total" => 57.00
						}
					}
				}
			}

			it "atribui o(a) receita à @receita" do
				receita = Projecao::Receita.create! atributos_receita
				Projecao::CalculoPorExercicio.create!(FactoryBot.attributes_for(:calculo_do_exercicio_de_2016, receita_id: receita.id, tipo: 'realizado'))

				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_invalidos_calculo_sem_exercicio}
				expect(assigns(:receita)).to eq(receita)
			end

			it "re-renderiza o template 'show' de receita" do
				receita = Projecao::Receita.create! atributos_receita
				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_invalidos_calculo_sem_exercicio}
				expect(response).to render_template("show")
			end
		end
	end

	describe "Atualizar calculo de exercicio sendo usuario comum" do
		let(:atributos_calculos) {
			{
				calculo_por_exercicios_attributes: {
					"3" => {
						"id" => Projecao::CalculoPorExercicio.create!(FactoryBot.attributes_for(:calculo_do_exercicio_para_ppa_criado, :receita, tipo: 'orcado', exercicio: 2013)).id,
						"exercicio" => 2013,
						"total" => 100.00
					},
					"4" => {
						"id" => Projecao::CalculoPorExercicio.create!(FactoryBot.attributes_for(:calculo_do_exercicio_para_ppa_criado, :receita, tipo: 'revisado', exercicio: 2013)).id,
						"exercicio" => 2013,
						"total" => 57.00
					}
				}
			}
		}

		context "ao atualizar projecao, verifica parametros enviados" do
			sign_in_usuario_comum
			 it "permite a atualização da projeção por cálculo de exercício" do
			 	receita = Projecao::Receita.create! atributos_receita
				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_calculos}
				receita.reload
				expect(receita.calculo_por_exercicios.find_by(tipo: 4).total).to eq 57
			end

			it "não permite a atualização dos anos anteriores da orçados e realizados" do
				receita = Projecao::Receita.create! atributos_receita
				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_calculos}
				receita.reload
				expect(receita.calculo_por_exercicios.find_by(tipo: 0).total).to eq 9.99
			end
		end
	end

	describe "Cria uma projeção por calculo de exercicio" do
		let(:atributos_calculos) {
			{
				calculo_por_exercicios_attributes: {
					"3" => {
						"id" => Projecao::CalculoPorExercicio.create!(FactoryBot.attributes_for(:calculo_do_exercicio_para_ppa_criado, :receita)).id,
						"exercicio" => 2016,
						"total" => 57.00
					}
				}
			}
		}

		context "ao atualizar projecao, verifica se usuario é admin" do
			it "permite a atualização da projeção por cálculo de exercício" do
				receita = Projecao::Receita.create! atributos_receita

				put :atualizar_calculos_por_exercicio, {id: receita.to_param, projecao_receita: atributos_calculos}
				expect(response).to redirect_to(receita)
			end
		end
	end

	describe "Projeção de receita, receita sendo de convênio" do
		let(:atributos_calculos) {
			{
				calculo_por_exercicios_attributes: {
					"3" => {
						"id" => Projecao::CalculoPorExercicio.create!(FactoryBot.attributes_for(:calculo_do_exercicio_para_ppa_criado, :receita_de_convenio)).id,
						"exercicio" => 2016,
						"total" => 57.00
					}
				}
			}
		}

		context "verifica se a receita é de convenio" do
			it "retorna erro" do
				receita = FactoryBot.create(:receita_para_ppa_atual, de_convenio: true)
				put :atualizar_calculos_por_exercicio_projecao, {id: receita.to_param, projecao_receita: atributos_calculos}
				expect(controller).to set_flash[:notice].to('Essa receita pertence a um convênio, seus valores projetados só podem ser editados na tela do convênio')
			end
		end
	end
end
