module GestaoDeEstoque
	class ConsumosController < ApplicationController
		include ControllerConcern
		before_action :authenticate_usuario!
		before_action :autoriza_usuario!
		before_action :set_consumo, only: [:show, :edit, :update, :destroy, :adicionar_dependencias_escolas, :editar_itens_do_consumo, :atualizar_itens_do_consumo, :retornar_para_aberto, :confirmar_consumo, :enviar_ao_almoxarifado, :recusar_requisicao, :receber_no_almoxarifado]
		before_action :disponibiliza_dependencias, only: [:index, :new, :create, :edit]
		before_action :set_tipo, only: [:index, :new, :edit]
		before_action :adicionar_dependencias_escolas, only: [:new, :create, :edit]

		# GET /gestao_de_estoque/consumos
		def index
			@almoxarifados = GestaoDeEstoque::Almoxarifado.where('gestao_de_estoque_almoxarifados.orcamento_id = ? AND tipo_de_almoxarifado <> 9', contexto_atual.id).order('id ASC')
			if @tipo == :outros
				@q = Consumo.where('unidade_orcamentaria_id in (?) and classificacao IS NOT NULL', @unidades_orcamentarias.ids).order("id DESC").search(params[:q])
			else
				@q = Consumo.where('unidade_orcamentaria_id in (?) and classificacao IS NULL', @unidades_orcamentarias.ids).order("id DESC").search(params[:q])
			end
			
			@consumos = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		end

		# GET /gestao_de_estoque/consumos/1
		def show
		end

		# GET /gestao_de_estoque/consumos/new
		def new
			@consumo = Consumo.new
			@consumo.programas_por_consumo.build if @consumo.programas_por_consumo.empty?
			if params[:interno] == "true"
				@interno = params[:interno]
			end
		end

		# GET /gestao_de_estoque/consumos/1/edit
		def edit
		end

		# POST /gestao_de_estoque/consumos
		def create
			@consumo = Consumo.new(consumo_params)
			@consumo.orcamento = contexto_atual
			@consumo.transaction do
				if @consumo.save
					if @consumo.programas_por_consumo.any?
						redirect_to @consumo
					else
						redirect_to gestao_de_estoque_editar_itens_do_consumo_path(@consumo)
					end
				else
					# disponibiliza_dependencias	
					# if @consumo.outros_procedimentos
					# 	render :action => "new", :tipo => "outros"
					# else
					# 	render :new
					# end 
					disponibiliza_dependencias
					adicionar_dependencias_escolas
					render :new
				end
			rescue Exception => e
				raise e
				raise ActiveRecord::Rollback
			end
		end

		# PATCH/PUT /gestao_de_estoque/consumos/1
		def update
			if @consumo.update( consumo_params )
				redirect_to @consumo, notice: 'Consumo foi atualizado(a) com sucesso.'
			else
				render :edit
			end
		end

		# DELETE /gestao_de_estoque/consumos/1
		def destroy
			mensagem = apaga_e_retorna_mensagem(@consumo)
			if @consumo.classificacao
				redirect_to gestao_de_estoque_consumos_url(tipo: 'outros'), mensagem
			else
				redirect_to gestao_de_estoque_consumos_url, mensagem
			end
		end

		def editar_itens_do_consumo
			@consumo.itens_do_consumo.build unless @consumo.itens_do_consumo.present?
			
			disponibiliza_dependencias_itens_do_consumo

			@unidades_orcamentarias_do_almoxarifado = Loa::UnidadeOrcamentaria.joins(:unidades_orcamentarias_do_almoxarifado)
				.where('gestao_de_estoque_unidades_orcamentarias_do_almoxarifado.almoxarifado_id = ?', @consumo.almoxarifado).order('orgao_id')

		end

		def atualizar_itens_do_consumo
			@consumo.transaction do
				if @consumo.update(consumo_params)
					mensagem = 'Itens atualizados com sucesso.'
					redirect_to gestao_de_estoque_consumo_path(@consumo), notice: mensagem
				else
					disponibiliza_dependencias_itens_do_consumo
					flash.now[:alert] = @consumo.errors.full_messages.to_sentence
					render :editar_itens_do_consumo
				end
			rescue Exception => e
				disponibiliza_dependencias
				disponibiliza_dependencias_itens_do_consumo
				@itens = GestaoDeEstoque::Estoque.where(almoxarifado_id: @consumo.almoxarifado_id,
					unidade_orcamentaria_id: @consumo.unidade_orcamentaria_id)
				render :editar_itens_do_consumo
				raise ActiveRecord::Rollback
			end
		end

		def retornar_para_aberto
			if @consumo.retornar_para_aberto!
				redirect_to gestao_de_estoque_consumo_path(@consumo), notice: "Consumo reaberto."
			else
				render :show
			end
		end

		def confirmar_consumo
			if @consumo.confirmar_consumo!
				redirect_to gestao_de_estoque_consumo_path(@consumo), notice: "Consumo confirmado."
			else
				render :show
			end
		end

		def enviar_ao_almoxarifado
			if @consumo.enviar_ao_almoxarifado!
				redirect_to gestao_de_estoque_consumo_path(@consumo), notice: 'O consumo foi enviada ao almoxarfiado com sucesso.'
			else
				render :show
			end
		end

		def recusar_requisicao
			@consumo.motivo_de_recusa = consumo_params[:motivo_de_recusa]
			if @consumo.recusar!
				redirect_to gestao_de_estoque_consumo_path(@consumo), notice: 'A Requisição foi recusada com sucesso.'
			else
				render :recusar_requisicao
			end
		end

		def receber_no_almoxarifado
			if @consumo.receber_no_almoxarifado!
				redirect_to gestao_de_estoque_consumo_path(@consumo), notice: 'O consumo foi recebida no almoxarfiado com sucesso.'
			else
				render :show
			end
		end

		private
		def disponibiliza_dependencias
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order(:codigo, :nome)
			@almoxarifados = GestaoDeEstoque::Almoxarifado
				.joins(:unidades_orcamentarias_do_almoxarifado)
				.where("gestao_de_estoque_almoxarifados.orcamento_id = ? and gestao_de_estoque_unidades_orcamentarias_do_almoxarifado.unidade_orcamentaria_id = ?", contexto_atual.id, @consumo.try(:unidade_orcamentaria_id))
				.order("id ASC") || Array.new
			@almoxarifados_interno = GestaoDeEstoque::Almoxarifado.where("orcamento_id = #{contexto_atual.id} and tipo_de_almoxarifado <> 9").order("id ASC")
			@agentes = Base::AgentePublicoMunicipal.all.distinct
			@tipos_de_materiais = GestaoDeEstoque::Consumo.tipos_de_materiais_i18n
			@classificacoes = GestaoDeEstoque::Consumo.classificacoes_i18n
		end

		def adicionar_dependencias_escolas
			if @consumo.present?
				@escolas = []
				@programas = []
				@consumo.programas_por_consumo.each do |campo|
					@escolas << campo.escola
					@programas << campo.programa_por_escola
				end
			else
				@escolas = Array.new
				@programas = Array.new
			end
		end

		def disponibiliza_dependencias_itens_do_consumo
			if @consumo.separa_itens_por_setor
				@itens_por_setor = GestaoDeEstoque::Estoque.where(almoxarifado_id: @consumo.almoxarifado_id,
					unidade_orcamentaria_id: @consumo.unidade_orcamentaria_id,
					sub_elemento_de_despesa_id: @consumo.sub_elemento_de_despesa_id).order('item_id ASC')
					.select{ |estoque| estoque.quantidade_total_saldo > 0 }
				@itens = GestaoDeEstoque::Estoque.where(almoxarifado_id: @consumo.almoxarifado_id,
					unidade_orcamentaria_id: @consumo.unidade_orcamentaria_id,
					sub_elemento_de_despesa_id: @consumo.sub_elemento_de_despesa_id).order('item_id ASC')
					.select{ |estoque| estoque.quantidade_total_saldo > 0 }
			else
				@itens = GestaoDeEstoque::Estoque.where(almoxarifado_id: @consumo.almoxarifado_id,
					unidade_orcamentaria_id: @consumo.unidade_orcamentaria_id,
					sub_elemento_de_despesa_id: @consumo.sub_elemento_de_despesa_id)
			end
		end

		def set_consumo
			@consumo = Consumo.find( params[:id] )
		end

		def set_tipo
			@tipo = :consumo
			@tipo = :outros if params[:tipo] == "outros"
		end

		# Permite apenas os parâmetros específicos
		def consumo_params
			consumo_params = params.require(:gestao_de_estoque_consumo)
				.permit( :data_de_consumo, :codigo, :status, :almoxarifado_id, :unidade_orcamentaria_id, :responsavel_id, :orcamento_id,
					:historico, :setor_solicitante, :requisitante, :motivo_de_recusa, :usa_escola, :separa_itens_por_setor, :escola_id,
					programas_por_consumo_attributes: [
						:id, :escola_id, :programa_por_escola_id, :_destroy
					],
					itens_do_consumo_attributes: [
						:id, :consumo_id, :estoque_id, :item_id, :unidade_de_medida_id, :enviando_ao_almoxarifado_pelo_patrimonio_attribute,
						:quantidade_disponivel_attribute, :quantidade_consumida, :valor_unitario, :total, :setor_id, :_destroy,
						setores_attributes: [
							:id, :item_do_consumo_id, :nome, :quantidade, :quantidade_disponivel_por_setor_attribute, :_destroy
						]
					]
				)

			consumo_params.merge(outros_procedimentos: params[:gestao_de_estoque_consumo][:tipo] == "outros")
		end
	end
end
