module Contabilidade
	class ObrasController < ApplicationController
		include ControllerConcern
		include Contabilidade::ObrasHelper
		include ObraControllersConcern

		before_action -> { verifica_modulo_na_sessao(["contabilidade", "administrativo", "obra", "controladoria"]) }
		before_action :authenticate_usuario!
		before_action :autoriza_usuario!, except: [:servicos, :divulgar_obra, :nao_divulgar_obra, :recuperar_contas_pcasp, :recuperar_dados_de_obra_via_contrato, :verificar_se_contrato_tem_obra_do_tipo_obra]
		before_action :set_obra, only: [:show, :edit, :update, :destroy, :nao_enviar_para_sim, :enviar_para_sim, :editar_data_de_envio_pro_sim, :atualizar_data_de_envio_pro_sim, :divulgar_obra, :nao_divulgar_obra, :editar_prazos_pos_obra, :atualizar_prazos_pos_obra, :editar_estudos_e_projetos, :atualizar_estudos_e_projetos, :tombar_obra]
		before_action :disponibiliza_dependencias, only: [:new, :edit]
		before_action :disponibiliza_dependencias_do_filtro, only: [:index, :servicos]
		before_action :set_utilizando_intermodulos
		# before_action -> {verifica_mes_bloqueado(@obra)}, only: [:edit, :destroy]

		# GET /contabilidade/obras
		def index
			filtro_de_obras_vigentes_no_exercicio_atual = "
				(extract(year from contabilidade_obras.data_de_inicio) = #{contexto_atual.exercicio}
					OR extract(year from contabilidade_obras.data_prevista_de_termino) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:por_prazo]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_acrescimo]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_reducao]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
				licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
				licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_reajuste_acrescimo]} AND
				extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_reajuste_decrescimo]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)	
				"

			if current_usuario.administrador?
				obras = Contabilidade::Obra.left_joins(contratos: [:aditivos]).distinct
			else
				unidades_por_usuario_ids = current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)
				obras = contexto_atual.obras.left_joins(contratos: [:aditivos, unidade_orcamentaria_por_pedido: :unidade_orcamentaria]).where("loa_unidades_orcamentarias.id IN (?)", unidades_por_usuario_ids).distinct
			end

			@q =
			if params[:sem_classificacao].present?
				obras.where("uso_do_bem = ? OR conta_pcasp_id = ?", nil , nil).order(id: :desc).ransack(query_params)
			elsif params[:concluidas_a_tombar].present?
				obras.joins(:situacoes_da_obra).where('contabilidade_situacoes_da_obra.tipo_de_status_da_obra =?', 5).order(id: :desc).ransack(query_params)
			else
				obras.where(tipo_de_obra: Contabilidade::Obra.tipos_de_obra[:obra]).order(id: :desc).ransack(query_params)
			end

			@obras = @q.result(distinct: true).paginate(page: params[:page], per_page: 10)
			@tipos_de_obras = Contabilidade::Obra.tipos_de_obra[:obra]
			@orcamentos = Orcamento.all.order("exercicio DESC")
		end

		# GET /obras/:exercicio/servicos
		def servicos
			filtro_de_obras_vigentes_no_exercicio_atual = "
				(extract(year from contabilidade_obras.data_de_inicio) = #{contexto_atual.exercicio}
					OR extract(year from contabilidade_obras.data_prevista_de_termino) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:por_prazo]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_acrescimo]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_reducao]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
				licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
				licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_reajuste_acrescimo]} AND
				extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)
				OR (
					licitacao_aditivos.status = #{Licitacao::Aditivo.status[:confirmado]} AND
					licitacao_aditivos.modalidade = #{Licitacao::Aditivo.modalidades[:prazo_e_reajuste_decrescimo]} AND
					extract(year from licitacao_aditivos.fim_da_vigencia) >= #{contexto_atual.exercicio}
				)		
				"

			if current_usuario.administrador?
				obras = Contabilidade::Obra.left_joins(contratos: [:aditivos]).where(filtro_de_obras_vigentes_no_exercicio_atual).distinct
			else
				unidades_por_usuario_ids = current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)
				obras = contexto_atual.obras.left_joins(contratos: [:aditivos, unidade_orcamentaria_por_pedido: :unidade_orcamentaria]).where(filtro_de_obras_vigentes_no_exercicio_atual).where("loa_unidades_orcamentarias.id IN (?)", unidades_por_usuario_ids).distinct
			end

			@q = obras.where(tipo_de_obra: Contabilidade::Obra.tipos_de_obra[:servico]).order(id: :desc).ransack(query_params)
			@obras = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
			@tipos_de_obras = Contabilidade::Obra.tipos_de_obra[:servico]
		end

		# GET /contabilidade/obras/1
		def show
		end

		# GET /administrativo/obras/new
		def new
			tipo_de_obra = ((params["servico"].present? && params["servico"] == "true") ? "servico" : "obra")
			@obra = contexto_atual.obras.new(tipo_de_obra: tipo_de_obra)
		end

		# GET /administrativo/obras/1/edit
		def edit
		end

		# POST /contabilidade/obras
		def create
			@obra = contexto_atual.obras.new( obra_params )
			@obra.data_de_envio_pro_sim = @obra.contrato.data_de_envio_pro_sim
			
			if @obra.save
				redirect_to rota_obra(@obra), notice: 'Obra foi criada com sucesso.'
			else
				disponibiliza_dependencias
				render :new
			end
		end

		# PATCH/PUT /contabilidade/obras/1
		def update
			if @obra.update( obra_params )
				redirect_to rota_obra(@obra), notice: 'Obra foi atualizada com sucesso.'
			else
				disponibiliza_dependencias
				render :edit
			end
		end

		# DELETE /administrativo/obras/1
		def destroy
			mensagem = apaga_e_retorna_mensagem(@obra)
			redirect_to rota_obras, mensagem
		end

		# PATCH/PUT /obras/nao_enviar_para_sim
		def nao_enviar_para_sim
			if @obra.update_column(:envia_pro_sim, false)
				redirect_to rota_obra(@obra), notice: 'A obra foi marcada para não ser enviada para o SIM.'
			end
		end

		def enviar_para_sim
			return if bloqueia_usuario_com_base_em 'nao_enviar_para_sim'
			if @obra.update_column(:envia_pro_sim, true)
				redirect_to rota_obra(@obra), notice: 'A obra foi marcada para ser enviada para o SIM.'
			end
		end

		#GET /obras/1/editar_data_de_envio_pro_sim
		def editar_data_de_envio_pro_sim
			return if bloqueia_usuario_com_base_em 'update'
		end

		#PATCH /obras/1/atualizar_data_de_envio_pro_sim
		def atualizar_data_de_envio_pro_sim
			if @obra.update_data_de_envio_pro_sim(obra_params[:data_de_envio_pro_sim]) && !obra_params[:data_de_envio_pro_sim].blank?
				redirect_to rota_obra(@obra), notice: 'Obra foi atualizada com sucesso.'
			else
				render :editar_data_de_envio_pro_sim
			end
		end

		#GET /obras/1/editar_prazos_pos_obra
		def editar_prazos_pos_obra
			return if bloqueia_usuario_com_base_em 'update'
		end

		#PATCH /obras/1/atualizar_prazos_pos_obra
		def atualizar_prazos_pos_obra
			if @obra.update(obra_params)
				redirect_to rota_obra(@obra), notice: 'Prazo Pós Obra foi atualizada com sucesso.'
			else
				render :editar_prazos_pos_obra
			end
		end

		#POST /:exercicio/obras/contas_pcasp
		def recuperar_contas_pcasp
			return if bloqueia_usuario_com_base_em 'index'
			contas = nil
			if params[:uso_do_bem].eql?("especial")
				contas = Contabilidade::Conta.where("codigo LIKE '1232101%'").where.not(codigo: "123210100").where(orcamento_id: Orcamento.where(exercicio: params[:exercicio]).first.id).select(:id, :nome)
			elsif params[:uso_do_bem].eql?("dominical")
				contas = Contabilidade::Conta.where("codigo LIKE '1232104%'").where.not(codigo: "123210400").where(orcamento_id: Orcamento.where(exercicio: params[:exercicio]).first.id).select(:id, :nome)
			elsif	params[:uso_do_bem].eql?("comum_do_povo")
				contas = Contabilidade::Conta.where("codigo LIKE '1232105%'").where.not(codigo: "123210500").where(orcamento_id: Orcamento.where(exercicio: params[:exercicio]).first.id).select(:id, :nome)
			end
			render json: contas
		end

		#GET /obras/:id/editar_estudos_e_projetos
		def editar_estudos_e_projetos
			@obra.mesmo_contrato = params[:mesmo_contrato]
			disponibiliza_dependencias_estudos_e_projetos
		end

		#PATCH /obras/:id/atualizar_estudos_e_projetos
		def atualizar_estudos_e_projetos
			@obra.mesmo_contrato = params[:mesmo_contrato]
			if @obra.update(obra_params)
				redirect_to rota_obra(@obra), notice: ' Estudo/Projetos da Obra foi atualizada com sucesso.'
			else
				disponibiliza_dependencias_estudos_e_projetos
				render :editar_estudos_e_projetos
			end
		end

		#POST /:exercicio/obras/dados_de_obra_via_contrato
		def recuperar_dados_de_obra_via_contrato
			return if bloqueia_usuario_com_base_em 'index'
			dados = nil
			if !params[:contrato_id].nil? && !params[:contrato_id].eql?("")
				contrato = Licitacao::Contrato.find(params[:contrato_id])
				if contrato.obra.present?
					dados = {uso_do_bem: contrato.obra.uso_do_bem, conta_pcasp_id: contrato.obra.pcasp_do_orcamento( contexto_atual ).try(:id)}
				end
			end
			render json: dados
		end

		def verificar_se_contrato_tem_obra_do_tipo_obra
			return if bloqueia_usuario_com_base_em 'index'
			dados = false
			if !params[:contrato_id].nil? && !params[:contrato_id].eql?("")
				dados = (Licitacao::Contrato.find(params[:contrato_id]).try(:obra).try(:tipo_de_obra) == 'obra')
			end
			render json: dados
		end

		def tombar_obra
			ActiveRecord::Base.transaction do
				begin
					@obra.tombar_a_obra
					redirect_to @obra, notice: "Obra Tombada"
				rescue => e
					redirect_to @obra, alert: "Falha no Tombamento #{e.message}"
				end
			end
		end

		private
		def set_obra
			@obra = Contabilidade::Obra.find( params[:id] )
		end

		def disponibiliza_dependencias_estudos_e_projetos
			if params[:mesmo_contrato].eql?("true")
				@contratos = [@obra.contrato]
			else
				@contratos = Licitacao::Contrato.where.not(status: [Licitacao::Contrato.status[:aberto], Licitacao::Contrato.status[:cancelado], Licitacao::Contrato.status[:rescindido]]).joins('LEFT JOIN obra_contratos_da_obra ON licitacao_contratos.id = obra_contratos_da_obra.contrato_id')
						.where(tipo_de_contrato: [Licitacao::Contrato.tipos_de_contratos["contrato_de_obras"], Licitacao::Contrato.tipos_de_contratos["servico_de_engenharia"]])
							.where('obra_contratos_da_obra.contrato_id IS NULL').order(created_at: :desc)
			end
		end

		def disponibiliza_dependencias
			@estados = Base::Estado.all
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias
			@tipos_de_obra = Contabilidade::Obra.tipos_de_obra
			@tipos_de_administracao = contexto_atual.tipos_de_administracao
			@exercicio = contexto_atual.exercicio
			@usos_de_bens = Contabilidade::Obra.uso_do_bens
			if !@obra.nil?
				if @obra.especial?
					@contas_pcasp = Contabilidade::Conta.where("codigo LIKE '1232101%'").where.not(codigo: "123210100").where(orcamento_id: Orcamento.where(exercicio: @exercicio).first.id).select(:id, :nome)
				elsif @obra.dominical?
					@contas_pcasp = Contabilidade::Conta.where("codigo LIKE '1232104%'").where.not(codigo: "123210400").where(orcamento_id: Orcamento.where(exercicio: @exercicio).first.id).select(:id, :nome)
				elsif	@obra.comum_do_povo?
					@contas_pcasp = Contabilidade::Conta.where("codigo LIKE '1232105%'").where.not(codigo: "123210500").where(orcamento_id: Orcamento.where(exercicio: @exercicio).first.id).select(:id, :nome)
				end
			end

			if @obra && @obra.persisted?
				@contratos = [@obra.contrato]
			else
				@contratos = Licitacao::Contrato.where.not(status: [Licitacao::Contrato.status[:aberto], Licitacao::Contrato.status[:cancelado], Licitacao::Contrato.status[:rescindido]]).joins('LEFT JOIN obra_contratos_da_obra ON licitacao_contratos.id = obra_contratos_da_obra.contrato_id')
					.where(tipo_de_contrato: [Licitacao::Contrato.tipos_de_contratos["contrato_de_obras"], Licitacao::Contrato.tipos_de_contratos["servico_de_engenharia"]])
						.where('obra_contratos_da_obra.contrato_id IS NULL').order(created_at: :desc)
				
				@contratos = @contratos.left_outer_joins(:aditivos).where("licitacao_contratos.fim_da_vigencia >= ? OR licitacao_aditivos.fim_da_vigencia >= ?", Date.today, Date.today).uniq
			end

			@classificacoes_de_bens = contexto_atual.contas.where(codigo: ['123210601','123210605','123210700',"123210800"]).order(:codigo)
		end

		def disponibiliza_dependencias_do_filtro
			@tipos_de_status_da_obra = Contabilidade::SituacaoDaObra.tipos_de_status_da_obra
			@fontes_de_origem = Contabilidade::Obra.fontes_de_origem
			@fontes_de_contrapartida = Contabilidade::Obra.fontes_de_contrapartida
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.joins(:orgao).order('loa_orgaos.codigo, loa_unidades_orcamentarias.codigo, loa_unidades_orcamentarias.nome')
			@pessoas = Base::Pessoa.includes(:tipo_de_pessoa).fornecedores
			@engenheiros_da_obra = Base::TipoDePessoa.find_by(codigo: '1').pessoas.order(:nome)
		end

		# Permite apenas os parâmetros específicos
		def obra_params
			params.require(:contabilidade_obra).permit(
			:codigo, :orcamento_id, :tipo_de_obra, :tipo_de_administracao_id,
			:tombo_do_terreno, :tombo_da_construcao, :licenca_ambiental, :orgao_licenca, :cei, :valor,:conta_id,
			:data_de_inicio, :data_prevista_de_termino, :data_da_licenca, :descricao, :contrato_id, :numero_do_crea,
			:possui_garantia, :possui_estudos_projetos, :apelido_da_obra, :fonte_de_origem, :fonte_de_contrapartida, :cep, :logradouro,
			:numero_logradouro, :complemento, :bairro, :cidade_id, :data_de_envio_pro_sim, :programa_de_trabalho, :data_do_alvara,
			:validade_do_alvara, :numero_do_alvara, :prazo_de_garantia, :prazo_de_manutencao, :uso_do_bem, :conta_pcasp_id, :valor_bdi,
			:contrato_estudos_id, :valor_estudos, :mesmo_contrato, :formulario_de_estudos
			)
		end

		def set_utilizando_intermodulos
			session[:set_utilizando_intermodulos] = false
		end

	end
end
