class Contabilidade::TaloesDeReceitaController < ApplicationController
	include ContabilidadeControllerConcern
	include ControllerConcern
	include GeradorDeEventosContabeisController

	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:fontes_de_recursos]
	before_action :set_talao_de_receita, only: [:show, :edit, :update, :destroy]
	before_action :disponibiliza_dependencias, only: [:index, :new, :edit]
	before_action :disponibiliza_eventos_contabeis, only: [:new, :edit, :create, :update]
	before_action -> { verifica_mes_bloqueado(@talao_de_receita)}, only: [:new, :edit, :create, :update, :destroy]

	# GET /contabilidade/taloes_de_receita
	def index
		@url_taloes_de_receita = contabilidade_taloes_de_receita_path
		@action_taloes_de_receita = ""
		@contas_bancarias = Base::ContaBancaria.all
		@fonte_de_recursos = contexto_atual.fontes_de_recursos.all

		if query_params["orcamentos_da_receita_unidade_orcamentaria_por_natureza_da_receita_unidade_orcamentaria_id"].present?
			unidade_orcamentaria_id = query_params["orcamentos_da_receita_unidade_orcamentaria_por_natureza_da_receita_unidade_orcamentaria_id"]
			@taloes_de_receita_busca = contabilidade_atual.taloes_de_receita.joins(orcamentos_da_receita: [unidade_orcamentaria_por_natureza_da_receita: :unidade_orcamentaria]).where('loa_unidades_orcamentarias.id = ?', unidade_orcamentaria_id).distinct
		else
			@taloes_de_receita_busca = contabilidade_atual.taloes_de_receita
		end

		if params[:orcamentarios].present?
			@url_taloes_de_receita = orcamentarios_contabilidade_taloes_de_receita_path
			@action_taloes_de_receita = "orcamentarios"
			@taloes_de_receita_busca = @taloes_de_receita_busca.where(origem_do_talao: :orcamentario).joins(:natureza_da_receita).order("data_do_talao DESC, base_naturezas_da_receita.codigo")
		elsif params[:extra_orcamentarios].present?
			@url_taloes_de_receita = extra_orcamentarios_contabilidade_taloes_de_receita_path
			@action_taloes_de_receita = "extra_orcamentarios"
			@contas_extra_orcamentarias = Contabilidade::ContaExtraOrcamentaria.ativos.where(orcamento: contexto_atual)
			@taloes_de_receita_busca = @taloes_de_receita_busca.where(origem_do_talao: :extra_orcamentario).order("data_do_talao DESC")
		end

		if params[:q].present? && params[:q][:valor].present?
			valor_buscado = params[:q][:valor].gsub(".", "").gsub(",", ".")
			@taloes_de_receita_busca = @taloes_de_receita_busca.where(valor: valor_buscado)
			@valor = valor_buscado.gsub(".", ",")
		end
		@q = @taloes_de_receita_busca.where("extract('Year' from data_do_talao) = ?", contexto_atual.exercicio).order("data_do_talao desc").ransack(query_params)
		@taloes_de_receita = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		
		if request.format.pdf?
			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 Gestora: #{unidade_orcamentaria.codigo_e_nome} - "
			else
				titulo2 += "Unidade Gestora: CONSOLIDADO - "
			end
			if params[:q].present? && params[:q]["pessoa_id_eq"].present?
				fornecedor = Base::Pessoa.find(params[:q]["pessoa_id_eq"])
				titulo3 += "Fornecedor: #{fornecedor.nome_e_cpf_ou_cnpj}"
			end

			titulo2 += "Período: #{params[:q]["data_do_talao_gteq"]} até #{params[:q]["data_do_talao_lteq"]} " if params[:q].present? and (params[:q]["data_do_talao_gteq"].present? || params[:q]["data_do_talao_lteq"].present?)
		end

		@lista_de_taloes = @q.result(distinct: false).order("data_do_talao DESC")

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

			format.pdf do
				render pdf: "taloes_de_receita",
				template: 'contabilidade/taloes_de_receita/index.pdf.slim',
				orientation: 'Landscape',
				header: {
					html: {
						template: 'layouts/_cabecalho_pdf.html.slim',
						locals: { titulo1: 'Relação de Pagamentos' , 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 /contabilidade/taloes_de_receita/new
	def new
		@talao_de_receita = contabilidade_atual.taloes_de_receita.new

		if params['relancamento'] == '1'
			@talao_de_receita = contabilidade_atual.taloes_de_receita.find(session[:anulacao_do_talao_de_receita]['talao_de_receita_id'])
			@talao_de_receita[:relancamento] = true

			carrega_select_box_para_edit

			@talao_de_receita.natureza_da_receita_id = @talao_de_receita.try(:orcamento_da_receita).try(:unidade_orcamentaria_por_natureza_da_receita_id)
			@talao_de_receita.unidade_orcamentaria_id = @talao_de_receita.try(:orcamento_da_receita).try(:unidade_orcamentaria_por_natureza_da_receita).try(:unidade_orcamentaria_id)
		else
			@talao_de_receita[:relancamento] = false
			
			if params[:item_do_lote_da_receita_id].present?
				@talao_de_receita.item_do_lote_da_receita_id = params[:item_do_lote_da_receita_id].to_i 
				@talao_de_receita.valor = params[:valor].to_d
				@talao_de_receita.data_do_talao = params[:data_do_talao]
			end
			if params[:atributos].present?
				reconstroi_gerador( @talao_de_receita, params[:atributos] )
				disponibiliza_dependencias
				carrega_select_box_para_new
			else
				@naturezas_da_receita = []
				@fontes_de_recursos = []
				@transferencias = []
			end
		end
	end

	# POST /contabilidade/taloes_de_receita
	def create
		ActiveRecord::Base.transaction do
			@talao_de_receita = contabilidade_atual.taloes_de_receita.new(talao_de_receita_params)
			if talao_de_receita_params[:relancamento] == true || talao_de_receita_params[:relancamento] == "true"
				anulacao = Contabilidade::AnulacaoDoTalaoDeReceita.new(session[:anulacao_do_talao_de_receita])
				anulacao.save
			end

			# Operação de Credito preenche automaticamente
			if @talao_de_receita.natureza_da_receita.present? && (@talao_de_receita.natureza_da_receita.codigo.first(4) == "0021" || (@talao_de_receita.natureza_da_receita.codigo.first(3) == "009" && @talao_de_receita.natureza_da_receita.codigo[4] == "2") || @talao_de_receita.natureza_da_receita.codigo.first(3) == "902")
				op = @talao_de_receita.operacao_de_credito
				conta_bancaria_por_unidade_orcamentaria = op.conta_bancaria_arrecadadora.contas_bancarias_por_unidade_orcamentaria.joins(unidade_orcamentaria: :orgao).where("loa_unidades_orcamentarias.codigo = ? AND loa_orgaos.codigo = ? AND loa_orgaos.orcamento_id = ?", op.unidade_orcamentaria_arrecadadora&.codigo, op.unidade_orcamentaria_arrecadadora&.orgao&.codigo, contexto_atual.id).first
				
				@talao_de_receita.conta_bancaria_por_unidade_orcamentaria_id = conta_bancaria_por_unidade_orcamentaria.id if conta_bancaria_por_unidade_orcamentaria.present?
				@talao_de_receita.sub_conta_pcasp_id = op.sub_conta_pcasp_id
				@talao_de_receita.pessoa_id = op.financiador.id
			end 

			@talao_de_receita.skip_callback = true
			if @talao_de_receita.save
				if @talao_de_receita.faz_movimentacoes_validas?
					# if params[:contabilidade_talao_de_receita][:manter_form] == "true"
					# 	redirect_path = { action: :new }
					# else
					# 	redirect_path =  @talao_de_receita
					# end
					@talao_de_receita.skip_callback = false
					@talao_de_receita.gerar_todos_os_movimentos(:data_do_talao, contexto_atual)
					redirect_to @talao_de_receita, notice: 'Talao de receita foi criado(a) com sucesso.'
				else
					set_orcamentario_ou_extraorcamentario
					error = mensagem_de_erro_das_movimentacoes_erradas( @talao_de_receita )
					redirect_to new_contabilidade_talao_de_receita_path(exercicio: contabilidade_atual.exercicio, atributos: talao_de_receita_params), alert: error
					raise ActiveRecord::Rollback
				end
			else
				set_orcamentario_ou_extraorcamentario
				disponibiliza_dependencias
				carrega_select_box_para_new
				render :new
			end
		end
	end

	# GET /contabilidade/taloes_de_receita/1
	def show
		@exibir_alerta_contexto = self.send(:exibir_alerta_de_contexto?, @talao_de_receita&.data_do_talao)
	end

	# GET /contabilidade/taloes_de_receita/1/edit
	def edit
		
		if @talao_de_receita.orcamento.exercicio != contexto_atual.exercicio
			redirect_to @talao_de_receita,alert: "Não foi possível editar o talão de receita a data do talão é diferente do exercicio logado"
		end
		
		if @talao_de_receita.natureza_da_receita_id
			natureza_da_receita_id = @talao_de_receita.natureza_da_receita_id
			unidade_orcamentaria_id = @talao_de_receita.unidade_orcamentaria.id

			@talao_de_receita.natureza_da_receita_id = natureza_da_receita_id
			@talao_de_receita.unidade_orcamentaria_id = unidade_orcamentaria_id

			# TRANSFORMA O VALOR EM POSITIVO SOMENTE PARA EDIÇÃO
			@talao_de_receita.valor = @talao_de_receita.valor * -1 if @talao_de_receita.valor < 0
			@talao_de_receita.complementos_por_fonte_do_talao_de_receita.each do |complemento|
				complemento.valor = complemento.valor * -1 if complemento.valor < 0
			end
		end
		carrega_select_box_para_edit
	end

	# PATCH/PUT /contabilidade/taloes_de_receita/1
	def update
		@talao_de_receita.transaction do
			@talao_de_receita.skip_callback = true
			if @talao_de_receita.update(talao_de_receita_params)
				@talao_de_receita.skip_callback = false
				@talao_de_receita.gerar_todos_os_movimentos(:data_do_talao, contexto_atual)
				redirect_to @talao_de_receita, notice: 'Talao de receita foi atualizado com sucesso.'
			else
				disponibiliza_dependencias
				carrega_select_box_para_edit
				render :edit
			end
		rescue Exception => e
			disponibiliza_dependencias
			carrega_select_box_para_edit
			flash.now[:alert] = e
			render :edit
		end
	end

	# DELETE /contabilidade/taloes_de_receita/1
	def destroy
		mensagem = apaga_e_retorna_mensagem(@talao_de_receita)
		redirect_to @talao_de_receita, mensagem
	end

	def fontes_de_recursos
		unidade_por_natureza_da_receita = Loa::UnidadeOrcamentariaPorNaturezaDaReceita.find_by(natureza_da_receita_id: params[:unidade_orcamentaria_por_natureza_da_receita_id], unidade_orcamentaria_id: params[:unidade_orcamentaria_id])
		@fontes_de_recursos = Loa::OrcamentoDaReceita.where( unidade_orcamentaria_por_natureza_da_receita_id: unidade_por_natureza_da_receita.id).order(:fonte_de_recursos_id)
		
		respond_to do |format|
			format.json { render json: @fontes_de_recursos }
			format.js
		end
	end

	def fontes_de_recursos_extra
		@fontes_de_recursos = Loa::OrcamentoDaReceita.joins(unidade_orcamentaria_por_natureza_da_receita: :unidade_orcamentaria).where("loa_unidades_orcamentarias_por_natureza_da_receita.unidade_orcamentaria_id = ?", params[:unidade_orcamentaria_id]).all.map { |i| i.fonte_de_recursos }.uniq
		
		respond_to do |format|
			format.json { render json: @fontes_de_recursos.map { |i| {id: i.id, codigo_e_descricao: i.codigo_e_descricao}} }
		end
	end

	private
		def set_talao_de_receita
			@talao_de_receita = Contabilidade::TalaoDeReceita.find( params[:id] )
		end

		def set_orcamentario_ou_extraorcamentario
			if params[:contabilidade_talao_de_receita][:orcamentarios].present?
				params[:orcamentarios] = true
			end
			if params[:contabilidade_talao_de_receita][:extra_orcamentarios].present?
				params[:extra_orcamentarios] = true
			end
		end

		def disponibiliza_dependencias
			data = ('01/01/'+"#{exercicio_atual}").to_date
			@pessoas = Base::Pessoa.includes(:tipo_de_pessoa).all

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

			@naturezas_da_receita = contexto_atual.naturezas_da_receita.joins(:receita_stn).where('base_receitas_stn.data_inativacao is null OR base_receitas_stn.data_inativacao <= ?', data).order('base_naturezas_da_receita.codigo')
			@tipos_de_documento = Contabilidade::TalaoDeReceita.tipos_de_documento
			@tipos_do_talao = Contabilidade::TalaoDeReceita.tipo_do_taloes
			@operacoes_de_credito = Obra::OperacaoDeCredito.where( unidade_orcamentaria_id: @talao_de_receita.unidade_orcamentaria_id).where(conta_bancaria_id: @talao_de_receita.conta_bancaria_por_unidade_orcamentaria.conta_bancaria_id).where.not(natureza_da_receita: nil) rescue []
			@complementos_da_fonte = (@talao_de_receita.nil? || @talao_de_receita.new_record?) ? [] : Contabilidade::ComplementoPorFonteDoTalaoDeReceita.complementacao_da_fonte_de_recursos
			@contas_extra_orcamentarias = []
			@contas_bancarias = []
			@sub_contas = []
			classificacoes_da_receita = contexto_atual.naturezas_da_receita.select{ |natureza| natureza.orcamentos_da_receita.sum(&:valor) != 0}.map{ |natureza| natureza.id}
			@classificacoes_da_receita = contexto_atual.naturezas_da_receita.where(id: classificacoes_da_receita)
			if @talao_de_receita && @talao_de_receita.unidade_orcamentaria.present?
				@contas_bancarias = Base::ContaBancariaPorUnidadeOrcamentaria.where( unidade_orcamentaria_id: @talao_de_receita.unidade_orcamentaria_id).order(:conta_bancaria_id)
			end

			if params[:extra_orcamentarios].present? && params[:extra_orcamentarios] == "true"
				@sub_contas = contexto_atual.sub_contas_pcasp.where(data_de_inativacao: nil).investimentos
			else
				if @talao_de_receita.present? && @talao_de_receita.unidade_orcamentaria.present?
					if @talao_de_receita.natureza_da_receita.present? && @talao_de_receita.natureza_da_receita.try(:detalhamento_optativo).to_s == "3"
						@sub_contas = contexto_atual.sub_contas_pcasp.where(data_de_inativacao: nil).divida_ativa
					end
					if @talao_de_receita.natureza_da_receita.present? && (@talao_de_receita.natureza_da_receita.try(:codigo).to_s == '0012150111000000' || @talao_de_receita.natureza_da_receita.try(:codigo).to_s == '0072150211000000')
						@sub_contas = contexto_atual.sub_contas_pcasp.where(data_de_inativacao: nil).rpps
					end
					if @talao_de_receita.natureza_da_receita.present? && (@talao_de_receita.natureza_da_receita.try(:codigo).to_s.first(4) == '0021' )
						@sub_contas = contexto_atual.sub_contas_pcasp.where(data_de_inativacao: nil).operacao_de_credito
					end
				end
			end

			@retencoes = []
			if @talao_de_receita&.extra_orcamentario? || params["extra_orcamentarios"] == "true"
				taloes_com_retencao_ids = Contabilidade::TalaoDeReceita.where(orcamento_id: contexto_atual.id).all.pluck(:retencao_id).compact
				@retencoes = Contabilidade::Retencao.joins(:pagamento).where("pagamento_id > 0 and orcamento_id = ? and contabilidade_retencoes.id not in (?)", contexto_atual.id, taloes_com_retencao_ids).all
			end
		end

		def carrega_select_box_para_new
			data = ('01/01/'+"#{exercicio_atual}").to_date
			@talao_de_receita_new = contabilidade_atual.taloes_de_receita.new
			@contas_extra_orcamentarias = []
			@transferencias = []
			@fontes_de_recursos = []
			@naturezas_da_receita = []

			if @talao_de_receita && @talao_de_receita.unidade_orcamentaria.present?
				@contas_bancarias = Base::ContaBancariaPorUnidadeOrcamentaria.where( unidade_orcamentaria_id: @talao_de_receita.unidade_orcamentaria_id).order(:conta_bancaria_id)

				if @talao_de_receita.conta_bancaria_por_unidade_orcamentaria.present?
					conta_bancaria_por_unidade = Base::ContaBancariaPorUnidadeOrcamentaria.find(@talao_de_receita.conta_bancaria_por_unidade_orcamentaria_id)
					@transferencias = Obra::Transferencia.where(unidade_orcamentaria_id: @talao_de_receita.unidade_orcamentaria_id).where(conta_bancaria_id: conta_bancaria_por_unidade.conta_bancaria.id).where.not(natureza_da_receita: nil)
				end
			end

			if @talao_de_receita.natureza_da_receita.present?
				@naturezas_da_receita = contexto_atual.naturezas_da_receita.joins(unidades_orcamentarias_por_natureza_da_receita: [natureza_da_receita: :receita_stn])
					.where(loa_unidades_orcamentarias_por_natureza_da_receita: {unidade_orcamentaria_id: @talao_de_receita.unidade_orcamentaria_id})
					.where('base_receitas_stn.data_inativacao is null OR base_receitas_stn.data_inativacao <= ?', data).order('base_naturezas_da_receita.codigo')
				@fontes_de_recursos = Loa::OrcamentoDaReceita.where( unidade_orcamentaria_por_natureza_da_receita_id: @talao_de_receita.natureza_da_receita_id ).order(:fonte_de_recursos_id)

				unidade_orcamentaria_por_natureza_da_receita = Loa::UnidadeOrcamentariaPorNaturezaDaReceita.where( id: @talao_de_receita.natureza_da_receita_id ).first
				unidade_orcamentaria = unidade_orcamentaria_por_natureza_da_receita.try(:unidade_orcamentaria)
			end

			if @talao_de_receita.extra_orcamentario?
				if @talao_de_receita.conta_extra_orcamentaria&.repasse_duodecimo_para_a_camara?
					@fontes_de_recursos = contexto_atual.present? ? contexto_atual.fontes_de_recursos.select { |f| f.codigo_completo == '1500000000' } : []
				else
					@fontes_de_recursos = contexto_atual.present? ? contexto_atual.fontes_de_recursos.select { |f| f.codigo_completo == '1869000000' } : []
				end
			end
		end

		def carrega_select_box_para_edit
			data = ('01/01/'+"#{exercicio_atual}").to_date
			if @talao_de_receita.natureza_da_receita.present?
				unidade_orcamentaria_id = @talao_de_receita.unidade_orcamentaria_id
				@contas_extra_orcamentarias = Contabilidade::ContaExtraOrcamentaria.joins(:contas_extra_por_unidades_orcamentarias).where('contabilidade_contas_extra_por_unidades_orcamentarias.unidade_orcamentaria_id = ?', @talao_de_receita.unidade_orcamentaria_id)
				@naturezas_da_receita = contexto_atual.naturezas_da_receita.joins(unidades_orcamentarias_por_natureza_da_receita: [natureza_da_receita: :receita_stn])
					.where(loa_unidades_orcamentarias_por_natureza_da_receita: {unidade_orcamentaria_id: @talao_de_receita.unidade_orcamentaria_id})
					.where('base_receitas_stn.data_inativacao is null OR base_receitas_stn.data_inativacao <= ?', data).order('base_naturezas_da_receita.codigo')
				@transferencias = Obra::Transferencia.where(unidade_orcamentaria_id: unidade_orcamentaria_id)
				@contas_bancarias = Base::ContaBancariaPorUnidadeOrcamentaria.where(unidade_orcamentaria_id: unidade_orcamentaria_id).order(:conta_bancaria_id)
			else
				carrega_select_box_para_new
			end
		end

		# Permite apenas os parâmetros específicos
		def talao_de_receita_params
			params.require(:contabilidade_talao_de_receita).permit( :conta_extra_orcamentaria_id,
				:origem_do_talao, :orcamento_id, :orcamento_da_receita_id, :pessoa_id, :operacao_de_credito_id,
				:tipo_de_documento, :tipo_do_talao, :unidade_orcamentaria_id, :natureza_da_receita_id, :transferencia_id, :retencao_id,
				:conta_bancaria_por_unidade_orcamentaria_id, :data_do_talao, :valor, :historico, :documento_de_credito, :movimentacao_do_plano_de_contas_id, :fonte_de_recursos_id,
				:relancamento, :evento_contabil_id,:pagamento_id, :talao_de_desconto,:retencao_id, :item_do_lote_da_receita_id, :manter_form, :sub_conta_pcasp_id,
				complementos_por_fonte_do_talao_de_receita_attributes: [:id, :orcamento_da_receita_id, :complementacao_da_fonte_de_recurso, :valor, :_destroy]
			)
		end
end
