require 'active_support/concern'
require 'aasm'
module VistoriavelContratosConcern
	extend ActiveSupport::Concern

	included do
		include AASM
		include MensagemConcern
		has_many :vistos, as: :vistoriavel, class_name: "Controladoria::Visto"

		aasm column: :status, enum: true, whiny_transitions: false do
			state :aberto, :initial => true
			state :enviado_para_controladoria
			state :enviado_para_copfin
			state :confirmado
			state :enviado_para_licitacao
			state :cancelado
			state :fechado

			event :enviar_projeto_basico_para_controladoria do
				transitions from: :aberto, to: :enviado_para_controladoria do
					guard do
						(vistos.copfin.empty? || reprovado_pela_controladoria?) && Configuracao.last.envia_documentos_para_controladoria? && possui_ata? && dotacoes_batem_com_valor_do_contrato?
					end
				end
			end

			event :enviar_para_controladoria do
				transitions from: :aberto, to: :enviado_para_controladoria do
					guard do
						Configuracao.last.envia_documento_para_controladoria? && !possui_ata? && dotacoes_batem_com_valor_do_contrato?
					end
				end
			end

			event :retornar_para_licitacao do
				transitions from: :enviado_para_controladoria, to: :aberto do
					guard do
						reprovado_pela_controladoria? && vistos.count > 0
					end
				end
			end

			event :enviar_para_copfin do
				transitions from: :enviado_para_controladoria, to: :enviado_para_copfin do
					guard do
						aprovado_pela_controladoria? && Configuracao.last.envia_documentos_para_copfin? && possui_ata?
					end
				end
			end

			event :retornar_para_licitacao_do_copfin do
				transitions from: :enviado_para_copfin, to: :aberto do
					guard do
						reprovado_pelo_copfin? && vistos.copfin.count > 0
					end
				end
			end

			event :retornar_pra_copfin do
				transitions from: :aberto, to: :enviado_para_copfin do
					guard do
						Configuracao.last.envia_documentos_para_copfin? && (vistos.copfin.count == 0  || reprovado_pelo_copfin?)
					end
				end
			end

			event :enviar_para_licitacao do
				transitions from: :enviado_para_controladoria, to: :enviado_para_licitacao do
					guard do
						aprovado_pela_controladoria? && !Configuracao.last.envia_documentos_para_copfin?
					end
				end
				transitions from: :enviado_para_copfin, to: :enviado_para_licitacao do
					guard do
						aprovado_pelo_copfin? && Configuracao.last.envia_documentos_para_copfin?
					end
				end
			end

			event :confirmar do
				transitions from: :aberto, to: :confirmado do
					guard do
						self.esta_solicitado? && ((valor_dos_itens_igual_ao_total_do_contrato? && !self.discriminacao_obrigatoria_de_itens?) || self.discriminacao_obrigatoria_de_itens?) && tem_itens? && dotacoes_batem_com_valor_do_contrato? && ata_de_registro_de_precos.present? && possui_numero_e_data_de_vigencia? &&
							(!Configuracao.last.envia_documentos_para_controladoria? || ((aprovado_pela_controladoria? || aprovado_pelo_copfin?) && (Configuracao.last.envia_documentos_para_controladoria? || Configuracao.last.envia_documentos_para_copfin?))) && ((!self.projeto.parceria_osc? && self.fiscais_do_contrato.where(ativo: true).last&.present?) || self.projeto.parceria_osc?)
					end
				end
				transitions from: :enviado_para_licitacao, to: :confirmado do
					guard do
						self.esta_solicitado? && (aprovado_pela_controladoria? || aprovado_pelo_copfin?) && dotacoes_batem_com_valor_do_contrato? && possui_numero_e_data_de_vigencia? && ((!self.projeto.parceria_osc? && self.fiscais_do_contrato.where(ativo: true).last&.present?) || self.projeto.parceria_osc?)
					end
				end
			end

			event :fechar do
				transitions from: :confirmado, to: :fechado do
					guard do
						if self.projeto.registro_de_preco?
							((valor_dos_itens_igual_ao_total_do_contrato? && !self.discriminacao_obrigatoria_de_itens?) || self.discriminacao_obrigatoria_de_itens?) && tem_itens? && (confirmado? && ata_de_registro_de_preco_id.present? && data_do_contrato.present?) && (!self.envia_pro_sim? || self.envia_pro_sim? && !self.data_de_envio_pro_sim.blank? && self.data_de_envio_pro_sim_valida?) && dotacoes_batem_com_valor_do_contrato?
						else
							((valor_dos_itens_igual_ao_total_do_contrato? && !self.discriminacao_obrigatoria_de_itens?) || self.discriminacao_obrigatoria_de_itens?) && tem_itens? && (confirmado? && data_do_contrato.present?) && (!self.envia_pro_sim? || self.envia_pro_sim? && !self.data_de_envio_pro_sim.blank? && self.data_de_envio_pro_sim_valida?) && dotacoes_batem_com_valor_do_contrato?
						end
					end
				end
				transitions from: :aberto, to: :fechado do
					guard do
						((valor_dos_itens_igual_ao_total_do_contrato? && !self.discriminacao_obrigatoria_de_itens?) || self.discriminacao_obrigatoria_de_itens?) && tem_itens? && ata_de_registro_de_preco_id.blank? && tem_dotacao? && (!self.envia_pro_sim? || self.envia_pro_sim? && !self.data_de_envio_pro_sim.blank? && self.data_de_envio_pro_sim_valida?) && dotacoes_batem_com_valor_do_contrato? && Configuracao.last.envia_documento_para_controladoria? == false && ((!self.projeto.parceria_osc? && self.fiscais_do_contrato.where(ativo: true).last&.present?) || self.projeto.parceria_osc?)
					end
				end

				after do
					fechamento_de_contrato self
				end
			end

			event :cancelar do
				transitions to: :cancelado
			end

			event :retornar_para_aberto do
				transitions to: :aberto do
					guard do
						!cancelado? && !tem_empenhos? && !tem_aditivos? && arquivo_id.nil? && ((self.contrato_de_obras? && obra.nil?) || !self.contrato_de_obras?)
					end
				end
			end
		end
	end

		def reprovado_pela_controladoria?
			!aprovado_pela_controladoria?
		end

		def reprovado_pelo_copfin?
			!aprovado_pelo_copfin?
		end

		def aprovado_pela_controladoria?
			vistos.controladoria.any? && vistos.controladoria.last.aprovado?
		end

		def possui_numero_e_data_de_vigencia?
			numero.present? && self.inicio_da_vigencia.present? && self.fim_da_vigencia.present?
		end

		def falta_preechimento_de_dados?
			!numero.present? || !self.inicio_da_vigencia.present? || !self.fim_da_vigencia.present?
		end

		def possui_ata?
			ata_de_registro_de_preco_id.present?
		end

		def aprovado_pelo_copfin?
			vistos.copfin.any? && vistos.copfin.last.aprovado?
		end

		def pode_criar_mais_vistos?
			vistos.empty? || vistos.last.created_at < self.updated_at
		end

		def contrato_confirmado?
			contrato.confirmado? || contrato.fechado?
		end

		def envia_pro_copfin?
			Configuracao.last.comite_programacao_financeira?
		end
end
