module Pca
class AcoesController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!
	before_action :defini_contexto_atual_da_acao
	before_action :set_acao, only: [:show, :edit, :update, :destroy, :fechar, :voltar_para_aberto, :selecionar_dotacao, :adicionar_dotacao, :atualiza_dotacao, :excluir_dotacao, :editar_itens, :atualizar_itens]
	before_action :disponibiliza_dependencias, only: [:new, :create, :edit, :update, :index, :envios_pncp, :editar_itens]
	before_action :disponibiliza_dependencias_pro_show, only: [:show]
	before_action :disponibiliza_dependencias_itens, only: [:editar_itens, :atualizar_itens, :busca_itens, :adiciona_itens]
	before_action :disponibiliza_dependencias_categorias, only: [:create, :new, :update, :edit]
	before_action -> { redirect_to @acao, alert: 'Essa Ação não pode ser alterada, pois já foi enviada para o PNCP.' if @acao && @acao.enviado_pncp?}, only: [:edit, :update, :destroy, :selecionar_dotacao, :adicionar_dotacao, :atualiza_dotacao, :excluir_dotacao, :editar_itens, :atualizar_itens]

	# GET /pca/acoes
	def index
		@q = Acao.order(:id).ransack(params[:q])
		order_params = 'data_de_cadastro DESC, numero DESC'
		

		if request.format.pdf?
			titulo1 = 'Relação de Demandas'
			titulo2 = ""
			titulo3 = ""
			if params[:q].present? && params[:q]["unidade_orcamentaria_id_eq"].present?
				unidade_orcamentaria = Loa::UnidadeOrcamentaria.find(params[:q]["unidade_orcamentaria_id_eq"])
				titulo2 += "Unidade Orçamentária: #{unidade_orcamentaria.codigo_e_nome}"
			else
				titulo2 += "Unidade Orçamentária: CONSOLIDADO"
			end
			
			if params[:q].present? && params[:q][:prioridade_eq].present?
				if params[:q][:prioridade_eq] == "1"
					prioridade = 'PRIORIDADE: BAIXA'
				elsif params[:q][:prioridade_eq] == "2"
					prioridade = 'PRIORIDADE: MÉDIA'
				elsif params[:q][:prioridade_eq] == "3"
					prioridade = 'PRIORIDADE: ALTA'
				end
			else
				prioridade = ''
			end

			if params[:q].present? && params[:q][:categoria_de_despesa_eq].present?
				if params[:q][:categoria_de_despesa_eq] == "1"
					categoria_de_despesa = ' CATEGORIA DE DESPESA: CUSTEIO'
				elsif params[:q][:categoria_de_despesa_eq] == "2"
					categoria_de_despesa = ' CATEGORIA DE DESPESA: INVESTIMENTO'
				elsif params[:q][:categoria_de_despesa_eq] == "3"
					categoria_de_despesa = ' CATEGORIA DE DESPESA: CUSTEIO E INVESTIMENTO'
				end
			else
				categoria_de_despesa = ''
			end

			if params[:q].present? && params[:q][:status_eq].present?
				if params[:q][:status_eq] == "1"
					status = ' STATUS: ABERTA'
				elsif params[:q][:status_eq] == "2"
					status = ' STATUS: FECHADA'
				elsif params[:q][:status_eq] == "3"
					status = ' STATUS: EM ESTUDO'
				elsif params[:q][:status_eq] == "4"
					status = ' STATUS: EM EXECUÇÃO'
				end
			else
				status = ''
			end

			titulo3 += prioridade + categoria_de_despesa + status

			if cookies[:ano_seguinte].to_boolean == true
				@lista_acoes = @q.result(distinct: true).ano_seguinte(Date.new(contexto_atual.exercicio).next_year.beginning_of_year, Date.new(contexto_atual.exercicio).next_year.end_of_year).order(order_params)
			else
				@lista_acoes = @q.result(distinct: true).ano_atual(Date.new(contexto_atual.exercicio).beginning_of_year, Date.new(contexto_atual.exercicio).end_of_year).order(order_params)
			end
		else
			if cookies[:ano_seguinte].to_boolean == true
				@acoes = @q.result(distinct: false).ano_seguinte(Date.new(contexto_atual.exercicio).next_year.beginning_of_year, Date.new(contexto_atual.exercicio).next_year.end_of_year).where(unidade_orcamentaria_id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).paginate(page: params[:page], per_page: 10)
				@url_acoes = pca_ano_seguinte_path
			else
				@acoes = @q.result(distinct: false).ano_atual(Date.new(contexto_atual.exercicio).beginning_of_year, Date.new(contexto_atual.exercicio).end_of_year).where(unidade_orcamentaria_id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).paginate(page: params[:page], per_page: 10)
				@url_acoes = pca_acoes_path
			end
		end

		@configuracoes = Configuracao.last
		respond_to do |format|
			format.html
			format.json

			format.pdf do
				render pdf: "acoes",
				template: 'pca/acoes/index.pdf.slim',
				orientation: 'Landscape',
				header: {
					html: {
						template: 'layouts/_cabecalho_pdf.html.slim',
						locals: { titulo1: titulo1 , titulo2: titulo2, titulo3: titulo3 }
					},
					spacing: 0
				},
				footer: { right: '[page]', font_size: 8 },
				disable_smart_shrinking: true,
				dpi: '96',
				margin: @configuracoes.margens_customizadas(top: 4)
			end
		end
	end

	# GET /pca/acoes/1
	def show
	end

	# GET /pca/acoes/new
	def new
		@acao = Acao.new
	end

	# GET /pca/acoes/1/edit
	def edit
	end

	# POST /pca/acoes
	def create
		@acao = Acao.new(acao_params)

		if @acao.save
			if @acao.possui_itens?
				redirect_to itens_pca_acao_path(@acao)
			else
				redirect_to @acao, notice: 'Acao foi criado(a) com sucesso.'
			end
		else
			render :new
		end
	end

	# PATCH/PUT /pca/acoes/1
	def update
		if @acao.update( acao_params )
			redirect_to @acao, notice: 'Acao foi atualizado(a) com sucesso.'
		else
			render :edit
		end
	end

	# DELETE /pca/acoes/1
	def destroy
		mensagem = apaga_e_retorna_mensagem(@acao)
		redirect_to pca_acoes_url, mensagem
	end

	# GET /pca/acoes/1/selecionar_dotacao
	def selecionar_dotacao
		if params[:dotacao_id].present? && !params[:dotacao_id].nil?
			@orcamento_da_despesa_por_acao = @acao.orcamentos_da_despesa_por_acao.find(params[:dotacao_id])
		else
			@orcamento_da_despesa_por_acao = @acao.orcamentos_da_despesa_por_acao.new
		end
		carrega_select_box
	end

	# POST /pca/acoes/1/adicionar_dotacao
	def adicionar_dotacao
		@orcamento_da_despesa_por_acao = @acao.orcamentos_da_despesa_por_acao.new(dotacao_params)
		if @orcamento_da_despesa_por_acao.save
			@orcamento_da_despesa_por_acao.update_column(:subacao_id, params[:pca_orcamento_da_despesa_por_acao][:subacao_id].to_i)
			redirect_path = pca_acao_path(@acao, tab: "dotacoes_da_acao")
			redirect_to redirect_path, success: 'Dotação foi adicionada com sucesso.'
		else
			carrega_select_box
			render :selecionar_dotacao
		end
	end

	# POST /pca/acoes/1/atualiza_dotacao
	def atualiza_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		@orcamento_da_despesa_por_acao = @acao.orcamentos_da_despesa_por_acao.find(dotacao_params[:id])
		if @orcamento_da_despesa_por_acao.update(dotacao_params)
			@orcamento_da_despesa_por_acao.update_column(:subacao_id, params[:pca_orcamento_da_despesa_por_acao][:subacao_id].to_i)
			redirect_path = pca_acao_path(@acao, tab: "dotacoes_da_acao")
			redirect_to redirect_path, success: 'Dotação foi atualizada com sucesso.'
		else
			carrega_select_box
			render :selecionar_dotacao
		end
	end

	def cadastrar_justificativa_exclusao_pncp
		@acao = Pca::Acao.find(params[:id])
	end

	# DELETE /pca/acoes/1/excluir_dotacao/1
	def excluir_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		orcamento_da_despesa_por_acao = Pca::OrcamentoDaDespesaPorAcao.find(params[:orcamento_da_despesa_por_acao_id])

		mensagem = apaga_e_retorna_mensagem(orcamento_da_despesa_por_acao)
		redirect_to pca_acao_path(orcamento_da_despesa_por_acao.acao) + "?tab=dotacoes_da_acao", mensagem
	end

	# GET /pca/acoes/1/itens
	def editar_itens
		disponibiliza_dependencias_itens
		if @acao.itens_da_acao.empty?
			@acao.itens_da_acao.build
		end
		@action = params[:action]
	end

	# PATCH /pca/acoes/1/itens
	def atualizar_itens
		return if bloqueia_usuario_com_base_em 'editar_itens'
		if @acao.update(itens_params)
			if params[:continuar_editando].present?
				redirect_to itens_licitacao_pedido_path(@acao), notice: 'Os itens cadastrados foram salvos com sucesso.'
			else
				redirect_to @acao, notice: 'Itens da Ação foram criados com sucesso.'
			end
		else
			@action = params[:action]
			disponibiliza_dependencias_itens
			flash.now[:alert] = "Não foi possivel adicionar os itens à Ação."
			render :editar_itens
		end
	end

	# GET /pca/acoes/1/busca_itens
	def busca_itens
		return if bloqueia_usuario_com_base_em 'editar_itens'
		disponibiliza_dependencias_busca_itens
		@q = Base::Item.where(esconder: false).where(categoria: @acao.categorias_dos_itens).where.not(id: @acao.itens_da_acao.map(&:item_id)).search(params[:q])
		@itens = params[:q].try(:values).try(:delete_if, &:empty?).try(:present?) ? @q.result(distinct: false) : []
		if @itens.size > 100
			@qtd_removida = @itens.size - 100
			@itens = @itens.limit(100)
		end
	end

	# PATCH /pca/acoes/1/adiciona_itens
	def adiciona_itens
		return if bloqueia_usuario_com_base_em 'editar_itens'
		@action = params[:action]
		if params[:itens] && params[:itens].size > 0
			quantidade = @acao.adiciona_itens(params[:itens])
			disponibiliza_dependencias_itens
			flash.now[:notice] = quantidade > 1 ? "#{quantidade} itens adicionados com sucesso" : "#{quantidade} item adicionado com sucesso"
			render :editar_itens
		else
			redirect_to busca_itens_licitacao_pedido_path(@acao), alert: "Nenhum item foi selecionado."
		end
	end

	def defini_contexto_atual_da_acao
		cookies[:ano_seguinte] = params[:ano_seguinte].present? ? params[:ano_seguinte].to_boolean : cookies[:ano_seguinte]
	end

	def disponibiliza_dependencias
		contexto_correto = cookies[:ano_seguinte].to_boolean == true ? contexto_atual : Orcamento.find_by_exercicio(contexto_atual.exercicio.to_i - 1)

		if current_usuario.desenvolvedor?
			@unidades_orcamentarias = contexto_correto.unidades_orcamentarias.order("loa_unidades_orcamentarias.codigo", "loa_unidades_orcamentarias.nome").uniq
		else
			@unidades_orcamentarias = contexto_correto.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order("loa_unidades_orcamentarias.codigo", "loa_unidades_orcamentarias.nome")
		end

		@agentes = ::Base::AgentePublicoMunicipal.all
	end

	def disponibiliza_dependencias_pro_show
		query_params = "item_type like 'Pca::Acao' AND item_id = #{@acao.id}"

		@acao.orcamentos_da_despesa_por_acao.each do |orcamento|
			query_params << " OR (item_type like 'Pca::OrcamentoDaDespesaPorAcao' AND item_id = #{orcamento.id})"
		end

		@logs_da_acao = PaperTrail::Version.where(query_params).order("created_at")
	end

	def disponibiliza_dependencias_itens
		@item = Base::Item.new
		@itens = Base::Item.where(categoria: @acao.categorias_dos_itens).where(esconder: false).includes(:unidade_de_medida)
		@unidades_de_medida = UnidadeDeMedida.all
		@ncms = Ncm.order(:descricao).all
	end

	def disponibiliza_dependencias_busca_itens
		@categorias = @acao.categorias_dos_itens
	end

	def disponibiliza_dependencias_categorias
		@categorias = Base::Categoria.principais.order(:codigo)
		@subcategorias = Base::Categoria.subcategorias
	end

	def carrega_select_box
		@elementos_de_despesa_por_subacao = contexto_atual.elementos_de_despesa.ativos
		@orcamentos_da_despesa = []
		@sub_elementos_de_despesa = []
		@subacoes = []
		
		unidade_orcamentaria = @acao.unidade_orcamentaria
		@subacoes = Loa::Subacao.joins('left join loa_acoes as b on loa_subacoes.acao_id = b.id left join contabilidade_solicitacao_de_alteracao_orcamentarias as c on b.solicitacao_de_alteracao_orcamentaria_id = c.id')
		.where('(c.status = ? or b.solicitacao_de_alteracao_orcamentaria_id is null)', Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.status["confirmado"]).where(unidade_orcamentaria_id: unidade_orcamentaria.id).distinct

		if @orcamento_da_despesa_por_acao.present? && @orcamento_da_despesa_por_acao.persisted?

			@orcamento_da_despesa_por_acao.subacao_id = @orcamento_da_despesa_por_acao.subacao_id
			# @orcamento_da_despesa_por_acao.elemento_de_despesa_por_subacao_id =  @orcamento_da_despesa_por_acao.orcamento_da_despesa.elemento_de_despesa_por_subacao.try(: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 = contexto_atual.elementos_de_despesa.ativos.where(@orcamento_da_despesa_por_acao.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao)).order('base_elementos_de_despesa.codigo').all
			@orcamentos_da_despesa = Loa::OrcamentoDaDespesa.where( elemento_de_despesa_por_subacao_id:  @orcamento_da_despesa_por_acao.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_por_acao.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) )

		end
	end

	def retorna_modalidades_de_licitacao
		modalidades_de_licitacao = Pca::Acao.forma_de_contratacao_modalidades_de_licitacao
		modalidades_de_licitacao = modalidades_de_licitacao.select {|ml| ml.eql?('pregao') || ml.eql?('concorrencia_publica') || ml.eql?('concurso') || ml.eql?('dialogo_competitivo') || ml.eql?('tomada_de_preco')} if params[:modalidade_enum].eql?('processo_licitatorio')
		modalidades_de_licitacao = modalidades_de_licitacao.select {|ml| ml.eql?('chamamento_publico') || ml.eql?('dispensa_de_chamamento') || ml.eql?('inexigibilidade_de_chamamento') || ml.eql?('chamada_publica')} if params[:modalidade_enum].eql?('parceria_osc')
		modalidades_de_licitacao = modalidades_de_licitacao.select {|ml| ml.eql?('nao_de_aplica')} if ['inexigibilidade_de_licitacao','dispensa_de_licitacao', 'carona', 'credenciamento'].include?(params[:modalidade_enum])

		render json: modalidades_de_licitacao.map{|modalidade| {key: modalidade[0], nome: Pca::Acao.localizar('forma_de_contratacao_modalidade_de_licitacao', modalidade[0])}}
	end

	# PATCH /pca/acoes/:id/fechar
	def fechar
		if @acao.fechar!
			redirect_to @acao, success: 'Ação fechada com sucesso.'
		else
			redirect_to @acao, alert: 'Não foi possivel fechada a ação.'
		end
	end

	# PATCH /pca/acoes/:id/voltar_para_aberto
	def voltar_para_aberto
		begin
			if @acao.voltar_para_aberto!
				mensagem = 'Ação reaberta e excluída do PNCP com sucesso.'
				if @acao.enviado_pncp?
					pncp_webservice = Pncp::WebserviceController.new()
					exclusao_acao = pncp_webservice.exclui_acao(@acao)
					mensagem = 'Ação reaberta e excluída do PNCP com sucesso.'
				end
				redirect_to @acao, success: "#{mensagem}"
			end
		rescue => exception
			redirect_to @acao, alert: 'Não foi possivel reabrir a ação.'
			raise ActiveRecord::Rollback
		end
	end

	# GET /pca/envios_pncp
	def envios_pncp
		@url_acoes = pca_envios_pncp_path
		@q = Acao.search(params[:q])

		@acoes = @q.result(distinct: false).where(unidade_orcamentaria_id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order("data_de_previsao_da_contratacao DESC").paginate(page: params[:page], per_page: 10)
	end

	private
	def set_acao
		@acao = Acao.find( params[:id] )
	end

	# Permite apenas os parâmetros específicos
	def acao_params
		params.require(:pca_acao).permit(:numero, :unidade_orcamentaria_id, :categoria_de_despesa, :tipo_de_contratacao, :prioridade, 
			:status, :data_de_cadastro, :data_de_previsao_da_contratacao, :objeto, :justificativa, :resultado_pretendido, :responsavel_id, 
			:forma_de_contratacao_modalidade, :forma_de_contratacao_modalidade_de_licitacao, :orcamento_id, :justificativa_prioridade, :outras_informacoes, 
			:possui_itens, :vinculada_a_outra_acao, :ano_seguinte, tipos_de_despesa_por_acao_attributes: [:id, :tipo_de_despesa, :_destroy],
			categorias_da_acao_attributes: [:id, :categoria_id, :subcategoria_id, :acao_id, :_destroy]
		)
		
	end

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

	def itens_params
		begin
			params.require(:pca_acao).permit(itens_da_acao_attributes: [:id, :quantidade, :valor, :marca, :item_id, :total, :_destroy])
		rescue ActionController::ParameterMissing
			nil
		end
	end

end
end
