module GestaoDeEstoque
	class DevolucoesDeMateriaisController < ApplicationController
		include ControllerConcern
		before_action :authenticate_usuario!
		before_action :autoriza_usuario!
		before_action :set_devolucao_de_material, only: [:show, :edit, :update, :destroy, :editar_itens_das_devolucoes_de_materiais,
			:atualiza_itens_das_devolucoes_de_materiais, :recusar_devolucao, :confirmar_recusa, :confirmar_recebimento_da_devolucao,
			:cancelar_devolucao, :confirmar_devolucao, :receber_devolucao, :enviar_devolucao_ao_almoxarifado]

		# GET /gestao_de_estoque/devolucoes_de_materiais
		def index
			disponibiliza_dependencias
			@q = GestaoDeEstoque::DevolucaoDeMaterial.order(:id).search(params[:q])
			@devolucoes_de_materiais = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)

			respond_to do |format|
				format.html
				format.json
			end
		end

		# GET /gestao_de_estoque/devolucoes_de_materiais/1
		def show
			respond_to do |format|
				format.html
				format.json
			end
		end

		# GET /gestao_de_estoque/devolucoes_de_materiais/new
		def new
			disponibiliza_dependencias
			@devolucao_de_material = GestaoDeEstoque::DevolucaoDeMaterial.new(origem_id: params[:origem])
			if params[:tipo] == 'T'
				@devolucao_de_material.origem_type = 'GestaoDeEstoque::Transferencia'
			elsif params[:tipo] == 'R'
				@devolucao_de_material.origem_type = 'Administrativo::RequisicaoDeMaterial'
			end
		end

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

		# POST /gestao_de_estoque/devolucoes_de_materiais
		def create
			@devolucao_de_material = GestaoDeEstoque::DevolucaoDeMaterial.new(devolucao_de_material_params)
			@devolucao_de_material.orcamento = contexto_atual
			if @devolucao_de_material.save
				if @devolucao_de_material.tipo_de_devolucao == "devolucao_total"
					adiciona_itens_total
					redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'Devolucao de material foi criado(a) com sucesso.'
				else
					redirect_to gestao_de_estoque_editar_itens_das_devolucoes_de_materiais_path(@devolucao_de_material)
				end
			else
				render :new
			end
		end

		# PATCH/PUT /gestao_de_estoque/devolucoes_de_materiais/1
		def update
			if @devolucao_de_material.update( devolucao_de_material_params )
				redirect_to @devolucao_de_material, notice: 'Devolucao de material foi atualizado(a) com sucesso.'
			else
				render :edit
			end
		end

		# DELETE /gestao_de_estoque/devolucoes_de_materiais/1
		def destroy
			mensagem = apaga_e_retorna_mensagem(@devolucao_de_material)
			redirect_to gestao_de_estoque_devolucoes_de_materiais_url, mensagem
		end

		def editar_itens_das_devolucoes_de_materiais
			disponibiliza_itens
		end

		def atualiza_itens_das_devolucoes_de_materiais
			return if bloqueia_usuario_com_base_em 'update'
			@devolucao_de_material.transaction do
				if @devolucao_de_material.update(itens_das_devolucoes_de_materiais_params)
					redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'Itens atualizados com sucesso.'
				else
					render :editar_itens_das_devolucoes_de_materiais
				end
			rescue Exception => e
				render :editar_itens_das_devolucoes_de_materiais
				raise ActiveRecord::Rollback
			end
		end

		def enviar_devolucao_ao_almoxarifado
			return if bloqueia_usuario_com_base_em 'update'
			if @devolucao_de_material.enviar_para_almoxarifado!
				redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'A Devolução foi enviada ao almoxarfiado com sucesso.'
			else
				render :show
			end
		end

		def cancelar_devolucao
			return if bloqueia_usuario_com_base_em 'update'
			if @devolucao_de_material.cancelar!
				redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'A Devolução foi cancelada com sucesso.'
			else
				render :show
			end
		end

		def receber_devolucao
			return if bloqueia_usuario_com_base_em 'update'
			if @devolucao_de_material.receber_devolucao!
				redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'Devolução de Material foi confirmada com sucesso.'
			else
				render :show
			end
		end

		def confirmar_devolucao
			return if bloqueia_usuario_com_base_em 'update'
			@devolucao_de_material.transaction do
				if @devolucao_de_material.confirmar_devolucao!
					redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'Devolução de Material foi confirmada com sucesso.'
				else
					render :show
				end
			rescue Exception => e
				render :show
				flash[:alert] = "Erro ao concluir a devolução #{e.message}"
				raise ActiveRecord::Rollback
			end
		end

		def recusar_devolucao

		end

		def confirmar_recusa
			return if bloqueia_usuario_com_base_em 'update'
			@devolucao_de_material.motivo_da_recusa = devolucao_de_material_params[:motivo_da_recusa]
			if @devolucao_de_material.recusar!
				redirect_to gestao_de_estoque_devolucao_de_material_path(@devolucao_de_material), notice: 'Devolução de Material foi recusada com sucesso.'
			else
				render :recusar_devolucao
			end
		end

		# Funções AJAX

		# GET
		def retorna_dados_itens
			@devolucao_de_material = GestaoDeEstoque::DevolucaoDeMaterial.find(params[:id])
			render json: {
				'quantidade_do_item': @devolucao_de_material.quantidade_total_do_item(params[:item])
			}
		end

		private
		def set_devolucao_de_material
			@devolucao_de_material = GestaoDeEstoque::DevolucaoDeMaterial.find( params[:id] )
		end

		def disponibiliza_itens
			if @devolucao_de_material.origem_type == 'GestaoDeEstoque::Transferencia'
				@transferencia = GestaoDeEstoque::Transferencia.find(@devolucao_de_material.origem_id)
				@transferencia.itens_da_transferencia.each do |item_da_transferencia|
					@devolucao_de_material.itens_das_devolucoes_de_materiais.find_or_initialize_by(item_id: item_da_transferencia.item_id, unidade_de_medida_id: item_da_transferencia.unidade_de_medida_de_conversao_id)
				end
			elsif	@devolucao_de_material.origem_type = 'Administrativo::RequisicaoDeMaterial'
				@requisicao = Administrativo::RequisicaoDeMaterial.find(@devolucao_de_material.origem_id)
				@requisicao.itens_das_requisicoes_de_materiais.each do |item_da_requisicao|
					@devolucao_de_material.itens_das_devolucoes_de_materiais.find_or_initialize_by(item_id: item_da_requisicao.item_id, unidade_de_medida_id: item_da_requisicao.unidade_de_medida_id)
				end
			end
		end

		def disponibiliza_dependencias
			@status = GestaoDeEstoque::DevolucaoDeMaterial.status
			@tipos_de_devolucoes = GestaoDeEstoque::DevolucaoDeMaterial.tipos_de_devolucoes
		end

		def adiciona_itens_total
			if @devolucao_de_material.origem_type == 'GestaoDeEstoque::Transferencia'
				@transferencia = GestaoDeEstoque::Transferencia.find(@devolucao_de_material.origem_id)
				if @transferencia.present?
					@transferencia.itens_da_transferencia.each do |item_da_transferencia|
						@devolucao_de_material.itens_das_devolucoes_de_materiais.find_or_initialize_by(item_id: item_da_transferencia.item_id, unidade_de_medida_id: item_da_transferencia.unidade_de_medida_de_conversao_id, quantidade_devolvida: item_da_transferencia.quantidade)
					end
				end
			elsif @devolucao_de_material.origem_type == 'Administrativo::RequisicaoDeMaterial'
				@requisicao = Administrativo::RequisicaoDeMaterial.find(@devolucao_de_material.origem_id)
				if @requisicao.present?
					@requisicao.itens_das_requisicoes_de_materiais.each do |item_da_requisicao|
						@devolucao_de_material.itens_das_devolucoes_de_materiais.find_or_initialize_by(item_id: item_da_requisicao.item_id, unidade_de_medida_id: item_da_requisicao.unidade_de_medida_id, quantidade_devolvida: item_da_requisicao.quantidade_atendida)
					end
				end
			end

			@devolucao_de_material.save
		end

		# Permite apenas os parâmetros específicos
		def devolucao_de_material_params
			params.require(:gestao_de_estoque_devolucao_de_material).permit(:numero_da_devolucao, :origem_id, :origem_type, :tipo,
				:orcamento_id, :status, :data_da_devolucao, :tipo_de_devolucao, :historico_da_devolucao, :motivo_da_recusa,
				itens_das_devolucoes_de_materiais_attributes: [:id, :item_id, :devolucao_de_material_id, :quantidade_devolvida, :unidade_de_medida_id, :_destroy])
		end

		def itens_das_devolucoes_de_materiais_params
			params.require(:gestao_de_estoque_devolucao_de_material).permit(itens_das_devolucoes_de_materiais_attributes: [:id, :item_id,
				:devolucao_de_material_id, :quantidade_devolvida, :unidade_de_medida_id, :_destroy])
		end
	end
end
