class Pncp::WebserviceController < ApplicationController
	skip_before_action :verify_authenticity_token

	@@authorization_token = nil

	# Acessando as configurações em qualquer lugar do seu aplicativo
	@@login = Rails.application.config.properties['login']
	@@senha = Rails.application.config.properties['senha']
	@@base_url = Rails.application.config.properties['base_url']
	@@usuario_pncp = Rails.application.config.properties['usuario_pncp']

	def auth
		login = {login: "#{@@login}",senha: "#{@@senha}"}
		begin
			response = RestClient::Request.new(
				method: :post,
				url: "#{@@base_url}/usuarios/login",
				payload: "#{login.to_json()}",
				headers: {  
					"Accept"=>"*/*",
					"Content-Type"=>"application/json"
				}
			).execute do |response, request, result|
				case response.code
				when 200
					
					@@authorization_token = response.headers[:authorization]
					return true
				else
					conteudo = JSON.parse(response.body)
					return false
				end
			end
		rescue Exception => e
			return false
		end
	end

	def atualizar_unidades
		@unidades =	Loa::UnidadeGestora.joins('inner join pncp_orgaos_pncp on pncp_orgaos_pncp.id = loa_unidades_gestoras.orgao_pncp_id').where('loa_unidades_gestoras.enviado_pncp = false or loa_unidades_gestoras.enviado_pncp is null').all	
		@unidades.each do |uni|
			verifica_unidade(uni)
		end
		
		@unidades.each do |uni|
			@envia_unidade = self.unidade_json(uni)
			self.envia_unidade(uni)
		end
		redirect_to loa_unidades_gestoras_path(contexto_atual)
	end

	def atualizar_orgaos
		
		@orgaos = Pncp::OrgaoPncp.where('enviado_pncp is not true').all
		@orgaos.each do |orgao|
			@envia_orgao = self.orgao_json(orgao)
			
			self.envia_orgao(orgao)
			
		end
	end

	def atualizar_contratos
		alerta = nil
		@contratos = Licitacao::Contrato.where("enviar_para_pncp = true AND enviado_pncp != true AND compra_cnpj IS NOT NULL AND compra_ano IS NOT NULL AND compra_sequencial IS NOT NULL").all
		@contratos.each do |contr|
			@envia_contrato = contr
			contrato = self.contrato_json(contr)
			self.inserir_contrato(contrato) 
		end
		redirect_to licitacao_envios_pncp_path
	end

	def envia_aditivos
		alerta = nil
		@aditivos = Licitacao::Aditivo.where("enviar_para_pncp IS TRUE AND enviado_pncp IS NOT TRUE").all
		@aditivos.each do |adit|
			@envia_aditivo = adit
			aditivo = self.aditivo_json(adit)
			self.inserir_aditivo(adit)
		end
		redirect_to licitacao_envios_pncp_aditivos_path
	end

	def atualizar_documentos_do_contrato
		@documentos = Licitacao::DocumentoDoContrato.all.joins(:contrato).where("licitacao_documentos_do_contrato.enviar_para_pncp = true AND licitacao_documentos_do_contrato.enviado_para_o_pncp is not true and licitacao_contratos.enviado_pncp = true")
		@documentos.each do |doc_do_contrato|
			@envia_documento = doc_do_contrato
			documento_do_contrato = self.documento_do_contrato_json(doc_do_contrato)
			self.inserir_documento_do_contrato(documento_do_contrato)
		end
		redirect_to licitacao_envios_pncp_path
	end

	def atualizar_documentos_do_aditivo
		@documentos = Licitacao::DocumentoDoAditivo.all.joins(:aditivo).where("licitacao_documentos_do_aditivo.enviar_para_pncp = true AND licitacao_documentos_do_aditivo.enviado_para_o_pncp is not true and licitacao_aditivos.enviado_pncp = true")
		@documentos.each do |doc_do_aditivo|
			self.inserir_documento_do_aditivo(doc_do_aditivo)
		end
		redirect_to licitacao_envios_pncp_aditivos_path
	end

	def atualizar_documentos_da_ata
		@documentos = Licitacao::DocumentoDaAta.joins(:ata_de_registro_de_precos).where("licitacao_documentos_da_ata.enviar_para_pncp IS TRUE AND enviado_para_o_pncp IS NOT TRUE AND enviado_pncp IS TRUE").distinct.all
		@documentos.each do |doc_da_ata|
			@documento_da_ata = doc_da_ata
			documento_da_ata = self.documento_da_ata_json(doc_da_ata)
			self.inserir_documento_da_ata(documento_da_ata)
		end
		redirect_to licitacao_envios_pncp_atas_path
	end

	def envia_acoes
		@acoes = Pca::Acao.where("status = ? AND (enviado_pncp = ? OR enviado_pncp IS null) AND EXTRACT(YEAR FROM data_de_previsao_da_contratacao) = ?", Pca::Acao.status[:fechado], false, params[:ano].to_i)
		resposta = Array.new
		@acoes_agrupada = @acoes.group_by{|a| a.unidade_orcamentaria.unidade_gestora}
		@acoes_agrupada.each do |unidade, acao|
			@envia_acao = acao
			acao_to_pncp = self.acao_json(acao)
			resposta.push(self.inserir_acao(acao_to_pncp))
		end
		redirect_to pca_envios_pncp_path
	end

	def envia_atas
		adicionar_entidades
		alerta = nil
		Licitacao::AtaDeRegistroDePrecos.where("enviar_para_pncp = true AND enviado_pncp IS NOT TRUE AND compra_cnpj IS NOT NULL AND compra_ano IS NOT NULL AND compra_sequencial IS NOT NULL").each do |ata|
			@ata = ata
			ata_json = self.ata_json(ata)
			self.inserir_ata(ata_json)
		end
		redirect_to licitacao_envios_pncp_atas_path
	end

	def exclui_acao(acao=nil)
		if acao.present? || acao.nil? && params[:id].present?
			acao = acao.nil? ? Pca::Acao.find(params[:id]) : acao
			if self.auth()
				begin
					sequencial_acao = acao.url_pncp.match(%r{/(\d+)$})[1]
					response = HTTParty.delete(
						"#{@@base_url}/orgaos/#{acao.cnpj_pncp}/pca/#{acao.try(:data_de_previsao_da_contratacao).try(:year)}/#{sequencial_acao}",
						headers: {
							"Accept" => "*/*",
							"Content-Type" => "application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					)

					case response.code
					when 200
						acoes_para_reenviar = Pca::Acao.where(url_pncp: acao.url_pncp)
						acoes_para_reenviar.each do |acao|
							acao.enviado_pncp = false
							acao.envia_pncp = true
							acao.justificativa_para_exclusao_pncp = "Atualização PCA"
							acao.url_pncp = nil
							acao.save(validate: false)
						end
					else
						conteudo = JSON.parse(response.body)
						alerta = conteudo["erros"].map{ |e| e["mensagem"].to_s }.join(', ') + "[Ação: #{acao.map(&:id)}]" rescue nil
						alerta = alerta.nil? ? conteudo["message"] : alerta
						render plain: alerta, status: :bad_request
					end
				rescue Exception => e
					render plain: e.message, status: :internal_server_error
				end
			end
		end
	end

	def adicionar_entidades
		if self.auth()
			orgaos_json = Pncp::OrgaoPncp.where('enviado_pncp = true').map{|a| a[:cnpj]}.join(", ")
			begin
				response = RestClient::Request.new(
					method: :put,
					url: "#{@@base_url}/usuarios/#{@@usuario_pncp}",
					payload: "{'entesAutorizados': [#{orgaos_json}]}",
					headers: {  
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}" 
					}
				).execute do |response, request, result|				
					case response.code
					when 200
						org.autorizado_pncp = true
						org.save(validate: false)
					end
				end
			rescue Exception => e
				return e 
			end
		end
	end

	def envia_orgao(org)
		if self.auth()
			begin
				response = RestClient::Request.new(
					method: :post,
					url: "#{@@base_url}/orgaos",
					payload: "#{@envia_orgao.to_json}",
					headers: {  
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}" 
					}
				).execute do |response, request, result|
					case response.code
					when 201
						org.enviado_pncp = true
						org.location_url = response.headers[:location]
						org.updated_at = Date.today
						
						org.save(validate: false)
					else
						conteudo = JSON.parse(response.body)
						alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Orgão: #{org[:razao_social].to_s}]" rescue nil
						alerta = alerta.nil? ? conteudo["message"] + "[Orgão: #{org[:razao_social].to_s}]" : alerta
						redirect_to pncp_orgaos_pncp_path, flash: { alert: alerta }
					end
				end
			rescue Exception => e
				return e 
			end
		end
	end

	def verifica_unidade(uni)
    if auth()
      begin
        response = RestClient::Request.execute(
          method: :get,
          url: "#{@@base_url}/orgaos/#{uni.orgao_pncp.cnpj}/unidades/#{uni.codigo_to_pncp}"
        )
				
        case response.code
        when 200
          uni.enviado_pncp = true
          uni.save(validate: false)

        end
			rescue Exception => e
				return e
      end
    end
  end

	def envia_unidade(uni)
		
		if self.auth()
			
			begin
				response = RestClient::Request.new(
					method: :post,
					url: "#{@@base_url}/orgaos/#{uni.orgao_pncp.cnpj}/unidades",
					payload: "#{@envia_unidade.to_json()}",
					headers: {  
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}"
					}
				).execute do |response, request, result|
					
					case response.code
					when 201
						uni.enviado_pncp = true
						uni.updated_at = Date.today
						
						org.save(validate: false)
					else
						conteudo = JSON.parse(response.body)
						alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Unidade: #{uni[:nome].to_s}]" rescue nil
						alerta = alerta.nil? ? conteudo["message"] + "[Unidade: #{[:nome].to_s}]" : alerta
						redirect_to loa_unidades_gestoras_path, flash: { alert: alerta }
					end
				end
			rescue Exception => e
				return e 
			end
		end
	end

	def inserir_contrato(contrato)
		if self.auth()
			begin
				response = RestClient::Request.new(
					method: :post,
					url: "#{@@base_url}/orgaos/#{contrato[:cnpj]}/contratos",
					payload: "#{contrato.to_json()}",
					headers: {
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}" 
					}
				).execute do |response, request, result|
					case response.code
					when 201
						@envia_contrato.update_columns(
							enviado_pncp: true,
							pncp_data_cadastro: DateTime.now,
							pncp_id: JSON.parse(RestClient.get(result[:location], headers: { "Authorization" => "#{@@authorization_token}"}))['numeroControlePNCP'].delete('-/'),
							url_pncp: "#{@@base_url.match(%r{^(https?://[^/]+)})[1]}/app/contratos/#{contrato[:cnpj]}/#{contrato[:anoContrato]}/#{result[:location].match(%r{/(\d+)$})[1]}"
						)
					else
						conteudo = JSON.parse(response.body)
						alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Contrato: #{contrato[:numeroContratoEmpenho].to_s}]" rescue nil
						alerta = alerta.nil? ? conteudo["message"] + "[Contrato: #{contrato[:numeroContratoEmpenho].to_s}]" : alerta
						Pncp::CriticasDeEnvio.create(modulo: @envia_contrato, descricao: alerta)
					end
					return response.code if response.present?
				end
			rescue Exception => e
				return e
			end
		end
	end

	def inserir_aditivo(aditivo)
		if self.auth()
			begin
				contrato = aditivo.contrato
				cnpj_orgao = contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj

				response = RestClient::Request.new(
					method: :post,
					url: "#{@@base_url}/orgaos/#{cnpj_orgao}/contratos/#{contrato.data_do_contrato.year}/#{contrato.url_pncp.match(%r{/(\d+)$})[1]}/termos",
					payload: "#{aditivo_json(aditivo).to_json()}",
					headers: {
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}"
					}
				).execute do |response, request, result|
					case response.code
					when 201
						aditivo.update_columns(
							enviado_pncp: true,
							pncp_data_cadastro: DateTime.now,
							url_pncp: "#{@@base_url.match(%r{^(https?://[^/]+)})[1]}/app/contratos/#{cnpj_orgao}/#{contrato.data_do_contrato.year}/#{contrato.url_pncp.match(%r{/(\d+)$})[1]}/termos/#{result[:location].match(%r{/(\d+)$})[1]}"
						)
					else
						conteudo = JSON.parse(response.body)
						alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Aditivo: #{contrato.numero}#{aditivo.numero.digitos(2)}]" rescue nil
						alerta = alerta.nil? ? conteudo["message"] + "[Aditivo: #{contrato.numero}#{aditivo.numero.digitos(2)}]" : alerta
						Pncp::CriticasDeEnvio.create(modulo: aditivo, descricao: alerta)
					end
					return response.code if response.present?
				end
			rescue Exception => e
				return e
			end
		end
	end

	def exclui_contratos(contrato=nil)
		if contrato.present? || (contrato.nil? && params[:id].present?)
			contrato = Licitacao::Contrato.find(params[:id]) if (contrato.nil? && params[:id].present?)
			if auth()
				begin
					cnpj_orgao = contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj
					id_sequencial = contrato.url_pncp.match(%r{/(\d+)$})[1]
					response = RestClient::Request.execute(
						method: :delete,
						url: "#{@@base_url}/orgaos/#{cnpj_orgao}/contratos/#{contrato.data_do_contrato.try(:year)}/#{id_sequencial}",
						headers: {
							"Accept"=>"*/*",
							"Content-Type"=>"application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					)
					case response.code
					when 200
						contrato.update_columns(enviado_pncp: false, pncp_id: nil, url_pncp: nil)
						contrato.documentos_do_contrato.where(enviado_para_o_pncp:true).each{|doc| doc.update_column(:enviado_para_o_pncp, false)}
						alerta = "Contrato excluido do PNCP"
					end
				rescue Exception => e
					return e
				end
			end
			redirect_to contrato, alert: alerta
		end
	end

	def exclui_aditivo(aditivo = nil)
		if aditivo.present? || aditivo.nil? && params[:id].present?
			aditivo = aditivo.nil? ? Licitacao::Aditivo.find(params[:id]) : aditivo
			if auth()
				begin
					contrato = aditivo.contrato
					cnpj_orgao = contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj
					id_sequencial_contrato = contrato.url_pncp.match(%r{/(\d+)$})[1]
					id_sequencial_aditivo = aditivo.url_pncp.match(%r{/(\d+)$})[1]

					response = RestClient::Request.execute(
						method: :delete,
						url: "#{@@base_url}/orgaos/#{cnpj_orgao}/contratos/#{contrato.data_do_contrato.try(:year)}/#{id_sequencial_contrato}/termos/#{id_sequencial_aditivo}",
						headers: {
							"Accept"=>"*/*",
							"Content-Type"=>"application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					)
					case response.code
					when 200
						aditivo.update_columns(enviado_pncp: false, pncp_id: nil, url_pncp: nil)
						alerta = "Aditivo excluido do PNCP"
					end
				rescue Exception => e
					return e
				end
				redirect_to licitacao_aditivo_path(aditivo), alert: alerta
			end
		end
	end

	def inserir_acao(acao)
		if self.auth()
			begin
				response = RestClient::Request.new(
					method: :post,
					url: "#{@@base_url}/orgaos/#{@envia_acao.first.cnpj_pncp}/pca",
					payload: "#{acao.to_json()}",
					headers: {
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}"
					}
				).execute do |response, request, result|
					case response.code
					when 201
						@envia_acao.each do |acao_atual|
							acao_atual[:enviado_pncp] = true
							acao_atual[:pncp_data_cadastro] = DateTime.now
							acao_atual.url_pncp = "#{@@base_url.match(%r{^(https?://[^/]+)})[1]}/app/pca/#{@envia_acao.first.unidade_orcamentaria.unidade_gestora.orgao_pncp.cnpj}/#{acao_atual.try(:data_de_previsao_da_contratacao).try(:year)}/#{result[:location].match(%r{/(\d+)$})[1]}"
							acao_atual.save(validate: false)
						end
					else
						conteudo = JSON.parse(response.body)
						if conteudo["message"] == "PCA já existe para a unidade órgão"
							@envia_acao = Pca::Acao.joins(unidade_orcamentaria: :unidade_gestora).where('status = ? AND EXTRACT(YEAR FROM data_de_previsao_da_contratacao) = ? AND loa_unidades_gestoras.id = ?', Pca::Acao.status[:fechado], @envia_acao.first.data_de_previsao_da_contratacao.year, @envia_acao.first.unidade_orcamentaria.unidade_gestora_id)
							self.exclui_acao(@envia_acao.where.not(url_pncp: nil).first)
							sleep(5)
							self.inserir_acao(self.acao_json(@envia_acao))
						elsif conteudo["message"] == "could not execute statement; SQL [n/a]; constraint [planocontratacaoitem_uk_negocio]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
							system("rake pca:adiciona_sequencial_no_item_da_acao_por_ug_e_exercicio #{@envia_acao.first.data_de_previsao_da_contratacao.year} #{@envia_acao.first.unidade_orcamentaria.unidade_gestora_id}")
							ActiveRecord::Base.connection.reconnect!
							@envia_acao.each(&:reload)
							self.inserir_acao(self.acao_json(@envia_acao))
						end
					end
					alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Ação: #{acao.map(&:id)}]" rescue nil
					alerta = alerta.nil? ? conteudo["message"] : alerta
					return alerta
				end
			rescue Exception => e
				return e
			end
		end
	end

	def inserir_ata(ata)
		if self.auth()
			begin
				response = RestClient::Request.new(
					method: :post,
					url: "#{@@base_url}/orgaos/#{ata[:cnpj]}/compras/#{ata[:anoCompra]}/#{ata[:sequencialCompra]}/atas",
					payload: "#{ata.to_json()}",
					headers: {
						"Accept"=>"*/*",
						"Content-Type"=>"application/json",
						"Authorization" => "#{@@authorization_token}"
					}
				).execute do |response, request, result|

					case response.code
					when 201
						@ata.update_columns(
							enviado_pncp: true,
							pncp_data_cadastro: DateTime.now,
							pncp_id: JSON.parse(RestClient.get(result[:location], headers: { "Authorization" => "#{@@authorization_token}"}))['numeroControlePNCP'].delete('-/'),
							url_pncp: "#{@@base_url.match(%r{^(https?://[^/]+)})[1]}/app/atas/#{ata[:cnpj]}/#{ata[:anoCompra]}/#{ata[:sequencialCompra]}/#{result[:location].match(%r{/(\d+)$})[1]}"
						)
					else
						conteudo = JSON.parse(response.body)
						alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Ata: #{ata[:numeroAtaRegistroPreco].to_s}]" rescue nil
						alerta = alerta.nil? ? conteudo["message"] + "[Ata: #{ata[:numeroAtaRegistroPreco].to_s}]" : alerta
						Pncp::CriticasDeEnvio.create(modulo: @ata, descricao: alerta)
					end
					return response.code if response.present?
				end
			rescue Exception => e
				return e
			end
		end
	end

	def retifica_ata(ata)
		if ata.present? || ata.nil? && params[:id].present?
			ata = ata.nil? ? Licitacao::AtaDeRegistroDePrecos.find(params[:id]) : ata
			alerta = "Não foi possivel atualizar a Ata"
			if self.auth()
				begin
					id_sequencial = ata.url.match(%r{/(\d+)$})[1]
					response = RestClient::Request.new(
						method: :put,
						url: "#{@@base_url}/orgaos/#{ata[:cnpj]}/compras/#{ata[:anoCompra]}/#{ata[:sequencialCompra]}/atas/#{id_sequencial}",
						payload: "#{ata.to_json()}",
						headers: {
							"Accept"=>"*/*",
							"Content-Type"=>"application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					).execute do |response, request, result|

						case response.code
						when 201
							@ata.update_columns(
								enviado_pncp: true,
								pncp_data_cadastro: DateTime.now,
								pncp_id: JSON.parse(RestClient.get(result[:location], headers: { "Authorization" => "#{@@authorization_token}"}))['numeroControlePNCP'].delete('-/'),
								url_pncp: "#{@@base_url.match(%r{^(https?://[^/]+)})[1]}/app/atas/#{ata[:cnpj]}/#{ata[:anoCompra]}/#{ata[:sequencialCompra]}/#{result[:location].match(%r{/(\d+)$})[1]}"
							)
						else
							conteudo = JSON.parse(response.body)
							alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Ata: #{ata[:numeroAtaRegistroPreco].to_s}]" rescue nil
							alerta = alerta.nil? ? conteudo["message"] + "[Ata: #{ata[:numeroAtaRegistroPreco].to_s}]" : alerta
							Pncp::CriticasDeEnvio.create(modulo: @ata, descricao: alerta)
						end
						return response.code if response.present?
					end
				rescue Exception => e
					return e
				end
			end
		end
	end

	def exclui_ata(ata=nil)
		if ata.present? || ata.nil? && params[:id].present?
			ata = ata.nil? ? Licitacao::AtaDeRegistroDePrecos.find(params[:id]) : ata
			alerta = "Não foi possivel excluir do PNCP"
			if auth()
				begin
					id_sequencial = ata.url_pncp.match(%r{/(\d+)$})[1]
					response = RestClient::Request.execute(
						method: :delete,
						url: "#{@@base_url}/orgaos/#{ata.compra_cnpj}/compras/#{ata.compra_ano}/#{ata.compra_sequencial}/atas/#{id_sequencial}",
						headers: {
							"Accept"=>"*/*",
							"Content-Type"=>"application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					)
					case response.code
					when 200
						ata.update_columns(enviado_pncp: false, pncp_id: nil, url_pncp: nil)
						alerta = "Ata excluida do PNCP"
					end
				rescue Exception => e
					return e
				end
			end
			redirect_to licitacao_ata_de_registro_de_precos_path(ata), alert: "#{alerta}"
		end
	end

	def consulta_ata()

	end

	def inserir_documento_do_contrato(doc_do_contrato)
		if self.auth()
			begin
				arquivo_pdf = Tempfile.new(['doc_do_contrato', '.pdf'], encoding: 'ASCII-8BIT')

				if @envia_documento.texto.present?
					pdf = WickedPdf.new.pdf_from_string(@envia_documento.texto)
					arquivo_pdf.write(pdf)
					arquivo_pdf.rewind
					arquivo = arquivo_pdf
				else
					s3_url = @envia_documento.documento.url
					s3_file = open(s3_url)
					arquivo = Tempfile.new(['doc_do_contrato', '.pdf'], encoding: 'ASCII-8BIT')
					arquivo.write(s3_file.read)
					arquivo.rewind
				end

				sequencial_contrato = @envia_documento.contrato.url_pncp.match(%r{/(\d+)$})[1]
				cnpj = @envia_documento.contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj
				ano_contrato = @envia_documento.contrato.data_do_contrato.year
				titulo_documento= @envia_documento.titulo_personalizado.parameterize(separator: ' ').gsub(/[^A-Za-z0-9 ]/, '').upcase

				response = HTTParty.post(
					"#{@@base_url}/orgaos/#{cnpj}/contratos/#{ano_contrato}/#{sequencial_contrato}/arquivos",
					body: {
						arquivo: arquivo
					},
					headers: {
						"Accept"=>"*/*",
						"Content-Type"=>"multipart/form-data",
						"Authorization" => "#{@@authorization_token}",
						"Titulo-Documento" => "#{titulo_documento}",
						"Tipo-Documento-Id" => "#{doc_do_contrato[:tipo_documento_id]}"
					}
				)

				arquivo.close
				arquivo_pdf.unlink if @envia_documento.texto.present?

				case response.code
				when 201
					@envia_documento.update_columns(
						enviado_para_o_pncp: true,
						pncp_data_cadastro: DateTime.now,
						url_pncp: response[:location]
					)
				else
					conteudo = JSON.parse(response.body)
					alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Documento: #]" rescue nil
					alerta = alerta.nil? ? conteudo["message"] : alerta
					Pncp::CriticasDeEnvio.create(modulo: @envia_documento, descricao: alerta)
				end
				return response.code if response.present?
			rescue Exception => e
				return e
			end
		end
	end

	def inserir_documento_do_aditivo(doc_do_aditivo)
		if self.auth()
			begin
				arquivo_pdf = Tempfile.new(['doc_do_aditivo', '.pdf'], encoding: 'ASCII-8BIT')

				if doc_do_aditivo.texto.present?
					pdf = WickedPdf.new.pdf_from_string(doc_do_aditivo.texto)
					arquivo_pdf.write(pdf)
					arquivo_pdf.rewind
					arquivo = arquivo_pdf
				else
					s3_url = doc_do_aditivo.documento.url
					s3_file = open(s3_url)
					arquivo = Tempfile.new(['doc_do_aditivo', '.pdf'], encoding: 'ASCII-8BIT')
					arquivo.write(s3_file.read)
					arquivo.rewind
				end

				sequencial_contrato = doc_do_aditivo.aditivo.contrato.url_pncp.match(%r{/(\d+)$})[1]
				sequencial_aditivo = doc_do_aditivo.aditivo.url_pncp.match(%r{/(\d+)$})[1]
				cnpj = doc_do_aditivo.aditivo.contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj
				ano_contrato = doc_do_aditivo.aditivo.contrato.data_do_contrato.year
				titulo_documento= doc_do_aditivo.titulo_personalizado.parameterize(separator: ' ').gsub(/[^A-Za-z0-9 ]/, '').upcase
				tipo_documento = doc_do_aditivo.tipo_de_documento == "aditivo" ? 14 : ""

				response = HTTParty.post(
					"#{@@base_url}/orgaos/#{cnpj}/contratos/#{ano_contrato}/#{sequencial_contrato}/termos/#{sequencial_aditivo}/arquivos",
					body: {
						arquivo: arquivo
					},
					headers: {
						"Accept"=>"*/*",
						"Content-Type"=>"multipart/form-data",
						"Authorization" => "#{@@authorization_token}",
						"Titulo-Documento" => "#{titulo_documento}",
						"Tipo-Documento-Id" => "#{tipo_documento}"
					}
				)

				arquivo.close
				arquivo_pdf.unlink if doc_do_aditivo.texto.present?

				case response.code
				when 201
					doc_do_aditivo.update_columns(enviado_para_o_pncp: true, pncp_data_cadastro: DateTime.now, url_pncp: response[:location])
				else
					conteudo = JSON.parse(response.body)
					alerta = conteudo["erros"].map{|e| e["mensagem"].to_s}.join(', ') + "[Documento: #]" rescue nil
					alerta = alerta.nil? ? conteudo["message"] : alerta
					Pncp::CriticasDeEnvio.create(modulo: doc_do_aditivo, descricao: alerta)
				end
				return response.code if response.present?
			rescue Exception => e
				return e
			end
		end
	end

	def exclui_documento_do_aditivo doc=nil
		if doc.present? || doc.nil? && params[:id].present?
			doc = doc.nil? ? Licitacao::DocumentoDoAditivo.find(params[:id]) : doc
			if auth()
				begin
					sequencial_contrato = doc.aditivo.contrato.url_pncp.match(%r{/(\d+)$})[1]
					sequencial_aditivo = doc.aditivo.url_pncp.match(%r{/(\d+)$})[1]
					cnpj = doc.aditivo.contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj
					ano_contrato = doc.aditivo.contrato.data_do_contrato.year
					id_sequencial = doc.url_pncp.match(%r{/(\d+)$})[1] rescue nil

					response = HTTParty.delete(
						"#{@@base_url}/orgaos/#{cnpj}/contratos/#{ano_contrato}/#{sequencial_contrato}/termos/#{sequencial_aditivo}/arquivos/#{id_sequencial}",
						headers: {
							"Accept" => "*/*",
							"Content-Type" => "application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					)
				rescue Exception => e
					return e
				end
			end
		end
	end

	def exclui_documento_do_contrato doc=nil
		if doc.present? || doc.nil? && params[:id].present?
			doc = doc.nil? ? Licitacao::DocumentoDoContrato.find(params[:id]) : doc
			alerta = "Não foi possivel excluir do PNCP"
			if auth()
				begin
					id_sequencial = doc.url_pncp.match(%r{/(\d+)$})[1]
					response = HTTParty.delete(
						"#{@@base_url}/orgaos/#{doc.contrato.compra_cnpj}/contratos/#{doc.contrato.compra_ano}/#{doc.contrato.compra_sequencial}/arquivos/#{id_sequencial}",
						headers: {
							"Accept" => "*/*",
							"Content-Type" => "application/json",
							"Authorization" => "#{@@authorization_token}"
						}
					)
				rescue Exception => e
					return e
				end
			end
		end
	end

	def inserir_documento_da_ata(doc_da_ata)
		if self.auth()
			begin
				arquivo_pdf = Tempfile.new(['doc_da_ata', '.pdf'], encoding: 'ASCII-8BIT')

				if @documento_da_ata.texto.present?
					pdf = WickedPdf.new.pdf_from_string(@documento_da_ata.texto)
					arquivo_pdf.write(pdf)
					arquivo_pdf.rewind
					arquivo = arquivo_pdf
				else
					s3_url = @documento_da_ata.documento.url
					s3_file = open(s3_url)
					arquivo = Tempfile.new(['doc_da_ata', '.pdf'], encoding: 'ASCII-8BIT')
					arquivo.write(s3_file.read)
					arquivo.rewind
				end

				cnpj = @documento_da_ata.ata_de_registro_de_precos.compra_cnpj
				ano_compra = @documento_da_ata.ata_de_registro_de_precos.compra_ano
				sequencial_compra = @documento_da_ata.ata_de_registro_de_precos.compra_sequencial
				sequencial_ata = @documento_da_ata.ata_de_registro_de_precos.url_pncp.match(%r{/(\d+)$})[1]
				titulo_documento = doc_da_ata[:titulo_documento].parameterize(separator: ' ').gsub(/[^A-Za-z0-9 ]/, '').upcase

				response = HTTParty.post(
					"#{@@base_url}/orgaos/#{cnpj}/compras/#{ano_compra}/#{sequencial_compra}/atas/#{sequencial_ata}/arquivos",
					body: {
						arquivo: arquivo
					},
					headers: {
						"Accept" => "*/*",
						"Titulo-Documento" => "#{titulo_documento}",
						"Tipo-Documento" => doc_da_ata[:tipo_documento_id].to_s,
						"Content-Type" => "multipart/form-data",
						"Authorization" => "#{@@authorization_token}"
					}
				)

				arquivo.close
				arquivo_pdf.unlink if @documento_da_ata.texto.present?

				case response.code
				when 201
					@documento_da_ata.update_columns(
						enviado_para_o_pncp: true,
						pncp_data_cadastro: DateTime.now,
						url_pncp: response.headers['location']
					)
				else
					conteudo = JSON.parse(response.body)
					alerta = conteudo["erros"].map { |e| e["mensagem"].to_s }.join(', ') rescue nil
					alerta = alerta.nil? ? conteudo["message"] : alerta
					Pncp::CriticasDeEnvio.create(modulo: @documento_da_ata, descricao: alerta)
				end

				return response.code if response.present?

			rescue Exception => e
				return e
			end
		end
	end

	def contrato_json(contrato)
		
		# liquidacao.empenho.unidade_orcamentaria.codigo_e_nome
		numero_do_processo = contrato.ata_de_registro_de_precos.present? ? contrato.ata_de_registro_de_precos.processo.numero_do_processo : contrato.projeto.numero_do_processo
		tipo_de_fornecedor = contrato.contratado.pessoa.pessoa_fisica? ? "PF" : "PJ"

		contatro_json = {
			cnpj: contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.orgao_pncp.cnpj,
			cnpjCompra: contrato.try(:compra_cnpj) , 
			anoCompra: contrato.try(:compra_ano),
			sequencialCompra: contrato.try(:compra_sequencial),
			tipoContratoId: contrato.read_attribute_before_type_cast(:tipo_contrato_pncp),
			numeroContratoEmpenho: contrato.try(:numero),
			anoContrato: contrato.data_do_contrato.try(:year),
			processo: numero_do_processo,
			categoriaProcessoId: contrato.read_attribute_before_type_cast(:tipo_processo_pncp),
			receita: false, # Lukas informou que os municiios possuem apenas contratos de despesas
			codigoUnidade: contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.try(:codigo_to_pncp),
			niFornecedor: contrato.try(:contratado).try(:pessoa).try(:cpf_ou_cnpj_sem_pontos),
			tipoPessoaFornecedor: tipo_de_fornecedor,
			nomeRazaoSocialFornecedor: contrato.try(:contratado).try(:pessoa).try(:nome),
				niFornecedorSubContratado: "",
				tipoPessoaFornecedorSubContratado: "",
				nomeRazaoSocialFornecedorSubContratado: "",
			objetoContrato: contrato.try(:objeto),
				informacaoComplementar: "",
			valorInicial: contrato.valor_do_contrato,
			numeroParcelas: contrato.quantidade_parcelas_pncp,
				valorParcela: contrato.valor_parcela_pncp,
			valorGlobal: contrato.valor_do_contrato,
				valorAcumulado: contrato.valor_do_contrato,
			dataAssinatura: contrato.try(:data_do_contrato),
			dataVigenciaInicio: contrato.try(:inicio_da_vigencia),
			dataVigenciaFim: contrato.try(:fim_da_vigencia)#,
				# identificadorCipi: "",
				# urlCipi: ""
		}
	end

	def aditivo_json(aditivo)
		tipo_de_fornecedor = aditivo.contrato.contratado.pessoa.pessoa_fisica? ? "PF" : "PJ"

		aditivo_json = {
			tipoTermoContratoId: 2,
			numeroTermoContrato: aditivo.numero,
			objetoTermoContrato: aditivo.objeto,
			dataAssinatura: aditivo.data_do_aditivo,
			qualificacaoAcrescimoSupressao: (aditivo.acrescimo? || aditivo.reducao?),
			qualificacaoVigencia: (aditivo.por_prazo?),
			qualificacaoFornecedor: false,
			qualificacaoReajuste: (aditivo.reajuste_de_valor_acrescimo? || aditivo.reajuste_de_valor_decrescimo?),
			qualificacaoInformativo: (aditivo.qualitativo? || aditivo.rescisao_contratual? || aditivo.alteracao_contratual? || aditivo.mudanca_de_item? || aditivo.nova_unidade_orcamentaria?),
			informativoObservacao: aditivo.justificativa,
			niFornecedor: nil,
			TipoPessoaFornecedor: nil,
			nomeRazaoSocialFornecedor: nil,
			niFornecedorSubContratado: nil,
			TipoPessoaFornecedorSubContratado: nil,
			nomeRazaoSocialFornecedorSubContratado: nil,
			fundamentoLegal: aditivo.legislacao.try(:titulo),
			valorAcrescido: (aditivo.acrescimo? || aditivo.reducao?) ? format("%.4f", aditivo.valor_total) : "0.0000",
			numeroParcelas: aditivo.quantidade_parcelas_pncp,
			valorParcela: format("%.4f", aditivo.valor_parcela_pncp),
			valorGlobal: format("%.4f", aditivo.valor_total),
			prazoAditadoDias: (aditivo.try(:inicio_da_vigencia).present? && aditivo.try(:fim_da_vigencia).present?) ? (aditivo.try(:fim_da_vigencia) - aditivo.try(:inicio_da_vigencia)).to_i : "",
			dataVigenciaInicio: aditivo.try(:inicio_da_vigencia),
			dataVigenciaFim: aditivo.try(:fim_da_vigencia)
		}
	end

	def acao_json(acao)
		acao_json = {
			cnpj: "#{acao.first.cnpj_pncp}",
			codigoUnidade: "#{acao.first.unidade_orcamentaria.unidade_gestora.try(:codigo_to_pncp)}",
			anoPca: "#{acao.first.try(:data_de_previsao_da_contratacao).try(:year)}",
			itensPlano: acao.flat_map(&:itens_to_pncp),
		}
	end

	def ata_json(ata)
		ata_json = {
			cnpj: ata.compra_cnpj,
			anoCompra: ata.compra_ano,
			sequencialCompra: ata.compra_sequencial,
			numeroAtaRegistroPreco: ata.numero,
			anoAta: ata.data_inicio_de_vigencia.try(:year),
			dataAssinatura: ata.data_da_assinatura,
			dataVigenciaInicio: ata.data_inicio_de_vigencia,
			dataVigenciaFim: ata.data_final_de_vigencia
		}
	end

	def retifica_contrato_json
		{
			cnpjOrgaoSubRogado: "",
			codigoUnidadeSubRogada: "",
			justificativa: "motivo/justificativa para a retificação do contrato"
		}
	end

	def excluir_contrato_json
		{
			justificativa: "motivo/justificativa para a retificação do contrato"
		}
	end

	def orgao_json(org)
		
		orgao = {
			cnpj: "#{org[:cnpj]}",
			razaoSocial: "#{org[:razao_social]}",
			poderId: Pncp::OrgaoPncp.poder_ids[org[:poder_id]], 
			esferaId: Pncp::OrgaoPncp.esfera_ids[org[:esfera_id]]
		}
	end

	def unidade_json(uni)
		unidade = {
			codigoIBGE: "#{Base::Cidade.find(Configuracao.last.cidade_id)&.codigo_ibge}",
			codigoUnidade: "#{uni.codigo_to_pncp}",
			nomeUnidade: "#{uni[:nome]}"
		}
	end

	def documento_do_contrato_json(doc_do_contrato)
		case doc_do_contrato.tipo_de_documento
		when "contrato"
			tipo_de_documento = 12
		when "termo_de_rescisao"
			tipo_de_documento = 13
		when "termo_aditivo"
			tipo_de_documento = 14
		when "termo_de_apostilamento"
			tipo_de_documento = 15
		when "nota_de_empenho"
			tipo_de_documento = 17
		when "relatorio_final_de_contrato"
			tipo_de_documento = 18
		when "outros_documentos"
			tipo_de_documento = 16
		end

		doc_do_contrato = {
			titulo_documento: doc_do_contrato.titulo_personalizado,
			tipo_documento_id: tipo_de_documento
		}
	end

	def documento_da_ata_json(doc_da_ata)
		if doc_da_ata.tipo_de_documento.present?
			tipo_de_documento = 11 if doc_da_ata.tipo_de_documento == "ata_de_registro_de_preco"
		end

		doc_da_ata = {
			titulo_documento: doc_da_ata.titulo_personalizado,
			tipo_documento_id: tipo_de_documento
		}
	end
end