class Licitacao::LotesController < ApplicationController
	include LicitacaoHelper
	include ControllerConcern
	include LicitacoesContabilidadeControllersConcern

	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except:[:desertar_lote,:fracassar_lote, :lotes_por_ganhador, :lotes_por_projeto, :excluir_rodada_de_lances, :salvar_ganhador, :salvar_ganhador_menor_preco, :editar_itens, :alterar_lotes]
	before_action :set_projeto, only: [:listar_itens, :criar_lotes, :editar_itens]
	before_action :set_lote, only: [:desertar_lote, :confirmar_anulacao_item, :anular_item, :define_ganhador, :salvar_ganhador, :salvar_ganhador_menor_preco, :alternar_cadastro_de_lances, :fracassar_lote, :excluir_rodada_de_lances, :editar_itens, :alterar_lotes]
	before_action :set_item_do_lote, only: [:confirmar_anulacao_item, :anular_item]
	before_action :projeto_deve_estar_aberto, only: [:confirmar_anulacao_item, :anular_item]
	before_action :verifica_se_contem_licitantes, only: [:define_ganhador]
	before_action :valida_se_todos_os_itens_do_lote_tem_cotacoes, only: [:define_ganhador, :alternar_cadastro_de_lances]
	before_action :verifica_se_rodada_nao_esta_concluida, only: [:alternar_cadastro_de_lances]

	def listar_itens
		return if bloqueia_usuario_com_base_em 'criar_lotes'
		if @projeto.aberto?
			@lotes = Licitacao::Lote.where(projeto_id: @projeto.id).first
			@itens = @lotes.itens_do_lote.order(:item_do_pedido_id)
		else
			redirect_to licitacao_projeto_path(@projeto), notice: "Não é possivel separar o projeto por lotes nessa etapa"
		end
	end

	def criar_lotes
		@lotes = Licitacao::Lote.where(projeto_id: @projeto.id).first
		if params[:itens]
				if  params[:itens].count < @lotes.itens_do_lote.count
					lote = @projeto.lotes.create(criterio_de_julgamento: @projeto.lotes.first.criterio_de_julgamento)
					params[:itens].each do |item_do_pedido|
						item = Licitacao::ItemDoLote.find_by_id(item_do_pedido)
						item.update(lote_id: lote.id)
					end
					redirect_to @projeto, success: "Lote criado com sucesso."
				else
					redirect_to licitacao_listar_itens_projeto_path(id: @projeto.id), success: "Não é possivel criar um novo lote, o primeiro lote do projeto não pode ficar vazio"
				end
		else
			redirect_to licitacao_listar_itens_projeto_path(id: @projeto.id), success: "Nenhum item foi selecionado"
		end
	end

	def editar_itens
		return if bloqueia_usuario_com_base_em 'criar_lotes'
		if @projeto.aberto?
			@lotes = @projeto.lotes
			@itens_do_lote = @lote.itens_do_lote.order(:item_do_pedido_id)
		else
			redirect_to licitacao_projeto_path(@projeto), notice: "Não é possivel separar o projeto por lotes nessa etapa"
		end
	end

	def alterar_lotes
		if @lote.update(itens_do_lote_params)
			@lote.reload
			@lote.delete if @lote.itens_do_lote.empty?
			redirect_to @lote.projeto, success: "Lote alterado com sucesso."
		else
			redirect_to licitacao_editar_itens_projeto_path(id: @projeto.id), success: "Não é possivel alterar o lote"
		end
	end

	# GET /licitacao/pedidos/1/edit
	def edit
		@lote = Licitacao::Lote.find(params[:id])
		disponibiliza_dependencias
	end

	# PATCH/PUT /licitacao/pedidos/1
	def update
		@lote = Licitacao::Lote.find(params[:id])
		disponibiliza_dependencias
		if @lote.update( lote_params )
			redirect_to licitacao_projeto_path(@lote.projeto) + "?tab=lotes" , notice: 'Lote foi atualizado com sucesso.'
		else
			render :edit
		end
	end

	# PATCH/PUT /licitacao/lotes/1/desertar_lote
	def desertar_lote
		return if bloqueia_usuario_com_base_em 'criar_lotes'
		if @lote.deserto!
			redirect_to licitacao_processo_path(@lote.projeto) + "?tab=lotes" , notice: 'Lote foi desertado com sucesso'
		else
			redirect_to licitacao_processo_path(@lote.projeto) + "?tab=lotes" , alert: 'Não foi possível desertar o lote'
		end
	end

	# PATCH/PUT /licitacao/lotes/1/fracassar_lote
	def fracassar_lote
			return if bloqueia_usuario_com_base_em 'criar_lotes'
		if @lote.fracassado!
			redirect_to licitacao_processo_path(@lote.projeto) + "?tab=lotes" , notice: 'Lote foi fracassado com sucesso'
		else
			redirect_to licitacao_processo_path(@lote.projeto) + "?tab=lotes" , alert: 'Não foi possível fracassar o lote'
		end
	end

	# GET /licitacao/lotes/1/item/1/anular
	def confirmar_anulacao_item
		return if bloqueia_usuario_com_base_em 'anular_item'
	end

	# PATCH /licitacao/lotes/1/item/1/anular
	def anular_item
		@item_do_lote = Licitacao::ItemDoLote.find(params[:id])
		if @item_do_lote.update(anulacao_params)
			itens_por_pessoa = Licitacao::ItemDoProjetoPorPessoa.where(item_do_lote_id: @item_do_lote.id)

			if itens_por_pessoa != nil
				itens_por_pessoa.each do |item_por_pessoa|
					item_por_pessoa.update(valido: false)
				end
			end

			if @lote.projeto.aberto?
				@item_do_lote.item_do_pedido.update_columns(valido: false, motivo: @item_do_lote.motivo_da_anulacao)
			end

			redirect_to licitacao_projeto_path(@lote.projeto, tab: "lotes"), notice: 'Item do lote foi anulado com sucesso.'
		else
			render :confirmar_anulacao_item
		end
	end

	#GET	/licitacao/lotes/1/define_ganhador
	def define_ganhador
		disponibiliza_dependencias_para_definir_ganhador
	end

	#PATCH/PUT /licitacao/lotes/1/salvar_ganhador
	def salvar_ganhador
		return if bloqueia_usuario_com_base_em 'criar_lotes'
		if @lote.salva_ganhador(ganhador_params)
			redirect_to licitacao_processo_path(@lote.projeto, tab: "lotes"), success: 'O ganhador do lote foi definido com sucesso.'
		else
			disponibiliza_dependencias_para_definir_ganhador
			flash[:alert] = "Não foi possivel definir o ganhador, verifique se todos os campos estão preenchidos corretamente."
			render :define_ganhador
		end
	end

	#PATCH/PUT /licitacao/lotes/1/salvar_ganhador_menor_preco
	def salvar_ganhador_menor_preco
		return if bloqueia_usuario_com_base_em 'criar_lotes'
		if @lote.define_ganhador_menor_preco
			redirect_to licitacao_processo_path(@lote.projeto, tab: "lotes"), success: 'O ganhador do lote foi definido com sucesso.'
		else
			redirect_to licitacao_processo_path(@lote.projeto, tab: "lotes"), alert: 'Não foi possível definir o ganhador do lote.'
		end
	end

	def alternar_cadastro_de_lances
		begin
			if @lote.lances_abertos?
				if @lote.fechar_lances
					flash[:success] = "Cadastro de lances fechado com sucesso!"
				end
			else
				if @lote.abrir_lances
					flash[:success] = "Cadastro de lances aberto com sucesso!"
				end
			end
		rescue => e
			flash[:alert] = e.message
		end
		redirect_to licitacao_mostrar_lances_path(@lote)
	end

	#PATCH/PUT /licitacao/lotes/1/excluir_rodada_de_lances
	def excluir_rodada_de_lances
		return if bloqueia_usuario_com_base_em 'create'
		if @lote.exclui_rodada_de_lances
			redirect_to licitacao_mostrar_lances_path(@lote), success: 'Rodada de lances excluída com sucesso!'
		else
			redirect_to licitacao_mostrar_lances_path(@lote), success: 'Rodada de lances não pode ser excluída!'
		end
	end

	def lotes_por_ganhador
		return if bloqueia_usuario_com_base_em 'create','licitacao/contratos'
		@ganhador = params[:ganhador_id]
		if params[:contrato_id].present?
			@lotes = Licitacao::Lote.where(ganhador_id: @ganhador ).all.ativos
			@contrato = Licitacao::Contrato.find(params[:contrato_id])
			respond_to do |format|
				format.json { render json: @lotes}
				format.js
			end
		else
			@lotes = Licitacao::Lote.where(ganhador_id: @ganhador ).all.ativos
			respond_to do |format|
				format.json { render json: @lotes}
				format.js
			end
		end
	end

	def lotes_por_projeto

		return if bloqueia_usuario_com_base_em 'create','licitacao/contratos'
			@lotes = Licitacao::Lote.where(projeto_id: params[:projeto_id] ).all.ativos
			respond_to do |format|
				format.json { render json: @lotes}
				format.js
			end
	end

	private
	def disponibiliza_dependencias_para_definir_ganhador
		@pessoas_com_cotacao = @lote.pessoas_do_projeto_com_cotacao
	end

	def disponibiliza_dependencias
		if ['chamamento_publico', 'chamada_publica'].include?(@lote.projeto.modalidade_de_licitacao)
			@criterios_de_julgamento = Licitacao::Lote.criterios_de_julgamento.select {|cj| cj.eql?('melhor_tecnica') || cj.eql?('tecnica_e_preco')}
		elsif ['tomada_de_precos', 'concorrencia_publica', 'carona'].include?(@lote.projeto.modalidade_de_licitacao)
			@criterios_de_julgamento = Licitacao::Lote.criterios_de_julgamento.select {|cj| cj.eql?('melhor_tecnica') || cj.eql?('tecnica_e_preco') || cj.eql?('menor_preco')}
		elsif ['pregao_eletronico', 'pregao_presencial'].include?(@lote.projeto.modalidade_de_licitacao)
			@criterios_de_julgamento = Licitacao::Lote.criterios_de_julgamento.select {|cj| cj.eql?('menor_preco') || cj.eql?('maior_desconto')}
		else
			@criterios_de_julgamento = Licitacao::Lote.criterios_de_julgamento.select {|cj| !cj.eql?('melhor_tecnica') && !cj.eql?('tecnica_e_preco')}
		end

		@tipos = Licitacao::Lote.tipos
	end

	def set_projeto
		@projeto = Licitacao::Projeto.find(params[:projeto_id])
		@pedido = @projeto.pedido
	end

	def set_lote
		@lote = Licitacao::Lote.find(params[:lote_id])
	end

	def set_item_do_lote
		@item_do_lote = Licitacao::ItemDoLote.find(params[:id])
	end

	def lote_params
		begin
			params.require(:licitacao_lote).permit(:status,:tipo,:criterio_de_julgamento)
		rescue ActionController::ParameterMissing
			nil
		end
	end

	def anulacao_params
		params.require(:licitacao_item_do_lote).permit(:motivo_da_anulacao).merge(anulado: true)
	end

	def ganhador_params
		params.require(:licitacao_lote).permit(:ganhador_id, :justificativa)
	end

	def projeto_deve_estar_aberto
		redirect_to licitacao_projeto_path(@lote.projeto), alert: "Essa ação não é permitida nessa etapa" unless @lote.projeto.aberto?
	end

	def verifica_se_contem_licitantes
		redirect_to licitacao_processo_path(@lote.processo, tab: "lotes"), alert: "Adicione pelo menos um licitante para definir o ganhador" unless @lote.processo.pessoas_do_projeto.classificados.any?
	end

	def verifica_se_rodada_nao_esta_concluida
		if @lote.rodadas.any? && @lote.lances_fechados? && @lote.rodadas.last.concluida?
			redirect_to licitacao_mostrar_lances_path(@lote), alert: "Essa rodada não pode ser editada pois está concluída."
		end
	end

	def valida_se_todos_os_itens_do_lote_tem_cotacoes
		begin
			@lote.todos_os_itens_do_lote_devem_ter_cotacoes
		rescue Exception => e
			redirect_to licitacao_processo_path(@lote.processo, tab: "lotes"), alert: e.message
		end
	end

	def itens_do_lote_params
		begin
			params.require(:licitacao_lote).permit(itens_do_lote_attributes: [:id, :lote_id, :sequencia])
		rescue ActionController::ParameterMissing
			nil
		end
	end
end
