require "net/http"
require "uri"
require "json"
namespace :portal_integration do
# Run tasks to update online portal endpoints 

	def onboard_client
		@onboard_client ||= SystemSetting.find_by(config_key: "CustomerPortalID")
	end

	def host_url
		@host_url = SystemSetting.find_by(config_key: "CustomerPortalURL")
	end
	
	desc "Test connection to the online portal"
	task :test_connection => :environment do 
		unless host_url.nil?
			puts("Connection to #{host_url&.config_value} successful")
		else
			puts("Connection failed!")
		end
	end

  	desc "post and update projects data and available stands"
  	task :projects => :environment do 

  		check_connected_host

  		url = SystemSetting.find_by(config_key: "CustomerPortalURL")
  		conn = Faraday.new(url: url.config_value)
  		@projects = Project.where(active: true)  
  		@projects.each_with_index do |project,i|
  			puts("****** dealing with #{project.name}")
			response = conn.post("/api/v1/interface/create_projects") do |req|
			  # req.headers["Authorization"] = "Bearer abc123"
			  req.body = {
			  	onboard_client: onboard_client.config_value,
			    name: project.name,
			    scope: project.scope,
			    location: project.location,
			    description: project.description
			  }
			end
			puts response.status
			# puts response.body
  		end
  		ClassCategory.all.each do |category|
			response = conn.post("/api/v1/interface/create_categories") do |req|
			  # req.headers["Authorization"] = "Bearer abc123"
			  req.body = {
			  	onboard_client: onboard_client.config_value,
			    name: category.name,
			    property_class: category.property_class.name,
			    description: category.description
			  }
			end
			puts response.status
  		end
  		GeneralPlan.all.each do |gp|
			response = conn.post("/api/v1/interface/create_general_plans") do |req|
			  # req.headers["Authorization"] = "Bearer abc123"
			  req.body = {
			  	onboard_client: onboard_client.config_value,
			    name: gp.name
			  }
			end
			puts response.status
  		end
  		PropertyDescription.all.each do |pd|
			response = conn.post("/api/v1/interface/create_property_descriptions") do |req|
			  # req.headers["Authorization"] = "Bearer abc123"
			  req.body = {
			  	onboard_client: onboard_client.config_value,
			    name: pd.name
			  }
			end
			puts response.status
  		end
  		PropertyUse.all.each do |pu|
			response = conn.post("/api/v1/interface/create_property_uses") do |req|
			  # req.headers["Authorization"] = "Bearer abc123"
			  req.body = {
			  	onboard_client: onboard_client.config_value,
			    name: pu.name
			  }
			end
			puts response.status
  		end
  	end

  	task :stands => :environment do 

  		check_connected_host

  		unless onboard_client
		  puts "CustomerPortalID not configured"
		  next
		end
  		url = SystemSetting.find_by(config_key: "CustomerPortalURL")
  		property_valuation = SystemSetting.find_by(config_key: "PropertyValuation")
  		conn = Faraday.new(url: url.config_value)
  		@projects = Project.where(id: 5) 
  		@projects.each_with_index do |project,i|
  			puts("******** dealing with #{project.name} - #{url.config_value}")
  			# check if the project exists
  			response = conn.get("/api/v1/interface/project") do |req|
  			  req.body = {
			  	name: project.name
			  }
			end
			x = 0
			if response.status == 200
				available_stands = project.stands.order(stand_number: :asc).where("active = true")
				# available_stands = project.stands.order(stand_number: :asc).where("stand_number = '33016'")
				unless available_stands.empty?
					available_stands.each do |stand|
						puts("*** #{x+=1} dealing with #{stand.stand_number}")
						response = conn.post("/api/v1/interface/create_stands") do |req|
						  req.body = {
						  	onboard_client: onboard_client.config_value,
						    property_number: stand.stand_number,
						    project: stand.project&.name,
						    size: stand.size,
						    price_psm: stand.price_psm,
						    sale_value: stand.size.to_f * stand.price_psm.to_f,
						    available: stand.available,
						    class_category: stand.class_category&.name,
						    property_class: stand&.class_category&.property_class&.name,
						    project_id: project.id,
						    to_sale: stand.to_sale,
						    tenure: stand.tenure,
						    property_use: stand.property_use&.name,
						    property_description: stand.property_description&.name,
						    status: stand.status,
						    stand_pricings: stand.stand_pricings.map do |pricing|
						      {
						        tenure: pricing.payment_period&.months,
						        price: pricing.price_psm,
						        deposit: stand.deposit,
						        sale_type: pricing.payment_period&.title
						      }
						    end
						  }
						end						
					end
				end
			end

  		end
  	end

  	task :customer_accounts => :environment do

  		check_connected_host  

  		unless onboard_client
		  puts "CustomerPortalID not configured"
		  next
		end
		customer_accounts = CustomerAccount.where(id: 4469)
		customer_accounts.each do |customer_account|
			puts("*** Dealing with #{customer_account.property_number} - #{customer_account.account_name}")
			customer = customer_account.customer
			puts("we are creating for #{customer},#{onboard_client.config_value}")
			begin
			  result = CustomerSyncService.new(customer,onboard_client.config_value).call

			  Rails.logger.info(
			    "Customer #{customer.id} synced successfully - Status: #{result[:status]}"
			  )

			  puts "=============================="
			  puts "SYNC SUCCESS"
			  puts "Customer ID: #{customer.id}"
			  puts "Status: #{result[:status]}"
			  # puts "Response: #{result[:body].inspect}"
			  puts "=============================="

			  sleep(0.2)

			rescue => e

			  Rails.logger.error(
			    "Customer #{customer.id} failed: #{e.message}"
			  )

			  puts "=============================="
			  puts "SYNC FAILED"
			  puts "Customer ID: #{customer.id}"
			  puts "Error: #{e.message}"
			  puts e.backtrace.first(10)
			  puts "=============================="

			end
		end
  	end
  	
  	task :transactions => :environment do 

  		check_connected_host

  		unless onboard_client
		  puts "CustomerPortalID not configured"
		  next
		end
  		url = SystemSetting.find_by(config_key: "CustomerPortalURL")
  		conn = Faraday.new(url: url.config_value)
  		@transactions = CustomerAccount.where(deleted: false)
  		@transactions.each_with_index do |transaction,i|
  			customer_account = CustomerAccount.find(transaction.customer_account_id)
  			puts("********* dealing with #{transaction.id} #{transaction.transaction_date} - #{transaction.amount} - #{transaction.debit}")
			if transaction.debit?
				response = conn.post("/api/v1/interface/create_invoices") do |req|
				  # req.headers["Authorization"] = "Bearer abc123"
				  req.body = {
				  	onboard_client: onboard_client.config_value,
				    customer_name: customer.customer_name,
				    project: customer_account.project.name,
				    property_number: customer_account.property_number,
				    deposit_amount: customer_account.deposit_amount,
				    property_size: customer_account.stand_size,
				    original_loan_amount: customer_account.original_loan_amount,
				    tenure: customer_account.number_of_years,
				    purchase_date: customer_account.registration_date,
				    contract_start_date: customer_account.contract_start_date,
				    contract_end_date: customer_account.contract_end_date,
				    agent_name: customer_account.agent.agent_name,
				    account_number: customer_account.account_number,
				    status: customer_account.status
				  }
				end 
			else
				response = conn.post("/api/v1/interface/create_receipts") do |req|
				  # req.headers["Authorization"] = "Bearer abc123"
				  req.body = {
				  	onboard_client: onboard_client.config_value,
				    customer_name: customer.customer_name,
				    project: customer_account.project.name,
				    property_number: customer_account.property_number,
				    deposit_amount: customer_account.deposit_amount,
				    property_size: customer_account.stand_size,
				    original_loan_amount: customer_account.original_loan_amount,
				    tenure: customer_account.number_of_years,
				    purchase_date: customer_account.registration_date,
				    contract_start_date: customer_account.contract_start_date,
				    contract_end_date: customer_account.contract_end_date,
				    agent_name: customer_account.agent.agent_name,
				    account_number: customer_account.account_number,
				    status: customer_account.status
				  }
				end 
			end
  		end
  	end

	desc "Sync reservations from Customer Portal"
	task sync_reservations: :environment do
		puts "Starting reservation sync..."

		SyncReservationsJob.perform_now

		puts "Reservation sync completed."
	end

	def tenant
		Tenant.find_by(tenant_uuid: 'ef582a79-1cc9-46f3-a123-1f63b6d2cfce')
	end

	def user
		ApiUser.find_by(email: 'david@dapsoft.co.zw')
	end

	desc "Export Projects"
	task export_projects: :environment do
	  uri = URI.parse("https://api.aibes.online/customer_portal/v2/properties/create_projects")
	  
	  projects = []

	  Project.find_each do |project|
	    puts "**** #{project.name}"

	      projects << {
	        project_name: project.name,
	        description: project.name,
	      }
	  end

	  http = Net::HTTP.new(uri.host, uri.port)

	  request = Net::HTTP::Post.new(uri.request_uri)
	  request["Content-Type"] = "application/json"
	  request["Accept"] = "application/json"
	  request["X-API-User-Email"] = 'david@dapsoft.co.zw'
	  request["X-Tenant-UUID"] = 'ef582a79-1cc9-46f3-a123-1f63b6d2cfce'

	  request.body = { :projects => projects }.to_json

	  response = http.request(request)

	  puts "Response: #{response.code}"
	  puts response.body
	end

	desc "Export available stands"
	task export_stands: :environment do
	  uri = URI.parse("https://api.aibes.online/customer_portal/v2/properties/create_stands")
	  
	  stands = []

	  Project.find_each do |project|
	    puts "**** #{project.name}"

	    project.stands.where(active: true, available: true, to_sale: true).where.not(size: [nil, 0]).find_each do |stand|
	      puts "******** #{stand.stand_number}"

	      stands << {
	        project_name: project.name,
	        property_number: stand.stand_number,
	        size: stand.size,
	        property_use: stand.property_use.try(:name),
	        property_description: stand.property_description.try(:name),
	        deposit: stand.deposit,
	        tenure: stand.tenure,
	        price_psm: stand.price_psm.to_f,
	        property_value: stand.sale_value.to_f,
	        status: "available",
	        active: stand.active
	      }
	    end
	  end

	  http = Net::HTTP.new(uri.host, uri.port)

	  request = Net::HTTP::Post.new(uri.request_uri)
	  request["Content-Type"] = "application/json"
	  request["Accept"] = "application/json"
	  request["X-API-User-Email"] = 'david@dapsoft.co.zw'
	  request["X-Tenant-UUID"] = 'ef582a79-1cc9-46f3-a123-1f63b6d2cfce'

	  request.body = { :stands => stands }.to_json

	  response = http.request(request)

	  puts "Response: #{response.code}"
	  puts response.body
	end

	desc "Export available stands"
	task create_document_requirements: :environment do
		id_doc_type = DocumentType.find_by(name: "National ID")
		residence_proof = DocumentType.find_by(name: "Proof of Residence")
		company_registration = DocumentType.find_by(name: "Company Registration")
		trust_deed = DocumentType.find_by(name: "Trust Deed")
		birth_certificate = DocumentType.find_by(name: "Birth Certificate")
		CustomerType.all.each do |ctype|
			case ctype.name 
			when 'Individual'
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: id_doc_type.id, applies_to: 'customer', age_scope: 'adult')
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: birth_certificate.id, applies_to: 'customer', age_scope: 'minor')			when 'Trust'
			when 'Joint Ownership'
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: id_doc_type.id, applies_to: 'representative', age_scope: 'adult')
			when 'Corporate'
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: company_registration.id)
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: id_doc_type.id, applies_to: 'representative', age_scope: 'adult')
			when 'Trust'
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: trust_deed.id)
				tenant.api_customer_type_document_types.create!(api_customer_type_id: ctype.id, document_type_id: id_doc_type.id, applies_to: 'representative', age_scope: 'adult')
			end
		end
	end

  	private

  	def check_connected_host
  		unless host_url.nil?
		     database = ActiveRecord::Base.connection_db_config.database
			puts("You are connected to #{host_url&.config_value} database #{database}")
		else
			puts("Connection failed!")
		end
		print "Would you like to continue? (y/n): "
		answer = STDIN.gets.chomp.downcase

		unless answer == "y"
			puts "Aborted by user."
			return
		end
  	end
end