class Contabilidade::TransferenciasFinanceirasController < ApplicationController
	include ContabilidadeControllerConcern
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:confirmar]
	before_action :disponibiliza_dependencias, only: [:new, :create, :edit, :update]
	before_action :set_transferencia_financeira, only: [:edit, :update, :destroy, :show, :confirmar]
	before_action -> { verifica_mes_bloqueado(@transferencia_financeira)}, only: [:edit, :destroy]

	def index
		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
		sorted_params = params.fetch(:q, {}).permit!.to_h.sort.reverse.to_h
		
		@q = contexto_atual.transferencias_financeiras.joins(:conta_bancaria_origem, :conta_bancaria_destino).where('base_contas_bancarias_por_unidade_orcamentaria.unidade_orcamentaria_id in (?)', @unidades_orcamentarias.pluck(:id)).order(data: :desc, numero_da_transferencia: :desc).ransack(sorted_params)
		if params[:q].present? && params[:q]["conta_bancaria_destino_conta_bancaria_id_eq"].present?
			@q = contexto_atual.transferencias_financeiras.where('base_contas_bancarias_por_unidade_orcamentaria.unidade_orcamentaria_id in (?)', @unidades_orcamentarias.pluck(:id)).order(data: :desc, numero_da_transferencia: :desc).ransack(sorted_params)
		end

		@transferencias_financeiras = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)

		@contas_bancarias = Base::ContaBancaria.left_outer_joins(agencia: :banco).includes(agencia: :banco).order(conta_caixa_pcasp: :desc, sigla: :asc, numero_da_conta: :asc)
		
		if request.format.pdf?
			titulo2 = ""
			titulo3 = ""
			if params[:q].present? && params[:q]["conta_bancaria_origem_unidade_orcamentaria_id_eq"].present? && params[:q]["conta_bancaria_destino_unidade_orcamentaria_id_eq"].present?
				unidade_origem = Loa::UnidadeOrcamentaria.find(params[:q]["conta_bancaria_origem_unidade_orcamentaria_id_eq"])
				unidade_destino = Loa::UnidadeOrcamentaria.find(params[:q]["conta_bancaria_destino_unidade_orcamentaria_id_eq"])
				titulo2 += "Unidade Orçamentária Origem: #{unidade_origem.codigo_e_nome} - Unidade Orçamentária Destino: #{unidade_destino.codigo_e_nome} - "
			elsif params[:q].present? && params[:q]["conta_bancaria_origem_unidade_orcamentaria_id_eq"].present? && params[:q]["conta_bancaria_destino_unidade_orcamentaria_id_eq"].blank?
				unidade_origem = Loa::UnidadeOrcamentaria.find(params[:q]["conta_bancaria_origem_unidade_orcamentaria_id_eq"])
				titulo2 += "Unidade Orçamentária Origem: #{unidade_origem.codigo_e_nome} - "
			elsif params[:q].present? && params[:q]["conta_bancaria_origem_unidade_orcamentaria_id_eq"].blank? && params[:q]["conta_bancaria_destino_unidade_orcamentaria_id_eq"].present?
				unidade_destino = Loa::UnidadeOrcamentaria.find(params[:q]["conta_bancaria_destino_unidade_orcamentaria_id_eq"])
				titulo2 += "Unidade Orçamentária Destino: #{unidade_destino.codigo_e_nome} - "
			else
				titulo2 += "Unidade Orçamentária: CONSOLIDADO - "
			end

			titulo2 += "De: #{params[:q]["data_gteq"] rescue ''} Até: #{params[:q]["data_lteq"] rescue ''} - " if params[:q].present? and (params[:q]["data_gteq"].present? || params[:q]["data_lteq"].present?)
			titulo2 += "Nº da Transferência: #{params[:q][:numero_da_transferencia_eq]} - " if params[:q].present? and params[:q][:numero_da_transferencia_eq].present?
			titulo3 += "Status: #{params[:q][:status_eq]} - " if params[:q].present? and params[:q][:status_eq].present?
			
			@q = contexto_atual.transferencias_financeiras.order(data: :desc, numero_da_transferencia: :desc).ransack(query_params)
			@lista_transferencias = @q.result(distinct: false)
		end

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

			format.pdf do
				render pdf: "liquidacoes",
				template: 'contabilidade/transferencias_financeiras/index.pdf.slim',
				orientation: 'Landscape',
				header: {
					html: {
						template: 'layouts/_cabecalho_pdf.html.slim',
						locals: { titulo1: 'Relação de Transferências Financeiras' , 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

	def new
		transferencia_realizada = Contabilidade::TransferenciaFinanceira.where("conta_do_grupo_de_retencoes_do_controle_de_pg_id = ?", params[:conta_do_grupo_de_retencoes_do_controle_de_pg_id]).first
		redirect_to contabilidade_transferencias_financeiras_path + "?utf8=✓&q%5Bnumero_da_transferencia_eq%5D=#{transferencia_realizada.try(:numero_da_transferencia)}", notice: "Esta transferência já foi realizada." if transferencia_realizada.present?


		if params[:conta_do_grupo_de_retencoes_do_controle_de_pg_id].present?
			conta_do_grupo_de_retencoes_do_controle_de_pg = Contabilidade::ContaDoGrupoDeRetencoesDoControleDePg.find(params[:conta_do_grupo_de_retencoes_do_controle_de_pg_id])
			if conta_do_grupo_de_retencoes_do_controle_de_pg.agrupamento_de_retencoes_do_controle_de_pg.detalhamento_por_ug? && conta_do_grupo_de_retencoes_do_controle_de_pg.agrupamento_de_retencoes_do_controle_de_pg.detalhamento_por_fonte?
				conta_bancaria_por_unidade_orcamentaria = Base::ContaBancariaPorUnidadeOrcamentaria.where("conta_bancaria_id = ? and unidade_orcamentaria_id = ? and principal is true", conta_do_grupo_de_retencoes_do_controle_de_pg.conta_origem_id, conta_do_grupo_de_retencoes_do_controle_de_pg.unidade_orcamentaria.id).first
				unidade_orcamentaria_origem_id = conta_do_grupo_de_retencoes_do_controle_de_pg.unidade_orcamentaria.try(:id)
				fonte_de_recurso_origem_id = conta_do_grupo_de_retencoes_do_controle_de_pg.fonte_de_recurso.try(:id)
			elsif conta_do_grupo_de_retencoes_do_controle_de_pg.agrupamento_de_retencoes_do_controle_de_pg.detalhamento_por_ug?
				conta_bancaria_por_unidade_orcamentaria = Base::ContaBancariaPorUnidadeOrcamentaria.where("conta_bancaria_id = ? and unidade_orcamentaria_id = ? and principal is true", conta_do_grupo_de_retencoes_do_controle_de_pg.conta_origem_id, conta_do_grupo_de_retencoes_do_controle_de_pg.unidade_orcamentaria.id).first
				unidade_orcamentaria_origem_id = conta_do_grupo_de_retencoes_do_controle_de_pg.unidade_orcamentaria.try(:id)
			elsif conta_do_grupo_de_retencoes_do_controle_de_pg.agrupamento_de_retencoes_do_controle_de_pg.detalhamento_por_fonte?
				conta_bancaria_por_unidade_orcamentaria = Base::ContaBancariaPorUnidadeOrcamentaria.joins(unidade_orcamentaria: [orgao: :orcamento]).where("conta_bancaria_id = ? and principal is true and exercicio = ?", conta_do_grupo_de_retencoes_do_controle_de_pg.conta_origem_id, contexto_atual.exercicio).first
				unidade_orcamentaria_origem_id = conta_bancaria_por_unidade_orcamentaria.unidade_orcamentaria.try(:id)
				fonte_de_recurso_origem_id = conta_do_grupo_de_retencoes_do_controle_de_pg.fonte_de_recurso.try(:id)
			end
			conta_bancaria_destino  = Base::ContaBancariaPorUnidadeOrcamentaria.joins(unidade_orcamentaria: [orgao: :orcamento]).where("conta_bancaria_id = ? and principal is true and exercicio = ?", conta_do_grupo_de_retencoes_do_controle_de_pg.conta_destino_id, contexto_atual.exercicio).first
			unidade_orcamentaria_destino_id = conta_bancaria_destino.unidade_orcamentaria.try(:id)

			@transferencia_financeira = contexto_atual.transferencias_financeiras.new(
				conta_do_grupo_de_retencoes_do_controle_de_pg_id: params[:conta_do_grupo_de_retencoes_do_controle_de_pg_id],
				valor: conta_do_grupo_de_retencoes_do_controle_de_pg.valor_do_grupo.valor_financeiro,
				unidade_orcamentaria_origem: unidade_orcamentaria_origem_id,
				unidade_orcamentaria_destino: unidade_orcamentaria_destino_id,
				conta_bancaria_origem_id: conta_bancaria_por_unidade_orcamentaria.try(:id),
				conta_bancaria_destino_id: conta_bancaria_destino.try(:id),
				fonte_de_recurso_origem_id: fonte_de_recurso_origem_id
			)
		else
			@transferencia_financeira = contexto_atual.transferencias_financeiras.new
		end
		disponibiliza_dados_edit
	end

	def show
		@exibir_alerta_contexto = self.send(:exibir_alerta_de_contexto?, @transferencia_financeira&.data)
	end

	def edit
		disponibiliza_dados_edit
	end

	def create
		ActiveRecord::Base.transaction do
			begin
				@transferencia_financeira = contexto_atual.transferencias_financeiras.new(transferencias_financeiras_params)
				if @transferencia_financeira.unidades_tem_mesmo_responsavel? || @transferencia_financeira.transferencia_entre_contas_mesma_ug?
					@transferencia_financeira.status = 'confirmado'
				else
					@transferencia_financeira.status = 'solicitado'
				end

				@transferencia_financeira.save!

				if @transferencia_financeira.saldo_final_da_conta_bancaria_valido?
					redirect_to @transferencia_financeira, notice: 'Transferência realizada com sucesso.'
				else
					raise StandardError.new "Conta bancariá origem ficará negativa, refaça o lançamento ou verifique o saldo da Conta."
				end
			rescue => exception
				disponibiliza_dados_edit
				flash.now[:alert] = 'Não foi possível realizar a transferência.' + exception.message
				render :new
				raise ActiveRecord::Rollback
			end
		end
	end

	def update
		ActiveRecord::Base.transaction do
			begin
				if @transferencia_financeira.update(transferencias_financeiras_params.except(:conta_bancaria_origem_id, :conta_bancaria_destino_id))
					if @transferencia_financeira.saldo_final_da_conta_bancaria_valido?
						redirect_to @transferencia_financeira, notice: 'Transferência realizada com sucesso.'
					else
						raise StandardError.new "Conta bancariá origem ficará negativa, refaça o lançamento ou verifique o saldo da Conta."
					end
				else
					flash.now[:alert] = @transferencia_financeira.errors.full_messages.join(", ")
					render :edit
				end
			rescue => exception
				disponibiliza_dados_edit
				flash.now[:alert] = 'Não foi possível realizar a transferência.' + exception.message
				render :edit
				raise ActiveRecord::Rollback
			end
		end
	end

	def destroy
		mensagem = apaga_e_retorna_mensagem(@transferencia_financeira)
		redirect_to @transferencia_financeira, mensagem
	end

	def confirmar
		return if bloqueia_usuario_com_base_em 'update'
		if @transferencia_financeira.confirmar!
			redirect_to @transferencia_financeira, success: 'A transferência foi confirmada com sucesso.'
		else
			redirect_to @transferencia_financeira, alert: 'Não foi possível confirmar a transferência. Por favor, confira se ela contém erros.'
		end
	end

	private
	def transferencias_financeiras_params
		params.require(:contabilidade_transferencia_financeira).permit(:unidade_orcamentaria_origem, :numero_da_transferencia, :unidade_orcamentaria_destino,
			:fonte_de_recurso_origem_id,:fonte_de_recurso_destino_id, :data,:tipo_de_transferencia, :tipo_de_plano_financeiro,
			:tipo_de_plano_previdenciario, :valor, :conta_bancaria_origem_id, :conta_bancaria_destino_id, :documento_bancario,
			:tipo_de_movimento, :historico, :status, :conta_do_grupo_de_retencoes_do_controle_de_pg_id, :conta_origem, :conta_destino)
	end

	def set_transferencia_financeira
		@transferencia_financeira = Contabilidade::TransferenciaFinanceira.find( params[:id] )
	end

	def disponibiliza_dependencias
		#@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.order(:id)
		@contas_bancarias_origem = []
		@contas_bancarias_destino = []
		@tipos_de_transferencia = Contabilidade::TransferenciaFinanceira.tipos_de_transferencia_mapeados
		@documentos_bancarios = Contabilidade::TransferenciaFinanceira.documentos_bancarios
		@tipos_de_movimento = Contabilidade::TransferenciaFinanceira.tipos_de_movimento
		@fontes_de_recurso_origem = []
		@fontes_de_recurso_destino = []
		@tipos_de_plano_financeiro = Contabilidade::TransferenciaFinanceira.tipos_de_plano_financeiro
		@tipos_de_plano_previdenciario =  Contabilidade::TransferenciaFinanceira.tipos_de_plano_previdenciario

		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
	end

	def disponibiliza_dados_edit
		@transferencia_financeira.unidade_orcamentaria_origem = @transferencia_financeira.conta_bancaria_origem.unidade_orcamentaria_id if @transferencia_financeira.persisted?
		@transferencia_financeira.unidade_orcamentaria_destino = @transferencia_financeira.conta_bancaria_destino.unidade_orcamentaria_id if @transferencia_financeira.persisted?
		@contas_bancarias_origem = Base::ContaBancariaPorUnidadeOrcamentaria.left_outer_joins(conta_bancaria: [agencia: :banco]).where("base_contas_bancarias_por_unidade_orcamentaria.unidade_orcamentaria_id = ?", @transferencia_financeira.unidade_orcamentaria_origem).order(conta_caixa_pcasp: :desc, sigla: :asc, numero_da_conta: :asc) if @transferencia_financeira.unidade_orcamentaria_origem.present?
		@contas_bancarias_destino = Base::ContaBancariaPorUnidadeOrcamentaria.left_outer_joins(conta_bancaria: [agencia: :banco]).where("base_contas_bancarias_por_unidade_orcamentaria.unidade_orcamentaria_id = ?", @transferencia_financeira.unidade_orcamentaria_destino).order(conta_caixa_pcasp: :desc, sigla: :asc, numero_da_conta: :asc) if @transferencia_financeira.unidade_orcamentaria_destino.present?

		@fontes_de_recurso_origem = @transferencia_financeira.conta_bancaria_origem.conta_bancaria.fontes_de_recursos if @transferencia_financeira.conta_bancaria_origem.present?
		@fontes_de_recurso_destino = @transferencia_financeira.conta_bancaria_destino.conta_bancaria.fontes_de_recursos if @transferencia_financeira.conta_bancaria_destino.present?
	end
end
