class Contabilidade::CancelamentoDeRestoAPagar < ApplicationRecord
	has_paper_trail
	include EnumIsh::Base
	include AASM
	include TradutorConcern
	include GeradorDeEventosContabeis
	include IncrementadorDeCodigoConcern

	attr_accessor :fornecedor_id, :usuario_id, :valor_minimo, :valor_maximo, :fonte_de_recurso_id, :classificacao

	belongs_to :orcamento
	belongs_to :orcamento_dos_empenhos, class_name: '::Orcamento', foreign_key: 'orcamento_dos_empenhos_id'
	belongs_to :unidade_orcamentaria, class_name: "Loa::UnidadeOrcamentaria"
	has_many :restos_a_pagar_cancelados, class_name: "Contabilidade::RestoAPagarCancelado", dependent: :destroy
	has_many :empenhos, through: :restos_a_pagar_cancelados

	accepts_nested_attributes_for :restos_a_pagar_cancelados, reject_if: :all_blank, allow_destroy: true

	validates :restos_a_pagar_cancelados, uniq_nested_attributes: { atributo: :empenho_id, mensagem: "Empenho deve ser único" }

	validates_presence_of :data, :motivo, :classificacao, :tipo

	validate :restos_a_pagar_invalido
	validate :verifica_decreto_preenchido_no_momento_de_confirmar, if: Proc.new{self.status_changed? && self.status == 'confirmado'}

	before_create :atribui_codigo_disponivel, if: Proc.new { self.numero.nil? }
	before_update :atribui_codigo_disponivel, if: Proc.new { self.data_changed? }

  enum_ish :classificacao, ['individual', 'todos', 'intervalo_de_valor', 'fonte_de_recurso', 'fornecedor'], default: 'individual'

	enum status:{
		solicitado: 0,
		confirmado: 1,
		enviado_para_contabilidade: 2
	}

	enum tipo: {
		nao_processado: 0,
		processado: 1
	}

	enum motivo: {
		outros: 2,
		valores_e_ou_inscricoes_indevidas: 4,
		insuficiencia_de_saldo_financeiro: 1
	}

	aasm column: :status, enum: true, whiny_transitions: false do
		state :solicitado, :initial => true
		state :confirmado
		state :enviado_para_contabilidade

		event :confirmar do
			transitions from: :solicitado, to: :confirmado do
				guard do
					!Configuracao.last.envia_empenho_para_contabilidade? && !self.restos_a_pagar_cancelados.sem_valor_cancelado.any? && self.decreto.present?
				end
			end

			transitions from: :enviado_para_contabilidade, to: :confirmado do
				guard do
					Configuracao.last.envia_empenho_para_contabilidade? && !self.restos_a_pagar_cancelados.sem_valor_cancelado.any? && self.decreto.present?
				end
			end
		end

		event :enviar_para_contabilidade do
			transitions from: :solicitado, to: :enviado_para_contabilidade do
				guard do
					Configuracao.last.envia_empenho_para_contabilidade?
				end
			end
		end
	end

	def valor_total
		restos_a_pagar_cancelados.sum(:valor_cancelado)
	end

	def unidade_orcamentaria
		restos_a_pagar_cancelados.last.try(:empenho).try(:unidade_orcamentaria)
	end

	def retorna_liquidacoes
		liquidacoes = []
		self.restos_a_pagar_cancelados.each do |rp|
			if self.nao_processado?
				liquidacoes << rp.liquidacoes.nao_processados(self.orcamento)
			else
				liquidacoes << rp.liquidacoes.processados(self.orcamento)
			end
		end

		return liquidacoes
	end

	def restos_a_pagar_invalido
		errors.add(:base, "A Unidade Orçamentária selecionada, não tem Restos a Pagar. Por favor, selecione um válido.") if restos_a_pagar_cancelados.size < 1
	end

	def verifica_decreto_preenchido_no_momento_de_confirmar
		errors.add(:decreto, "O cancelamento não pode ser confirmado enquanto o decreto não for preenchido") if decreto.nil? || !decreto.present?
	end

	def verifica_motivo_e_tipo
		if (self.processado? && self.insuficiencia_de_saldo_financeiro?) || (self.nao_processado? && self.valores_e_ou_inscricoes_indevidas?)
			errors.add(:motivo, "O Motivo selecionado não é válido para esse tipo de Restos a Pagar.")
		end
	end

	def atribui_codigo_disponivel
		gerar_codigo(data, :numero, :data, :orcamento_id, self.orcamento_id)
	end
end
