module Contabilidade
class ConciliacoesBancariasController < ApplicationController
	include ControllerConcern
	before_action -> { verifica_modulo_na_sessao(["financeiro"]) }
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!
	before_action :set_conciliacao_bancaria, only: [:show, :edit, :update, :destroy]
	before_action :disponibiliza_dependencias, only: [ :new, :edit ]
	before_action :disponibiliza_dependencias_do_index, only: [ :index ]

	# GET /contabilidade/conciliacoes_bancarias
	def index
		@q = ConciliacaoBancaria.order("ID DESC").search(params[:q])
		@conciliacoes_bancarias = @q.result(distinct: false).includes(:conta_bancaria).paginate(page: params[:page], per_page: 10)
	end

	# GET /contabilidade/conciliacoes_bancarias/1
	def show
		@transacoes_pendentes = @conciliacao_bancaria.transacoes.pendente.all
		@conciliacoes =  @conciliacao_bancaria.conciliacoes.joins(:transacao_da_conciliacao).order("contabilidade_transacoes_da_conciliacao.data ASC").group_by { |c| c.grupo }.to_a
		
		@transacoes_conciliadas = @conciliacao_bancaria.transacoes.conciliado.all
		@transacoes_descartadas = @conciliacao_bancaria.transacoes.descartado.all

		inicio = Date.new(@conciliacao_bancaria.ano_do_arquivo.to_i, Contabilidade::ConciliacaoBancaria.meses_do_arquivo[@conciliacao_bancaria.mes_do_arquivo].to_i, 1)
		fim = inicio.end_of_month
		@movimentacoes_da_conta_bancaria = @conciliacao_bancaria.conta_bancaria.movimentacoes_da_conta_bancaria.where("data_da_movimentacao between ? and ? and historico != 'Saldo inicial do Exercício.'", inicio, fim).where(conciliada: [false, nil]).all
		@movimentacoes_bancarias = @movimentacoes_da_conta_bancaria.to_a
		@transacoes_pendentes.each do |transacao|
			transacao.pesquisa_movimentacao_sugerida(@movimentacoes_da_conta_bancaria)
			if transacao.movimentacao.present?
				@movimentacoes_bancarias.delete_if { |o| o.id == transacao.movimentacao.id }.size
			end
		end
		@movimentacoes = (@transacoes_pendentes + @movimentacoes_bancarias).to_a.sort_by{ |o| o[:data] || o [:data_da_movimentacao]}
	end

	# GET /contabilidade/conciliacoes_bancarias/new
	def new
		@conciliacao_bancaria = ConciliacaoBancaria.new
	end

	# POST /contabilidade/conciliacoes_bancarias
	def create
		@conciliacao_bancaria = ConciliacaoBancaria.new(conciliacao_bancaria_params)

		if @conciliacao_bancaria.save
			redirect_to @conciliacao_bancaria, notice: 'Conciliacao bancária foi criada com sucesso.'
		else
			disponibiliza_dependencias
			if @conciliacao_bancaria.errors[:leitura_do_arquivo].present?
				flash[:alert] = @conciliacao_bancaria.errors[:leitura_do_arquivo].join(",")
			end
			render :new
		end
	end

	# DELETE /contabilidade/conciliacoes_bancarias/1
	def destroy
		if @conciliacao_bancaria.transacoes.conciliado.any?
			redirect_to @conciliacao_bancaria, notice: "Conciliação não pode ser excluída pois possúi transações conciliadas."
		else
			if @conciliacao_bancaria.destroy
				redirect_to contabilidade_conciliacoes_bancarias_url, notice: "Conciliação excluída com sucesso"
			else
				flash[:alert] = @conciliacao_bancaria.errors[:exclusao_da_conciliacao].join(",") if @conciliacao_bancaria.errors[:exclusao_da_conciliacao].present?
				render :show
			end
		end
	end

	def disponibiliza_dependencias
		@bancos = Base::Banco.all.order("numero_do_banco ASC")
		@contas_bancarias = Base::ContaBancaria.joins(:agencia).where("base_agencias.banco_id = ?", @conciliacao_bancaria.try(:banco_id)) || Array.new
	end

	def disponibiliza_dependencias_do_index
		@bancos = Base::Banco.all.order("numero_do_banco ASC")
		@contas_bancarias = Base::ContaBancaria.all
		@meses_do_arquivo = Contabilidade::ConciliacaoBancaria.meses_do_arquivo
		@unidades_orcamentarias = contexto_atual.unidades_orcamentarias
	end

	def conciliar
		@transacao_da_conciliacao = Contabilidade::TransacaoDaConciliacao.find(params[:transacao_da_conciliacao_id])
		respond_to do |format|
			begin
				if @transacao_da_conciliacao.conciliar(params[:movimentacao_id])
					format.json { render json: { status: true, mensagem: "", transacao_da_conciliacao: @transacao_da_conciliacao, movimentacao_da_conta_bancaria: @transacao_da_conciliacao.movimentacao } }
				else
					format.json { render json: { status: false, mensagem: "Não foi possível conciliar a movimentação." } }
				end
			rescue
				format.json { render json: { status: false, mensagem: "Não foi possível conciliar a movimentação." } }
			end
		end
	end

	def conciliar_selecionados
		respond_to do |format|
			begin
				grupo = SecureRandom.uuid

				lista_de_transacoes = params[:transacoes].split(",")
				lista_de_movimentacoes = params[:movimentacoes].split(",")
				
				if lista_de_transacoes.size == 1 && lista_de_movimentacoes.size > 1
					lista_de_movimentacoes.each do |movimentacao|
						conciliacao = Contabilidade::Conciliacao.create(
							transacao_da_conciliacao_id: s.first.to_i,
							movimentacao_da_conta_bancaria_id: movimentacao.to_i,
							grupo: grupo,
							tipo_de_grupo: :transacao
						)
					end
				end

				if lista_de_transacoes.size > 1 && lista_de_movimentacoes.size == 1
					lista_de_transacoes.each do |transacao|
						conciliacao = Contabilidade::Conciliacao.create(
							transacao_da_conciliacao_id: transacao.to_i,
							movimentacao_da_conta_bancaria_id: lista_de_movimentacoes.first.to_i,
							grupo: grupo,
							tipo_de_grupo: :movimento
						)
					end
				end

				if lista_de_transacoes.size == 1 && lista_de_movimentacoes.size == 1
					conciliacao = Contabilidade::Conciliacao.create(
						transacao_da_conciliacao_id: lista_de_transacoes.first.to_i,
						movimentacao_da_conta_bancaria_id: lista_de_movimentacoes.first.to_i,
						grupo: grupo,
						tipo_de_grupo: :nenhum
					)
				end
				format.json { render json: { status: true, mensagem: "As movimentações foram conciliadas.", quantidade: lista_de_transacoes.size } }
			rescue
				format.json { render json: { status: false, mensagem: "Não foi possível conciliar as movimentações selecionadas.", quantidade: lista_de_transacoes.size } }
			end
		end
	end

	private
		def set_conciliacao_bancaria
			@conciliacao_bancaria = ConciliacaoBancaria.find( params[:id] )
		end

		# Permite apenas os parâmetros específicos
		def conciliacao_bancaria_params
			params.require(:contabilidade_conciliacao_bancaria).permit(
				:banco_id, :conta_bancaria_id, :mes_do_arquivo, :ano_do_arquivo,
				:arquivo_ofx, :arquivo_pdf)
		end
	end
end
