module Licitacao
class ApostilamentosController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:editar_dotacoes, :atualiza_dotacoes, :excluir_dotacao]
	before_action :set_contrato, only: [:create, :new]
	before_action :disponibiliza_dependencias, only: [:create, :new, :update, :edit]
	before_action :set_apostilamento, only: [:show, :edit, :update, :destroy,:editar_dotacoes, :atualiza_dotacoes, :editar_itens_do_apostilamento, :atualizar_itens_do_apostilamento]
	before_action :set_orcamento_da_despesa, only: [:editar_itens_do_orcamento_da_despesa, :atualizar_itens_do_orcamento_da_despesa]
	# GET /licitacao/apostilamentos/1
	def show
	end

	# GET /licitacao/apostilamentos/new
	def new
		@apostilamento = @contrato.apostilamentos.new
	end

	# GET /licitacao/apostilamentos/1/edit
	def edit
	end

	# POST /licitacao/apostilamentos
	def create
		@apostilamento = @contrato.apostilamentos.new(apostilamento_params)
		@apostilamento.orcamento = contexto_atual

		if @apostilamento.save
			redirect_to @apostilamento, notice: 'Apostilamento foi criado com sucesso.'
		else
			render :new
		end
	end

	# PATCH/PUT /licitacao/apostilamentos/1
	def update
		if @apostilamento.update( apostilamento_params )
			redirect_to @apostilamento, notice: 'Apostilamento foi atualizado com sucesso.'
		else
			render :edit
		end
	end

	# DELETE /licitacao/apostilamentos/1
	def destroy
		mensagem = apaga_e_retorna_mensagem(@apostilamento)
		redirect_to licitacao_contrato_path(@apostilamento.contrato), mensagem
	end

	#GET	/licitacao/apostilamentos/1/dotacoes_aditivo
	def editar_dotacoes
		return if bloqueia_usuario_com_base_em 'update'
		@orcamento_da_despesa_do_apostilamento = @apostilamento.orcamentos_da_despesa_do_apostilamento.build
		carrega_select_box_dotacao
	end

	#PATCH	/licitacao/apostilamentos/1/atualiza_dotacoes
	def atualiza_dotacoes
		@orcamento_da_despesa_do_apostilamento = @apostilamento.orcamentos_da_despesa_do_apostilamento.new(dotacao_params)
		if @orcamento_da_despesa_do_apostilamento.save
			redirect_to licitacao_apostilamento_path(@apostilamento, tab: "dotacoes_do_apostilamento"), success: 'Dotação foi adicionada com sucesso.'
		else
			carrega_select_box_dotacao
			render :editar_dotacoes
		end
	end

	#DELETE	/licitacao/aditivos/excluir_dotacao/1
	def excluir_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		orcamento_da_despesa_do_apostilamento = Licitacao::OrcamentoDaDespesaDoApostilamento.find(params[:orcamento_da_despesa_do_apostilamento_id])

		mensagem = apaga_e_retorna_mensagem(orcamento_da_despesa_do_apostilamento)
		redirect_to licitacao_apostilamento_path(orcamento_da_despesa_do_apostilamento.apostilamento, tab: 'dotacoes_do_apostilamento'), mensagem
	end

	def editar_itens_do_apostilamento
		@apostilamento.contrato.itens_do_contrato.each do |item_do_contrato|
			if @apostilamento.itens_do_apostilamento.where(item_do_contrato_id: item_do_contrato.id).empty?
				@apostilamento.itens_do_apostilamento.build(item_do_contrato_id: item_do_contrato.id)
			end
		end
	end

	def atualizar_itens_do_apostilamento
		if @apostilamento.update(itens_do_apostilamento_params)
			redirect_to @apostilamento, success: "Itens Cadastrados com Sucesso"
		else
			@apostilamento.contrato.itens_do_contrato.each do |item_do_contrato|
				unless @apostilamento.itens_do_apostilamento.any?{ |item_do_apostilamento| item_do_apostilamento if item_do_apostilamento.item_do_contrato_id.eql?(item_do_contrato.id) }
					@apostilamento.itens_do_apostilamento.build(item_do_contrato_id: item_do_contrato.id)
				end
			end
			render :editar_itens_do_apostilamento
		end
	end

	def excluir_itens_do_apostilamento
		item_do_apostilamento = Licitacao::ItemDoApostilamento.find(params[:id])
		mensagem = apaga_e_retorna_mensagem(item_do_apostilamento)
		redirect_to item_do_apostilamento.apostilamento, mensagem
	end

	def editar_itens_do_orcamento_da_despesa
		@itens_do_contrato = @orcamento_da_despesa_do_apostilamento.contrato.itens_do_contrato

		if params[:todos].present?
			@orcamento_da_despesa_do_apostilamento.build_todos_itens_do_contrato
		else
			@orcamento_da_despesa_do_apostilamento.build_item
		end
	end

	def atualizar_itens_do_orcamento_da_despesa
		if @orcamento_da_despesa_do_apostilamento.update(itens_do_orcamento_da_despesa_params)
			redirect_to @orcamento_da_despesa_do_apostilamento.apostilamento, notice: 'Cadastro dos itens concluido com sucesso'
		else
			@itens_do_contrato = @orcamento_da_despesa_do_apostilamento.contrato.itens_do_contrato

			render :editar_itens_do_orcamento_da_despesa
		end
	end

	private

	def set_apostilamento
		@apostilamento = Licitacao::Apostilamento.find( params[:id] )
	end

	def set_orcamento_da_despesa
		@orcamento_da_despesa_do_apostilamento = Licitacao::OrcamentoDaDespesaDoApostilamento.find_by(id: params[:id])
	end

	def set_contrato
		@contrato = Licitacao::Contrato.find( params[:contrato_id] )
	end

	def disponibiliza_dependencias
		@legislacoes = Base::Legislacao.artigo
	end

	def carrega_select_box_dotacao
		@unidades_orcamentarias = @apostilamento.contrato.projeto.unidades_orcamentarias
		@elementos_de_despesa_por_subacao = []
		@orcamentos_da_despesa = []
		@sub_elementos_de_despesa = []
		@subacoes = []

		unidade_do_contrato = @apostilamento.contrato.unidade_orcamentaria_do_exercicio
		if unidade_do_contrato.id.present?
			projeto = @apostilamento.contrato.projeto if @apostilamento.contrato.projeto.present?
			unidade_orcamentaria = contexto_atual.unidades_orcamentarias.joins(:orgao).find_by(loa_orgaos:{codigo: @apostilamento.contrato.unidade_orcamentaria_do_exercicio.orgao.codigo}, codigo: @apostilamento.contrato.unidade_orcamentaria_do_exercicio.codigo)
			if unidade_orcamentaria.nil?
				unidade_orcamentaria = contexto_atual.unidades_orcamentarias.joins(:unidades_orcamentaria_vinculada)
					.find_by('loa_unidades_orcamentaria_vinculada.unidade_orcamentaria_vinculada_id = ?', @apostilamento.contrato.unidade_orcamentaria.id)
			end

			if @orcamento_da_despesa_do_apostilamento.present? && @orcamento_da_despesa_do_apostilamento.persisted?

				@orcamento_da_despesa_do_apostilamento.subacao_id =  @orcamento_da_despesa_do_apostilamento.subacao.id
				@orcamento_da_despesa_do_apostilamento.elemento_de_despesa_por_subacao_id =  @orcamento_da_despesa_do_apostilamento.elemento_de_despesa_por_subacao.id
				clausulas = { unidade_orcamentaria_id: unidade_orcamentaria.id }
				@subacoes = Loa::Subacao.joins(:elementos_de_despesa_por_subacao).where(clausulas).distinct
				@elementos_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.includes(:elemento_de_despesa).where(subacao_id:  @orcamento_da_despesa_do_apostilamento.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao).try(:subacao_id) ).order('base_elementos_de_despesa.codigo').all
				@orcamentos_da_despesa = Loa::OrcamentoDaDespesa.where( elemento_de_despesa_por_subacao_id:  @orcamento_da_despesa_do_apostilamento.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao_id) ).order(:fonte_de_recursos_id)
				elemento_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.where( id: @orcamento_da_despesa_do_apostilamento.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao_id) ).first
				@sub_elementos_de_despesa = Contabilidade::SubElementoDeDespesa.ativos.where( elemento_de_despesa_id: elemento_de_despesa_por_subacao.try(:elemento_de_despesa_id) )
			
			elsif params[:licitacao_orcamento_da_despesa_do_apostilamento].present?

				@orcamento_da_despesa_do_apostilamento.subacao_id =  params[:licitacao_orcamento_da_despesa_do_apostilamento][:subacao_id]
				@orcamento_da_despesa_do_apostilamento.elemento_de_despesa_por_subacao_id =  params[:licitacao_orcamento_da_despesa_do_apostilamento][:elemento_de_despesa_por_subacao_id]
				clausulas = { unidade_orcamentaria_id: unidade_orcamentaria.id }
				@subacoes = Loa::Subacao.joins(:elementos_de_despesa_por_subacao).where(clausulas).distinct
				@elementos_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.includes(:elemento_de_despesa).where(subacao_id:  params[:licitacao_orcamento_da_despesa_do_apostilamento][:subacao_id] ).order('base_elementos_de_despesa.codigo').all
				@orcamentos_da_despesa = Loa::OrcamentoDaDespesa.where( elemento_de_despesa_por_subacao_id:  params[:licitacao_orcamento_da_despesa_do_apostilamento][:elemento_de_despesa_por_subacao_id]).order(:fonte_de_recursos_id)
				elemento_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.where( id: params[:licitacao_orcamento_da_despesa_do_apostilamento][:elemento_de_despesa_por_subacao_id]).first
				@sub_elementos_de_despesa = Contabilidade::SubElementoDeDespesa.ativos.where( elemento_de_despesa_id: elemento_de_despesa_por_subacao.try(:elemento_de_despesa_id) )
			end

			if projeto.present? && projeto.orcamentos_da_despesa_por_projetos.any? && Configuracao.last.comprometimento_de_dotacoes?
				orcamentos_do_projeto = projeto.orcamentos_da_despesa_por_projetos.joins(orcamento_da_despesa: { elemento_de_despesa_por_subacao: :subacao }).where('loa_subacoes.unidade_orcamentaria_id = ?', unidade_orcamentaria.id)
				if orcamentos_do_projeto.any?
					@subacoes = orcamentos_do_projeto.map{|orcamento| orcamento.orcamento_da_despesa.elemento_de_despesa_por_subacao.subacao}
				else
					clausulas = { unidade_orcamentaria_id: unidade_orcamentaria.id }
					@subacoes = Loa::Subacao.joins(:elementos_de_despesa_por_subacao).where(clausulas).distinct
				end
			elsif !@orcamento_da_despesa_do_apostilamento.persisted?
				clausulas = { unidade_orcamentaria_id: unidade_orcamentaria.id }
				@subacoes = Loa::Subacao.joins(:elementos_de_despesa_por_subacao).where(clausulas).distinct
			end
		end
	end

	# Permite apenas os parâmetros específicos
	def apostilamento_params
		params.require(:licitacao_apostilamento).permit(:contrato_id, :orcamento_id, :data_apostilamento, :modalidade, :legislacao_id, :objeto)
	end

	def dotacao_params
		params.require(:licitacao_orcamento_da_despesa_do_apostilamento).permit(:subacao_id, :elemento_de_despesa_por_subacao_id, :sub_elemento_de_despesa_id, :orcamento_da_despesa_id, :valor )
	end

	def itens_do_orcamento_da_despesa_params
		params.require(:licitacao_orcamento_da_despesa_do_apostilamento).permit(itens_do_orcamento_da_despesa_do_apostilamento_attributes: [
			:id,
			:item_do_contrato_id,
			:orcamento_da_despesa_do_apostilamento_id,
			:quantidade,
			:saldo,
			:preco_unitario,
			:_destroy
		])
	end

	def itens_do_apostilamento_params
		params.require(:licitacao_apostilamento).permit(itens_do_apostilamento_attributes: [ 
			:id,
			:item_do_contrato_id,
			:preco_unitario_original,
			:preco_unitario,
			:quantidade,
			:valor_atualizado,
			:quantidade_no_contrato,
			:saldo_atualizado,
			:_destroy
		])
	end
end
end
