#This class represents the scheduling manager container page. As need arises,
#other ruby class test pages representing different scheduling manager tabs
#could be created (e.g. booking, consults, vaac, wait list, etc.

require "rubygems"
require "selenium-webdriver"
require "./pages/utilities"
require "rspec"
require "page-object"
require "spec_helper"
require "./spec/spec_helper"

class SchedulingManager
  include PageObject

  @@BOOKING_BUTTON_LABEL = 'Booking'
  @@WAIT_LIST_BUTTON_LABEL = 'Wait List'
  @@CONSULTS_BUTTON_LABEL = 'Consults'
  @@VETERAN_REQUESTS_BUTTON_LABEL = 'Veteran Requests'
  @@MORE_BUTTON_LABEL = 'More'

  #page-object components. The name of the component is the first parameter, where to find the element on the page is the second parameter
  link(:about, :id => 'footer-about-btn')
  link(:more, :css => '#footer-more-btn > span.ui-btn-inner > span.ui-btn-text')

  button(:left_navigation_button, :id => 'left-navigation')
  div(:left_navigation_panel, :id => 'left-navigation-panel')

  link(:about_button, :id => 'portal-about-btn')
  link(:exit_button, :id => 'portal-exit-btn')

  div(:exit_popup, :id=>'exit-popup-popup')

  link(:veteran_requests_btn, :id => 'footer-veteran-requests-btn')
  link(:booking_btn, :id => 'footer-booking-btn')
  link(:footer_menu_popup_screen, :id => 'footer-menu-popup-screen')
  button(:appointment_button, :css => '#appointment-button .ok-button')
  button(:appointment_button_disabled, :css => '#appointment-button .ui-disabled')
  div(:patient_context, :xpath => '//*[@id="header"]/div/div/div')

  text_field(:patient_search_input, :xpath => '//*[@id="primary-search-filter"]/div/form/div/input')
  link(:patient_search_link, :css => '#patient-search > div > div > div > a')
  ul(:patient_search_results_ul, :id => 'patient-search-results')

  div(:about_content, :xpath => '//*[@id="about-content"]')
  link(:user_guide, :xpath => '//*[@id="user-guide"]')
  button(:about_done_button, :xpath => '//*[@id="done-btn"]')
  h3(:about_popup_title, :css => '#about-dialog > div > div.ui-header.ui-bar-c > h3')
  h3(:about_app_title_and_version, :css => '#about-content > div.about-wrapper > h3:nth-child(1)')
  p(:about_app_overview, :xpath => '//*[@id="about-content"]/div[1]/p[1]')
  p(:about_accessing_app_heading, :xpath => '/html/body/div[3]/div/div[2]/div/strong')
  p(:about_accessing_app_description, :xpath => '//*[@id="about-content"]/div[1]/p[2]')
  p(:about_main_page_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[2]')
  p(:about_main_page_description, :xpath => '//*[@id="about-content"]/div[1]/p[3]')
  h3(:about_booking_heading, :xpath => '//*[@id="about-content"]/div[1]/h3[2]')
  p(:about_booking_description, :xpath => '//*[@id="about-content"]/div[1]/p[4]')
  p(:about_booking_selecting_patient_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[3]')
  p(:about_booking_selecting_patient_description, :xpath => '//*[@id="about-content"]/div[1]/p[5]')
  p(:about_booking_selecting_specialty_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[4]')
  p(:about_booking_selecting_specialty_description, :xpath => '//*[@id="about-content"]/div[1]/p[6]')
  p(:about_booking_calendar_month_view_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[5]')
  p(:about_booking_calendar_month_view_description, :xpath => '//*[@id="about-content"]/div[1]/p[7]')
  p(:about_booking_calendar_week_view_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[6]')
  p(:about_booking_calendar_week_view_description, :xpath => '//*[@id="about-content"]/div[1]/p[10]')
  p(:about_booking_calendar_day_view_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[7]')
  p(:about_booking_calendar_day_view_description, :xpath => '//*[@id="about-content"]/div[1]/p[11]')
  p(:about_booking_appointment_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[8]')
  p(:about_booking_appointment_description, :xpath => '//*[@id="about-content"]/div[1]/p[12]')
  p(:about_booking_patient_tab_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[9]')
  p(:about_booking_patient_tab_description, :xpath => '//*[@id="about-content"]/div[1]/p[14]')
  p(:about_cancelling_apointment_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[11]')
  p(:about_cancelling_appointment_description, :xpath => '//*[@id="about-content"]/div[1]/p[16]')
  p(:about_wait_list_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[12]')
  p(:about_wait_list_description, :xpath => '//*[@id="about-content"]/div[1]/p[17]')
  p(:about_consult_orders_heading, :xpath => '//*[@id="about-content"]/div[1]/strong[13]')
  p(:about_consult_orders_description, :xpath => '//*[@id="about-content"]/div[1]/p[18]')
  p(:about_vaac_heading, :xpath => '//*[@id="about-content"]/div[1]/h3[5]')
  p(:about_vaac_description, :xpath => '//*[@id="about-content"]/div[1]/p[25]')

  p(:patient_info_name, :css => '#header > div > div > div > div > p:nth-child(1) > strong')
  p(:patient_info_dob, :css => '#header > div > div > div > div > p:nth-child(2)')
  p(:patient_info_ssn, :css => '#header > div > div > div > div > p:nth-child(3)')
  button(:clear_patient_context, :id => 'clear-context')
  button(:patient_contact_btn, :id => 'patient-contact')
  button(:patient_details_done_btn, :id => 'patient-details-done-btn')
  button(:process_request, :xpath => '//*[@id="process-request"]')
  button(:patient_search_btn, :id => 'patient-search')
  button(:date_picker_set_btn, :id => 'set-btn')
  h1(:patient_contact_dtls_header, :xpath => '//*[@id="patient-details"]/div[1]/h1')
  span(:email, :xpath => '//*[@id="patient-details"]/div[2]/ul/li[1]/span[2]')
  span(:home_phone, :xpath => '//*[@id="patient-details"]/div[2]/ul/li[2]/span[2]')
  span(:work_phone, :xpath => '//*[@id="patient-details"]/div[2]/ul/li[3]/span[2]')
  span(:address, :xpath => '//*[@id="patient-details"]/div[2]/ul/li[4]/span[2]')

  p(:no_patient_selected_message, :xpath => '//*[@id="header"]/div/div/div/p/strong')

  label(:desired_date_label, :css => 'label[for="desired-date"]')

	list_item(:option_date_1, :xpath => '//*[contains(@class, "option-date1")]')
	
	text_field(:service_specialty_field, :id => 'calendar-specialty-input')
	link(:specialty_list_item, :xpath => '//*[@id="calendar-specialty"]/li[3]/div/div/a')
	button(:clinic_menu_btn, :id => 'calendar-clinic-button')
	button(:close_btn, :id => 'close-btn')
	button(:date_picker_btn, :id => 'date-picker-btn')
	button(:confirm_button, :id => 'confirm-button')
	text_field(:desired_date, :id => 'desired-date')
	
	link(:footer_veteran_requests_btn, :xpath => '//*[@id="footer-veteran-requests-btn"]')
	link(:footer_waitlist_btn, :xpath => '//*[@id="footer-waitlist-btn"]')
	link(:footer_booking_btn, :id => 'footer-booking-btn')
	link(:active_booking_btn, :css => '#footer-booking-btn.ui-btn-active')
	link(:footer_consults_btn, :id => 'footer-consults-btn')
	
	span(:ewl_desired_date, :xpath => '//*[@id="inner-content"]/section[2]/div/div/div/div[2]/ul[2]/li[1]/span[2]')
	span(:near_desired_date, :xpath => '//*[@id="inner-content"]/section[2]/div/div/div/div[2]/ul/li[7]/span[2]')
	span(:recall_desired_date, :xpath => '//*[@id="inner-content"]/section[2]/div/div/div/div[2]/ul/li[7]/span[2]')
	
	div(:date_picker_popup, :id => 'date-picker-popup')
	link(:date_picker_close_btn, :xpath => '//*[@id="date-picker"]/a')

	div(:patient_info, :xpath => '//*[@id="header"]/div/div/div')
	
	div(:confirmation_popup, :id => 'confirmation')
	
	list_item(:confirm_last_name, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[1]')
	list_item(:confirm_first_name, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[2]')
	list_item(:confirm_dob, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[3]')
	list_item(:confirm_age, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[4]')
	list_item(:confirm_gender, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[5]')
	list_item(:confirm_location, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[6]')
	list_item(:confirm_ssn, :xpath => '//*[@id="confirmation"]/div[1]/ul/li[7]')

	link(:patient_search_close_btn, :css => '#search .ui-btn-right')
  link(:nearlist_header, :xpath => '//*[@id="near"]/h3/a')
  link(:recalllist_header, :xpath => '//*[@id="recall"]/h3/a')

  spans(:patient_context_headers, :css => '#patient-simple-details span')
  strongs(:patient_context_values, :css => '#patient-simple-details strong')

  text_field(:consults_specialty_field, :id => 'service-specialty-input')
  link(:consults_rad_service, :css => '[data-id="50"]')
  h3(:test_vamc3, :xpath => '//*[@id="inner-content"]/section[2]/div/div/div/div[1]/h3')
  h1(:sdd_popup, :xpath => '//*[@id="error-calendar-clinic-listbox"]/div[1]/h1')


	button(:calendar_next_btn, :css => '.fc-button-next')
	buttons(:calendar_available_day, :css => '.available button')
	buttons(:calendar_available_slot, :css => '.fc-view-agendaDay .fc-event')
	button(:correct_date_picker_btn, :id => 'correcting-date-picker-btn')
  text_field(:correct_desired_date, :id => 'correcting-desired-date')
  button(:setdd,:xpath => '//*[@id="desired-date-ok-button"]/button')
  button(:setdd_disabled, :css => '#desired-date-ok-button button:disabled')
  span(:clinic1_check, :css => 'label[for="clinic-1"] .ui-icon-checkbox-on')

  #methods
  def openPage(driver)
    @driver = driver
    #open the default booking page
    # booking_btn
  end

  def reenterApp()
    @driver.get("#{$acp_url}/#{$acp_app}")
  end

  def getAppName()
    app_name = "#{about_app_title_and_version.split(' ')[0]} #{about_app_title_and_version.split(' ')[1]}"
    puts "  -app title: #{app_name}"
    return app_name
  end

  def getAppVersion()
    puts "  -app version: #{about_app_title_and_version.split(' ')[2]}"
    return about_app_title_and_version.split(' ')[2]
  end

  def getLeftNavigationBtn()
    @driver.find_element(:id, "left-navigation")
  end

  def getLeftPanel()
    @driver.find_element(:id, 'left-navigation-panel')
  end

  def openLeftPanel()
    left_navigation_button unless left_navigation_panel_element.visible?
  end

  def closeLeftPanel()
    left_navigation_button if left_navigation_panel_element.visible?
  end

  def closeExitPopup()
    @driver.find_element(:id, 'exit-close-btn').click if exit_popup_element.visible?
    get_wait.until{ !exit_popup_element.visible? }
  end

  def openAboutPopup()
    openLeftPanel
    get_wait.until{ about_button_element.visible? }
    about_button
  end

  def getAboutPopupTitleText()
    get_wait.until{ about_popup_title_element.visible? }
    about_popup_title
  end

  def getAboutNavMenuText
    openLeftPanel
    get_wait.until{ about_button_element.visible? }
    about_button_element.element.text
  end

  def getNavBtnLabel(nav_button)
    puts " -getFooterBtnLabel(#{nav_button})"

    #close any open menus like the more menu if open, if not it won't hurt to click on this next element anyway
    #@driver.find_element(:id, 'footer-menu-popup-screen').click

    button_name = ''

    if (@@BOOKING_BUTTON_LABEL == nav_button)
      button_name = booking_button_element.element.text.rstrip
    end

    if (@@WAIT_LIST_BUTTON_LABEL == nav_button)
      button_name = @driver.find_element(:id, 'footer-waitlist-btn').text.rstrip
    end

    if (@@CONSULTS_BUTTON_LABEL == nav_button)
      button_name = @driver.find_element(:id, 'footer-consults-btn').text.rstrip
    end

    if (@@VETERAN_REQUESTS_BUTTON_LABEL == nav_button)
      button_name = veteran_requests_btn_element.element.text.rstrip
    end

    if (@@MORE_BUTTON_LABEL == nav_button)
      button_name = @driver.find_element(:id, 'footer-more-btn').text.rstrip
    end

    puts "  -nav button name: #{button_name}"
    return button_name
  end

  def getPatientDOB()
    return patient_info_dob_element.text[0, 10]
  end

  def getPatientAge()
    dob_line = patient_info_dob_element.text
    return dob_line[dob_line.index('(')+1..dob_line.index(')')-1]
  end

  def getPatientGender()
    return patient_info_dob_element.text[-1, 1]
  end

  def isDOBFormatted()
    puts " -isDOBFormatted()"
    # puts "  -DOB: #{self.getPatientDOB()}"
    # puts "  -DOB match: #{self.getPatientDOB.match('^\d{2}/\d{2}/\d{4}')}"
    puts "  -DOB formatted? #{self.getPatientDOB.match('^\d{2}/\d{2}/\d{4}') != nil}"
    return self.getPatientDOB.match('^\d{2}/\d{2}/\d{4}') != nil
  end

  def isPatientAgeValid()
    puts " -isPatientAgeValid()"

    #Note: currently the application seems to neglect birth month and only uses birth year to calculate age.
    today = DateTime.now

    dob = Date.parse(self.getPatientDOB)

    displayed_age = self.getPatientAge.to_i

    # calc_age = today - dob
    # puts "calc age: #{(calc_age.to_i/365.4).round}"
    puts "  -calc age by year: #{(today.year - dob.year)}"

    # now = Time.now.utc.to_date
    # age = now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
    # puts "age calc from web: #{age}"
    puts "  -displayed age matches calculated age: #{((today.year - dob.year) == displayed_age)}"
    if ((today.year - dob.year) == displayed_age)
      return true
    else return false
    end
  end

  def isPatientNameFormatted()
    puts " -isPatientNameFormatted()"

    isFormatted = false
    patient_name = @driver.find_element(:xpath => '//*[@id="header"]/div/div/div/div/p[1]/strong').text.split(',')
    puts "  -patient lastname: #{patient_name[0]}"
    puts "  -patient firstname: #{patient_name[1]}"
    if (patient_name.size > 2)
      isFormatted = false
    else
      isFormatted = true
    end

    if ((patient_name[0].match(/\p{Lower}/) == nil) && (patient_name[1].match(/\p{Lower}/) == nil))
      isFormatted = true
    else
      isFormatted = false
    end

    return isFormatted
  end

  def isPatientSSNFormatted()
    puts " -isPatientSSNFormatted()"
    patient_ssn = patient_info_ssn_element.text
    puts "  -patient ssn: #{patient_ssn}"
    # puts "  -value of regex pattern match using the string match function: #{patient_ssn.match('^\d{3}-\d{2}-\d{4}$')}"
    if (patient_ssn.match('^\d{3}-\d{2}-\d{4}$') != nil)
      return true
    else
      return false
    end
  end

  def isPatientEmailFormatted()
    if (email_element.text.empty?)
      puts "  -patient email: not present"
      return true #nothing to validate until email address is required of the patient
    else
      patient_email = email_element.text
      puts "  -patient email: #{patient_email}"
      if (patient_email.match('\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b') != nil)
        return true
      else
        return false
      end
    end
  end

  def isPatientHomePhoneFormatted()
    #TODO: possibly enable a real phone number validation - currently the phone number being displayed from the backend is not formattted correctly.
    if (home_phone_element.text.empty?)
      puts "  -patient home phone: not present"
      return true #nothing to validate until the home phone number is required of the patient
    else
      patient_home_phone = home_phone_element.text
      puts "  -patient home phone: #{patient_home_phone}"
      return true
    end
  end

  def isPatientWorkPhoneFormatted()
    if (work_phone_element.text.empty?)
      puts "  -patient work phone: not present"
      return true #nothing to validate until the work phone number is required of the patient
    else
      patient_work_phone = work_phone_element.text
      puts "  -patient work phone: #{patient_work_phone}"
      # if (patient_work_phone.match('/^([0-9\(\)\/\+ \-]*)$/') != nil)
      return true
      # else return false
      # end
    end
  end

  def isPatientAddressFormatted()
    if (address_element.text.empty?)
      puts "  -patient address: not present"
      return true #nothing to validate until the address is required of the patient
    else
      puts "  -patient address: #{address_element.text}"
      return true
    end
  end

  #this method will most likely go away with the new patient search paradigm from JPV
  def updatePatientContextByName(patient_name)
    puts "  -updatePatientContextByName(#{patient_name})"
    wait = Selenium::WebDriver::Wait.new(:timeout => 30)

    patient_search_input = patient_name
    patient_search_input_element.fire_event('change')

    wait.until { @driver.find_element(:xpath => "//ul[@id='patient-search-results']/li[0]").displayed? }

    for i in 1..@driver.find_elements(:xpath, "//ul[@id='patient-search-results']/li").length do
      result = @driver.find_element(:xpath, "//ul[@id='patient-search-results']/li[i]/div/div/a/h3")
      puts "  -result[#{i}]: #{result.text}"
      if (result.text == patient_name)
        @driver.find_element(:xpath, "//ul[@id='patient-search-results']/li[i]/div/div/a").click
      end
    end
  end

  def findPatientTen()
  	@driver.find_element(:id, "patient-search").click
  	
  	sleep 2
  
    @driver.find_element(:xpath, '//*[@id="primary-search-filter"]/div/form/div/input').clear
    # @driver.find_element(:id, "patient-search-input").send_keys patient_name, :return
    @driver.find_element(:xpath, '//*[@id="primary-search-filter"]/div/form/div/input').send_keys "TEN, PATIENT"
    # sleep 10
    @driver.find_element(:xpath, '//*[@id="primary-search-filter"]/div/form/div/input').send_keys :return
    sleep 2
    # puts "entered search value: #{patient_name}"

    # puts "  -patient search results ul: #{patient_search_results_ul}"
    puts "  -patient search result size: #{@driver.find_elements(:xpath, "//ul[@id='patient-list']/li").size}"

    @driver.find_element(:xpath, "//ul[@id='patient-list']/li[4]/div/div/a").click
    
    @driver.find_element(:id, "confirm-button").click
    
    sleep 5
  end
  
  def openClinicMenu()
  	self.service_specialty_field = ""
  
  	self.service_specialty_field_element.send_keys 'general medicine'
  	
  	self.specialty_list_item_element.click
  	
  	sleep 1
  	
  	self.clinic_menu_btn
  end

  def selectDesiredDate(date_desired)
    puts " -selectDesiredDate(#{date_desired})"
    year_xpath = '.year button[data-value="' + date_desired.split('/')[2] + '"]'
    day_xpath = '.day button[data-value="' + date_desired.split('/')[1] + '"]'
    month_xpath = '.month button[data-value="' + date_desired.split('/')[0] + '"]'
    puts "#{year_xpath}"
    puts "desired date #{date_desired} in the date picker: #{@driver.find_element(:css, year_xpath).text}"
    puts "desired date #{date_desired} in the date picker: #{@driver.find_element(:css, day_xpath).text}"
    puts "desired date #{date_desired} in the date picker: #{@driver.find_element(:css, month_xpath).text}"
  end
  
  def isPatientSearchDisplayed()
  	patient_search_displayed = self.patient_search_input_element.visible?
  	
  	puts " -patient search is displayed: #{patient_search_displayed}"
  	
  	return patient_search_displayed
  end

  def arePatientDetailsValid(last_name, first_name, dob, age, gender, ssn)
    headers = self.patient_context_headers_elements
    values = self.patient_context_values_elements

    return headers[0].text == "Last" && \
           headers[1].text == "First" && \
           headers[2].text== "DOB" && \
           headers[3].text == "Age" && \
           headers[4].text == "Gender" && \
           headers[5].text == "SSN" && \

          values[0].text == last_name && \
    values[1].text == first_name && \
    values[2].text == dob && \
    values[3].text == age && \
    values[4].text == gender && \
    values[5].text == ssn

  end

	def pickAvailableSlot()
		self.calendar_next_btn	
		
		sleep 2
		
		self.calendar_available_day_elements[0].click
		
		sleep 2
		
		self.calendar_available_slot_elements[0].click
	end
end
