// functions in this modeule are used for verifying that a student is who they 
// say they are

function set_shared_or_private(shared_or_private){
    //reads or writes to local storage whether this computer is shared or private
    BookStorage.isPrivateComputer(shared_or_private==="private")
    const location = shared_or_private==="private" ? AutoStorage.STORAGE_TYPE.LOCAL : AutoStorage.STORAGE_TYPE.SESSION
    BookStorage.updateStorageType(location)
    show_shared_private_details()
  
}

function show_shared_private_details(){
    // show or hide the details of each authentication method appropriately
    if(BookStorage.isPrivateComputer()){
        for(const elem of document.getElementsByClassName("shared-computer")){
            elem.style.display="none"
        }
        for(const elem of document.getElementsByClassName("private-computer")){
            elem.style.display=""
        }
    }else{
        for(const elem of document.getElementsByClassName("shared-computer")){
            elem.style.display=""
        }
        for(const elem of document.getElementsByClassName("private-computer")){
            elem.style.display="none"
        }
    }
      
}

async function choose_configuration(evt) {
  //log("evt",evt)


  // can be called by passing in the checkbox to operate on, or by clicking the checkbox
  let checkbox=evt
  if(evt.target){
    // it looks as though we are clicking on the checkbox
    checkbox = evt.target
  }

  const config_id = checkbox.id

  // set the dbType to the id of hte box just checked
  let change=false
  let response=null
  switch (config_id) {
    case "book":
      change=true
      break
    case "sqlite":
      change=true
      break
    case "dataworld":
      //log("setting dw token")
      checkbox.innerHTML="hourglass_empty"
      checkbox.classList.add("blink")
      if(!evt.ctrlKey){//only trying to check existing config is ctrl is not down when clicked
        response=get_from_book_storage("dwToken")
        if (response){
          response = await check_dw_connection(response)
          if(response.status!=="success"){
            response=null
          }
        }
      }

      if(response){  
        change=true
      }else{  
        // either there is no dwToken or it did not work
        response = await get_dw_token()
        if(response){
          BookStorage.dwToken(response)
          change=true
        }
      }
      checkbox.classList.remove("blink")
      break
    case "oracle":
      checkbox.innerHTML="hourglass_empty"
      checkbox.classList.add("blink")
      // check to see if we can run an oracle query
      
      let succesfullyExecutedQuery=false
      if(!evt.ctrlKey){//only trying to check existing config is ctrl is not down when clicked

        let endpoint = BookStorage.loginType()==="gas" ? get_gas_endpoint() : null
        // it's okay to attempt the query if we have an endpoint OR we the logintype is paid

        if(endpoint || BookStorage.loginType()==="paid"){
          try{
              response = await run_db_query({connection:"sql_book_connection", engine:"oracle",endpoint:endpoint, query:"select count(*) as one from canvas.museum"})  
              log(response)
              if (response?.items[0]?.resultSet?.items[0]?.one) {
                succesfullyExecutedQuery = true
              }else{
                succesfullyExecutedQuery = false
              }
          }catch(e){
            succesfullyExecutedQuery = false
          }
        }
      }
      if(succesfullyExecutedQuery){
        // we succesfully executed an oracle query
        change=true
      }else{
        response = await get_oracle_configuration()
        log("response from getting oracle", response)
        if(response=="connected"){
          change=true
        }
      }
      checkbox.classList.remove("blink")
      break
  }
  checkbox.classList.remove("blink")
  checkbox.innerHTML="check_box_outline_blank"
  if(change){
    BookStorage.dbType(config_id)
    set_book_label()
    for (box of document.querySelectorAll("." + checkbox.dataset.set)) {
      box.getElementsByTagName("span")[0].innerHTML = "check_box_outline_blank"
      box.nextElementSibling.style.display = "none"
    }
    checkbox.innerHTML = "check_box"
    tag("config-" + config_id).style.display = ""
    configure_book()
  }
}


async function choose_ai_method(evt) {
  // executed when the users clicks the an AI option checkbox on the congiguration page
  const checkbox=evt.target
  if(checkbox.innerHTML==="check_box"){return}
  BookStorage.aiType(checkbox.id)

  for (box of document.querySelectorAll("." + checkbox.dataset.set)) {
    box.getElementsByTagName("span")[0].innerHTML = "check_box_outline_blank"
    box.nextElementSibling.style.display = "none"
  }

  checkbox.innerHTML = "check_box"
  configure_book()
}




async function choose_login_method(evt) {// old config process.  needs to be deleted when new procees is working
  //log("calling choose login method");

  // can be called by passing in the checkbox to operate on, or by clicking the checkbox
  let checkbox=evt
  if(evt.target){
    // it looks as though we are clicking on the checkbox
    checkbox = evt.target
  }
    const login_id = checkbox.id
  
    let change = false
    let auth_message="You are now configured to not require a password when working on this computer."
    let new_package

    checkbox.innerHTML="hourglass_empty"
    checkbox.classList.add("blink")

    login_id === "login-paid" ? firebase.auth.signOut(firebase.auth.getAuth()) : null

    switch (login_id) {
      case "login-none":
        set_login_password()
        change=true
        message({
          message:auth_message,
          title:"Authentication Method Changed",
          seconds:8,
          show:true
        })
        if(BookStorage.dbType()==="oracle"){
            // Oracle not allowed with this login type
            swtich_db("oracle","sqlite")
        }
        break
      case "login-local":
        auth_message="You are now logged in to this computer.  If you close your browser, you will need to supply your password again to access your saved settings."
        new_package = await set_local_password()
        if(new_package.password){
          // we have a new local password.  Use it to encrypt values in bookStorage
          set_login_password(new_package.password)
          BookStorage.localCanary(ncrypt("logged in",BookStorage.token()))
          change=true
          message({
            message:auth_message ,
            title:"Authentication Method Changed",
            seconds:8,
            show:true
          })
          if(BookStorage.dbType()==="oracle"){
            // Oracle not allowed with this login type
            swtich_db("oracle","sqlite")
          }
  
        }
        break
      case "login-gas":
        //log("getting deployment id",BookStorage.deploymentId())
        // first check to see if we have a valid token
        if(!evt.ctrlKey){//only trying to check existing config is ctrl is not down when clicked
          auth_message="You are now logged in using your own authentication server.  If you close your browser, you will need to supply your password again to access your saved settings."
          if(get_from_book_storage("deploymentId") && get_from_book_storage("gasToken")){
              // we ahave a token and deployment it, lets see if it is valid fist...
              const payload = {
                  mode: "connect"
              }
              const response = await server_post(payload, get_gas_endpoint())
              if (response.status === "connected") {
                  // we have connected and we are done
                  change=true
                  set_login_password(uuid())
                  server_properties_to_book_storage(response,get_from_book_storage("deploymentId"))
                  message({
                      message:auth_message,
                      title:"Authentication Method Changed",
                      seconds:8,
                      show:true
                  })
                  
                  break
              }
          }
        }        
        // set a new password if necessary
        new_package = await set_gas_password()
        if(new_package && new_package.status && new_package.status==="success"){
            BookStorage.deploymentId(new_package.deployment_id)
            // we have a new information for gas authentication.  Use it to encrypt values in bookStorage
            change=true
            set_login_password(new_package.password)
            BookStorage.localCanaryBookStrage=BookStorage.token  // used to hold the local-login token so we can recall it 
            message({
            message:auth_message,
            title:"Authentication Method Changed",
            seconds:8,
            show:true
            })
    
        }
        
        break  
      case "login-paid":
        //log("firebase-login")
        change = true // renders the check box
        // window.paidSection()
        paidUserInfo()
        break
    }
    checkbox.classList.remove("blink")
    checkbox.innerHTML="check_box_outline_blank"

    if(change){
      BookStorage.loginType(login_id.split("-")[1])
      // clear other checkmarks 
      for (box of document.querySelectorAll("." + checkbox.dataset.set)) {
        box.getElementsByTagName("span")[0].innerHTML = "check_box_outline_blank"
        box.nextElementSibling.style.display = "none"
      }
      // check the correct one 
      checkbox.innerHTML = "check_box"
      tag("config-" + login_id).style.display = "block"
      

      //debugger
      set_book_label()  
      configure_book()  
    }
    function swtich_db(from_db,to_db){
        // changes bookstroage dbtype and the checkbox.  does no verification
        BookStorage.dbType(to_db)
        tag(from_db).innerHTML="check_box_outline_blank"
        tag(to_db).innerHTML="check_box"
    }
  
  }


  async function abandon_machine(){
    
    const button_label="Yes, clear all data."
    const button = await ui_message_box(
        "This will clear all data from this machine, resetting it as if no one has used this book here.  Are you sure you want to clear the data? ",
        "Are you sure?",
        [button_label, "Oops, don't clear my data."]
    )
    
    if(button===button_label){
        localStorage.clear()
        sessionStorage.clear()
        document.body.innerHTML="<h3>Book Closed</h3><p>This book has been closed by the user and all traces of it's use has been removed from this machine.  To start again, refresh this page or click the link below.</p><p style='text-align:center'><a href='/?page=introduction'>Click here to Start Over</a>"
    }
}

function set_login_password(password="Samuel Davies"){
    BookStorage.changeEncryptionKey(password)
    if(BookStorage.isPrivateComputer()){
        BookStorage.updateStorageType(AutoStorage.STORAGE_TYPE.LOCAL)
    }else{
        BookStorage.updateStorageType(AutoStorage.STORAGE_TYPE.SESSION)
    }  
}

async function show_login_form(){  // Figure out which form to show for loggin in.

  const login_type = localStorage.getItem("loginType")
  const login_pacakge = localStorage.getItem("loginPackage")




  const value = await new Promise(
    (resolve, reject)=>{
      document.body.append(ui_modal("Login",login_form(resolve),resolve))
      configure_login_form()
      paidUserInfo("paid-login-container")// passing the value is not working, put some bad code in paidUserInfo that checks for existence of paid-login-container
      tag("pwd").focus()
    }
  )

if(value?.status==="success"){
  message({
    title: "Logged In",
    message: "You are now logged in and your prior configuration and work have been restored.",
    seconds: 4,
    show: true
  })

  load_page(CURRENT_PAGE_ID)// reload the page to account for new data

}

function login_form(resolve = () => { }, reject = () => { }) {
  const form = ui_form("auth-container ui-inline-block")
  
  const password_block = ui_div("local gas",ui_label("", "Password"), ui_br(),ui_input_password_reveal("ui-input ui-full-width"))
  const password_input = password_block.getElementsByTagName("input")[0]
  password_input.id="pwd"
  const error_message = ui_div("ui-bg-clear error-message ")
  const submit = ui_btn("Login")
  submit.classList.add("mt3")
  submit.classList.add("local") 
  submit.classList.add("gas")
  submit.onclick = async (e) => {
      e.preventDefault()

      if(login_type.value==="gas"){
        //Local gas//////////////////////////////////////////////////////////////////////////////////////////////////////
        

        if( e.target.innerHTML==="Login" || e.target.innerHTML==="Reset Password"){
          // initial connection to see if the server responding    
          if(deployment_id_input.value.length===0){
              error_message.replaceChildren(ui_span("", "Deployment ID is required."))
          }else if(password_input.value.length<8){
              error_message.replaceChildren(ui_span("", "Password must be at least 8 characters long."))
          }else if(e.target.innerHTML==="Reset Password" && reset_code_input.value.length!==8){
              error_message.replaceChildren(ui_span("", "Password must be exactly 8 characters long."))
  
          }else{
              // passed all checks
              //submit.replaceChildren(ui_loading())
              //debugger
              submit.disabled = true
              submit.innerHTML=`<span class="material-symbols-outlined blink" style="vertical-align:middle">hourglass_empty</span>`
              error_message.replaceChildren()
              reset.style.display="none"

              const payload = {
                  mode: "connect"
              }

              if(password_input.value){
                  payload.password=password_input.value
              }
              
              if (reset_code_input.value) {
                  payload.resetToken = reset_code_input.value
              }
              
              const response = await frelayServerPost(payload,get_gas_endpoint(deployment_id_input.value))
              submit.disabled = false
              if(response.status==="error"){
                // the server was contacted but because we have not sent a password, we could not yet login
                submit.innerHTML="Login"
                error_message.replaceChildren(ui_span("", "Unable to contact server using the Deployment ID given.  Please verify and try again."))
              }else if(response.status==="alive"){
                BookStorage.deploymentId(deployment_id_input.value)
                // the server was contacted but because we have not sent a password, we could not yet login
                submit.innerHTML="Login"
                password_div.style.display="block"
              }else if(response.status==="invalid-password"){
                BookStorage.deploymentId(deployment_id_input.value)
                
                //if(submit.innerHTML==="Login"){
                    error_message.replaceChildren(ui_span("", "Invalid Password.  Try again or use the button below to change your password."))
                    reset.style.display=""
                // }else{
                     submit.innerHTML="Login"
                //     password_div.style.display="block"
                // }
                
              }else if(response.status==="connected"){
                    // The existing token was valid, so we are connected
                    set_login_password(uuid())
                    server_properties_to_book_storage(response, deployment_id_input.value)
                    BookStorage.gasToken(response.token)
                    BookStorage.loginType("gas")
                    BookStorage.deploymentId(deployment_id_input.value)
                    tag("overlay").remove()
                    resolve({status:"success", deployment_id:deployment_id_input.value})            
              }
          }         
        }


      }else if(login_type==="paid"){
        //paidUserInfo()// build the paid user interface

      }else{
        //Local login//////////////////////////////////////////////////////////////////////////////////////////////////////
        if(password_input.value.length<8){
          error_message.replaceChildren(ui_span("", "Password must be at least 8 characters long."))
          return
        }
        // we have a password, see if we can decrypt the loginPackage
        let book_storage_object
        try{
          // passed all checks
          //submit.replaceChildren(ui_loading())
          //submit.disabled = true
          const temp_token = ncrypt("Shall we sin on still impenitent and incorrigible?", password_input.value)
          book_storage_object=JSON.parse(dcrypt(localStorage.getItem("loginPackage"), temp_token))

        }catch(e){
          error_message.replaceChildren(ui_span("", `The password in incorrect. If you have forgotten the password, there is no way to recover it. You'll need to choose "Settings" instead of "Login" and reconfigure this book from scratch.`))
          return
        }
 
        object_to_bookstorage(book_storage_object)
        tag("overlay").remove()
        resolve({status:"success"})

      }


  }


  

  const options=[]
  if(localStorage.getItem("loginPackage")){// we can only do a local auth the loginPackage has been saved here
    options.push({value:"local", innerHTML:"Login to this computer", selected:true})

  }
  options.push({value:"paid", innerHTML:"This book's authentication service", selected:localStorage.getItem("loginType")==="paid"})
  options.push({value:"gas", innerHTML:"Your own authentication service", selected:localStorage.getItem("loginType")==="gas"})


 


  // local login specific
  const login_type=ui_select("ui-input ui-full-width",...options)
  login_type.id="login_type"
  login_type.onchange = (e) => {
    e.preventDefault()
    configure_login_form()
    //console.log(e.target.value)
  }
  // paid specific
  const paid_container=ui_div("paid",ui_sign_in_form(async (user_cred)=>{
    // resolve
    log("logged in***********************", user_cred)
    // get book stroage from paylay
    BookStorage.loginType("paid")
    
    const data = await get_server_property({key:"book_storage"})
    // need to restore data
    if(data){
      server_properties_to_book_storage(data)
    }
    
    tag("overlay").remove()
    resolve({status:"success"})            
  },(error_obj)=>{
    // reject
    console.error("error logging into paylay",error_obj)
  }))
  paid_container.id="paid-login-container"

  // gas specific
  const deployment_id_input=ui_input("ui-input ui-full-width")
  const deployment_id_block = ui_div("gas",ui_label("", "Deployment ID"), ui_br(),deployment_id_input)

  const reset_code_input = ui_input("ui-input ui-full-width")

  const reset = ui_btn("Request Password Reset")       
  reset.style.display="none"
  const reset_message = ui_div("ui-bg-clear")

  reset.classList.add("mt3")

  const reset_div=ui_div("", ui_label("", "Password Reset Code"), ui_br(), reset_code_input)
  reset_div.style.display="none"
  const reset_container=ui_div("gas", reset_div)

  reset.onclick = async (e) => {
    e.preventDefault()
    reset.disabled = true
    error_message.replaceChildren()
    submit.style.display="none"
    reset.innerHTML=`<span class="material-symbols-outlined blink" style="vertical-align:middle">hourglass_empty</span>`


    const payload = {
      mode: "request-reset",
    }
    const response = await server_post(payload,get_gas_endpoint(deployment_id_input.value))
    reset.disabled = false
    //log("response", response)
    if (response.status === "success") {
      reset_message.replaceChildren(ui_span("", 'A reset code has been sent to the email address attached to the deployment id you entered. Enter the code in the "Pasword Reset Code" field above and enter the password you want to use.'))
      reset_div.style.display="block"
      submit.innerHTML="Reset Password"
      submit.style.display=""
      reset.style.display="none"
      // message({
      //   message: `A reset code has been sent to the email address attached to the deployment id you enterd. Enter the code in the "Reset Code" field below and choose a new password.  You can also change the username if you like.`,
      //   title: "Password",
      //   seconds: 8,
      //   show: true
      // })
      // tag("reset-code").style.display = null
      // tag("reset-button").style.display = "none"
    } else if (response.status === "failure") {
      message({
        message: response.message,
        title: "Reset Request Failed",
        seconds: 8,
        kind: "error",
        show: true
      })
    } else {
      message({
        message: result,
        title: "Unexpected Error",
        seconds: 8,
        kind: "error",
        show: true
      })
    }

  }




  form.append(
      ui_label("", "Authentication Method"), ui_br(),
      login_type,
      deployment_id_block,
      password_block,
      reset_container,
      submit,
      error_message,
      reset,
      reset_message,
      paid_container,
  )
  return form




}


function configure_login_form(){// show what should be shwn based on which option is selected
    
    
  for(const elem of document.querySelectorAll(".gas, .local, .paid")){
    log("found:",elem)
    elem.style.display="none"
  }

  for(const elem of document.querySelectorAll("." + tag("login_type").value)){
    elem.style.display=""
  }

  // if(login_type.value==="gas"){
  //   password_block.style.display=""
  //   deployment_id_block.style.display=""
  // }else if(login_type.value==="paid"){
  //   password_block.style.display="none"
  //   deployment_id_block.style.display="none"
  // }else{
  //   // must be local
  //   password_block.style.display=""
  //   deployment_id_block.style.display="none"
  // }

}



  // if(login_type==="local" && login_pacakge){
  //   login_local()
  // }else if(login_type==="gas"){
  //   login_gas()
  // }else if(login_type==="paid"){
  //   log("Need to build a form for paylay login")
  // }else{
  //   // none
  // }
  

 // await login_dialog(warning_message)

}


  

async function login_local(){
    // allows the user to supply the password for a local login and verifies if it is correct
    const value = await new Promise(
      (resolve, reject)=>{
        document.body.append(ui_modal("Login to this Computer",login_local_form(resolve),resolve))
        tag("pwd").focus()
      }
    )


    //log("login response", value)













    return value
  
    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function login_local_form(resolve = () => { }, reject = () => { }) {
      const form = ui_form("auth-container ui-inline-block")
      
      const password_block = ui_input_password_reveal("ui-input ui-full-width")
      const password_input = password_block.getElementsByTagName("input")[0]
      password_input.id="pwd"
      const error_message = ui_div("ui-bg-clear error-message ")
      const submit = ui_btn("login")
      submit.classList.add("mt3")
      submit.onclick = (e) => {
          e.preventDefault()
          //debugger
          if(password_input.value.length<8){
            error_message.replaceChildren(ui_span("", "Password must be at least 8 characters long."))
            return
          }
          // we have a password, see if we can decrypt the loginPackage
          let book_storage_object
          try{
            // passed all checks
            //submit.replaceChildren(ui_loading())
            //submit.disabled = true
            const temp_token = ncrypt("Shall we sin on still impenitent and incorrigible?", password_input.value)
            book_storage_object=JSON.parse(dcrypt(localStorage.getItem("loginPackage"), temp_token))

          }catch(e){
            error_message.replaceChildren(ui_span("", "The password in incorrect."))
            return
          }

          object_to_bookstorage(book_storage_object)
          tag("overlay").remove()
          resolve("success")


      }
  
      // const switch_btn = ui_btn("Switch to No Authentication")
      // switch_btn.classList.add("mt3")
      // switch_btn.onclick = (e) => {
      //     e.preventDefault()
      //     set_login_password()
      //     tag("overlay").remove()
      //     resolve("no login")
      // }
  
      // const or=ui_h2("","OR")
      // or.style.textAlign="center"
      form.append(
          ui_p("","This book is configured for authentication directly on this computer. Please supply the password you chose previously to access your saved settings and any prior work.")  ,
          ui_label("", "Password"), ui_br(), password_block, ui_br(),
          submit,
          error_message,
          // or,
          ui_p("","If you have forgotten the password, there is no way to recover it.  You'll need to choose \"Settings\" instead of \"Login\" and reconfigure this book from scratch.")  ,
          // switch_btn
      )
      return form
    }
  }
  


  async function setup_wizard_login_gas(){
    // allows the user to supply the password for a gas login and verifies if it is correct

    const value = await new Promise(
      (resolve, reject)=>{
        document.body.append(ui_modal("Login to your Authentication Service",login_gas_form2(resolve),resolve))
        tag("pwd").focus()
      }
    )
    return value
  
    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function login_gas_form2(resolve = () => { }, reject = () => { }) {
      const form = ui_form("auth-container ui-inline-block")
      form.append(
        setup_wizard_gas_authentication_block(resolve)
      )
      return form
    }
    
  
  }

  



  
  async function login_gas(){
    // allows the user to supply the password for a local login and verifies if it is correct
    
    // first, check to see if we are already logged in

    // can't get here unless we are logged out.  no need to check

    // if(get_from_book_storage("deploymentId") && get_from_book_storage("gasToken")){
    //     // we ahave a token and deployment it, lets see if it is valid fist...
    //     const payload = {
    //         mode: "connect"
    //     }
    //     const response = await server_post(payload)
    //     if (response.status === "connected") {

    //         set_login_password(uuid())// generate a password for use with encryption.  I does not need to be knowable because this login time is verified at google server
    //         server_properties_to_book_storage(response, get_from_book_storage("deploymentId"))
    //         message({
    //             message:"You are now logged in using your own authentication server.",
    //             title:"Authentication Method Changed",
    //             seconds:8,
    //             show:true
    //         })
    //         return {status:"success"}
    //     }
    // }

    const value = await new Promise(
      (resolve, reject)=>{
        document.body.append(ui_modal("Login to your Authentication Service",login_gas_form(resolve),resolve))
        tag("depl-id").focus()
      }
    )
    return value
  
    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function login_gas_form(resolve = () => { }, reject = () => { }) {
      const form = ui_form("auth-container ui-inline-block")
  
      form.append(
          gas_authentication_block(resolve),
      )
      return form
    }
    
  
  }


  
  async function set_local_password(){
  // sets the password for a local login
    const value = await new Promise(
      (resolve, reject)=>{
        document.body.append(ui_modal("Set Local Password",set_local_password_form(resolve),resolve))
        tag("pwd").focus()
      }
    )
    return value
  
    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function set_local_password_form(resolve = () => { }, reject = () => { }) {
      const form = ui_form("auth-container ui-inline-block")
      const password_block = ui_input_password_reveal("ui-input ui-full-width")
      const password_input = password_block.getElementsByTagName("input")[0]
      password_input.id="pwd"
      const submit = ui_btn("Set Password")
      const error_message = ui_div("ui-bg-clear error-message ")
      submit.classList.add("mt3")
      submit.onclick = (e) => {
          e.preventDefault()
          
          if(password_input.value.length===0){
            error_message.replaceChildren(ui_span("", "Password is required."))
          }else{
            // passed all checks
            //submit.replaceChildren(ui_loading())
            submit.disabled = true
            error_message.replaceChildren()
            tag("overlay").remove()
            resolve({password:password_input.value})
          }
      }
      form.append(
          ui_p("","Choose a password that you will use to authenticate on this computer.   We'll use it to encrypt your settings and work so even if someone gets ahold of this computer, they wont be able to read your data."),
          ui_label("", "Password"), ui_br(), password_block, ui_br(),
          submit,
          error_message,
      )
      return form
    }
    
  
  }
  
  
  
  
  async function set_gas_password(){
    // sets the password for a local login
      const value = await new Promise(
        (resolve, reject)=>{
          document.body.append(ui_modal("Connect to your Authentication Service",set_gas_password_form(resolve),resolve))
          tag("depl-id").focus()
        }
      )
      return value
    
      // currently only used here, but could be used elsewhere.  then we will move it out of this fn
      function set_gas_password_form(resolve = () => { }, reject = () => { }) {
        const form = ui_form("auth-container ui-inline-block")
        form.append(
            gas_authentication_block(resolve)
        )
        return form
      }
      
    
    }
    

    function gas_authentication_block(resolve){
   
      const deployment_id_input = ui_input("ui-input ui-full-width")
      deployment_id_input.id="depl-id"
  
      const password_block = ui_input_password_reveal("ui-input ui-full-width")
      const password_input = password_block.getElementsByTagName("input")[0]
      const password_div=ui_div("", ui_label("", "Password"), ui_br(), password_block)
      //password_div.style.display="none"
  
      const reset_code_input = ui_input("ui-input ui-full-width")
      const reset_div=ui_div("", ui_label("", "Password Reset Code"), ui_br(), reset_code_input)
      reset_div.style.display="none"
  
      const reset = ui_btn("Reset Password")       
      reset.style.display="none"
      const reset_message = ui_div("ui-bg-clear")
  
      reset.classList.add("mt3")
      reset.onclick = async (e) => {
          e.preventDefault()
          reset.disabled = true
          const payload = {
              mode: "request-reset",
            }
            const response = await server_post(payload,get_gas_endpoint(deployment_id_input.value))
            reset.disabled = false
            //log("response", response)
            if (response.status === "success") {
              reset_message.replaceChildren(ui_span("", 'A reset code has been sent to the email address attached to the deployment id you entered. Enter the code in the "Reset Code" field above and enter the password you want to use.'))
              reset_div.style.display="block"
              // message({
              //   message: `A reset code has been sent to the email address attached to the deployment id you enterd. Enter the code in the "Reset Code" field below and choose a new password.  You can also change the username if you like.`,
              //   title: "Password",
              //   seconds: 8,
              //   show: true
              // })
              // tag("reset-code").style.display = null
              // tag("reset-button").style.display = "none"
            } else if (response.status === "failure") {
              message({
                message: response.message,
                title: "Reset Request Failed",
                seconds: 8,
                kind: "error",
                show: true
              })
            } else {
              message({
                message: result,
                title: "Unexpected Error",
                seconds: 8,
                kind: "error",
                show: true
              })
            }
        
  
      }
  
      const submit = ui_btn("Connect")       
      const error_message = ui_div("ui-bg-clear error-message ")
      submit.classList.add("mt3")
      submit.onclick = async (e) => {
          e.preventDefault()
          //debugger
          if(e.target.innerHTML==="Connect" || e.target.innerHTML==="Login"){
              // initial connection to see if the server responding    
              if(deployment_id_input.value.length===0){
                  error_message.replaceChildren(ui_span("", "Deployment ID is required."))
              }else if(e.target.innerHTML==="Login" && password_input.value.length===0){
                  error_message.replaceChildren(ui_span("", "Password is required."))
              }else{
                  // passed all checks
                  //submit.replaceChildren(ui_loading())
                  //debugger
                  submit.disabled = true
                  error_message.replaceChildren()
                  reset.style.display="none"
  
                  const payload = {
                      mode: "connect"
                  }
  
                  if(password_input.value){
                      payload.password=password_input.value
                  }
                  
                  if (reset_code_input.value) {
                      payload.resetToken = reset_code_input.value
                  }
                  
                    const response = await frelayServerPost(payload,get_gas_endpoint(deployment_id_input.value))
                    submit.disabled = false
                    if(response.status==="error"){
                      // the server was contacted but because we have not sent a password, we could not yet login
                      debugger
                      error_message.replaceChildren(ui_span("", "Unable to contact server using the Deployment ID given.  Please verify and try again."))
                    }else if(response.status==="alive"){
                      BookStorage.deploymentId(deployment_id_input.value)
                      // the server was contacted but because we have not sent a password, we could not yet login
                      submit.innerHTML="Login"
                      password_div.style.display="block"
                    }else if(response.status==="invalid-password"){
                      BookStorage.deploymentId(deployment_id_input.value)
                      
                      if(submit.innerHTML==="Login"){
                          error_message.replaceChildren(ui_span("", "Invalid Password.  Try again or use the button below to change your password."))
                          reset.style.display=""
                      }else{
                          submit.innerHTML="Login"
                          password_div.style.display="block"
                      }
                      
                    }else if(response.status==="connected"){
                          // The existing token was valid, so we are connected
                          set_login_password(uuid())
                          server_properties_to_book_storage(response, deployment_id_input.value)
                          BookStorage.gasToken(response.token)
                          tag("overlay").remove()
                          resolve({status:"success", deployment_id:deployment_id_input.value})            
                    }else{
  
                    }
  
              }
          }else if(e.target.innerHTML==="login"){
  
          }
      }
  
      return ui_div("",
          ui_p("",'Enter the "Deployment ID" that you copied when you set up your authentication service on Google Apps Script.'),
          ui_label("", "Deployment ID"), ui_br(), deployment_id_input, ui_br(),
          password_div,
          reset_div,
          submit,
          error_message,
          reset,
          reset_message,
      )
  
  
  }    
      
    
      


function setup_wizard_gas_authentication_block(resolve){
  const submit = ui_btn("Login")    
  const error_message = ui_div("ui-bg-clear error-message ")   
  const deployment_id=tag("gas-deployment-id").value
  const password_block = ui_input_password_reveal("ui-input ui-full-width")
  password_block.id="pwd"
  const password_input = password_block.getElementsByTagName("input")[0]
  const password_div=ui_div("", ui_label("", "Password"), ui_br(), password_block)

  const reset_code_input = ui_input("ui-input ui-full-width")
  const reset_div=ui_div("", ui_label("", "Password Reset Code"), ui_br(), reset_code_input)
  reset_div.style.display="none"

  const reset = ui_btn("Request Password Reset")       
  reset.style.display="none"
  const reset_message = ui_div("ui-bg-clear")

  reset.classList.add("mt3")
  reset.onclick = async (e) => {
      e.preventDefault()
      reset.disabled = true
      const payload = {
          mode: "request-reset",
      }
      const response = await server_post(payload,get_gas_endpoint(deployment_id))
      reset.disabled = false
      //log("response", response)
      if (response.status === "success") {
        reset_message.replaceChildren(ui_span("", 'A reset code has been sent to the email address attached to the deployment id you entered. Enter the code in the "Password Reset Code" field above and enter the password you want to use.'))
        reset_div.style.display="block"
        password_div.style.display="none"
        reset.style.display="none"
        submit.innerHTML="Reset Password"
        error_message.replaceChildren()
        password_input.value=tag("local-login-pwd").value// read the original password the user supplied in the wizard
      } else if (response.status === "failure") {
        message({
          message: response.message,
          title: "Reset Request Failed",
          seconds: 8,
          kind: "error",
          show: true
        })
      } else {
        message({
          message: result,
          title: "Unexpected Error",
          seconds: 8,
          kind: "error",
          show: true
        })
      }
  }

    submit.classList.add("mt3")
    submit.onclick = async (e) => {
      debugger
      e.preventDefault()
        // initial connection to see if the server responding    
      if(password_input.value.length===0){
        error_message.replaceChildren(ui_span("", "Password is required."))
      }else{
        // passed all checks
        //submit.replaceChildren(ui_loading())
        submit.disabled = true
        error_message.replaceChildren()
        reset.style.display="none"

        const payload = {
            mode: "connect"
        }

        payload.password=password_input.value
        
        if (reset_code_input.value) {
            payload.resetToken = reset_code_input.value
        }
        
        const response = await frelayServerPost(payload,get_gas_endpoint(deployment_id))
        submit.disabled = false
        if(response.status==="error"){
          // the server was contacted but because we have not sent a password, we could not yet login
          debugger
          submit.innerHTML="Login"
          error_message.replaceChildren(ui_span("", "Unable to contact server using the Deployment ID given.  Please verify and try again."))
        }else if(response.status==="alive"){
          BookStorage.deploymentId(deployment_id)
          // the server was contacted but because we have not sent a password, we could not yet login
          submit.innerHTML="Login"
          password_div.style.display="block"
        }else if(response.status==="invalid-password"){
          BookStorage.deploymentId(deployment_id)
          
          if(submit.innerHTML==="Login"){
              error_message.replaceChildren(ui_span("", "Invalid Password.  Try again or use the button below to change your password."))
              reset.style.display=""
          }else{
              submit.innerHTML="Login"
              password_div.style.display="block"
          }
          
        }else if(response.status==="connected"){
              // The existing token was valid, so we are connected
              tag("overlay").remove()
              resolve({status:"success", token:response.token})            
        }else{
              debugger
              tag("overlay").remove()
              resolve({status:"failure", message:"unexpected response from service"})            

        }
      }
    }

    return ui_div("",
        ui_p("",'The authentication service identified by the Deployment ID you entered has already been configured with a password.  Enter it below to continue.'),
        password_div,
        reset_div,
        submit,
        error_message,
        reset,
        reset_message,
    )


}    
    
  
  
function paste_settings_import(){
    // imports stdent data to a a textbox for copy and pasting
  
  let data=tag("copy-paste").value

  try{
    data=JSON.parse(data)
  }catch(e){
    message({
      message: "There is an error in the import data.",
      title: "Import Error",
      seconds: 8,
      kind: "error",
      show: true
    })
    return
  }
  //log("data", data)

  //log("get_book_db_type()",get_book_db_type())
  object_to_bookstorage(data)
  //log("get_book_db_type tag",tag(get_book_db_type()))

  // run the same code that gets run when the settings page loads
  choose_configuration(tag(get_book_db_type()))
  choose_login_method(tag("login-"+BookStorage.loginType()))
  fill_server_configuration()  

  message({
    message: "Your information has been restored",
    title: "Import Succeeded",
    seconds: 4,
    show: true
  })
  


}

function paste_settings_export(){
  const data=bookstorage_to_object()
  log(data)

  tag("copy-paste").value=JSON.stringify(data,null,2)

  message({
    message: "Your information can now be copied or edited.",
    title: "Export Successful",
    seconds: 8,
    show: true
  })

}


function export_student_data(){
    // exports stdent data to a file to be imported with import_student_date
    const password=tag("import-export-password").value
  
  
    const data=bookstorage_to_object()
  
    const data_file=(
      password ? 
      ncrypt(JSON.stringify(data),password)
      : 
      JSON.stringify(data,null,2)
    )
  
    //log(data_file)
  
    download_text_file(data_file, "sql-book-settings.json")
    message({
      message: "Your information file has been exported.",
      title: "File Downloaded",
      seconds: 8,
      show: true
    })
}


function import_student_data(raw_data){
    // imports a file that was exported with export_stduent_data
    //log("at import stduetn data")
  
    let data
    try{// try to import with out password, just in case...
      data=JSON.parse(raw_data) 
    } catch(e){
      // could not decrypt withhout PW, try with
      data=dcrypt(raw_data,tag("import-export-password").value)
      
      if(data==="failed"){  
        message({
          message: "The password you provided is not correct.  Please try again.",
          title: "File Not Imported",
          seconds: 8,
          kind: "error",
          show: true
        })
        return
      }    
    }

    object_to_bookstorage(data)

  
    // run the same code that gets run when the settings page loads
    choose_configuration(tag(get_book_db_type()))
    choose_login_method(tag("login-"+BookStorage.loginType()))
    fill_server_configuration()  
  
    message({
      message: "Your information has been restored",
      title: "File Imported",
      seconds: 8,
      show: true
    })
  }

  function fill_server_configuration() {
    // computer shared or private
    
    if(BookStorage.isPrivateComputer()){
      tag("private_computer").checked=true
    }else{
      tag("shared_computer").checked=true
    }
    
    
  
    // prefill the server configuration with whatever is known about it
    //log("url", url)
    const url_params = get_params()
    //log("url_params", url_params)
    if (url_params.data) {
      // a data block has been sent in link, these take precedence
      data = JSON.parse(atob(url_params.data))
      //log("data", data)
      tag("gas-username").value = data.gasUsername
  
      if(data.deploymentId){
        tag("deployment-id").value = data.deploymentId
        BookStorage.deploymentId=data.deploymentId
      }
    }
  
    data_from_book_storage_to_element(document.body)  
  
  
  }
  
  
function data_from_book_storage_to_element(element=document.body){
    // looks at all input tags in element and uses thier ids to try to pull data from bookStorage
    for (const [var_name,id] of Object.entries(get_id_map_from_element(element))){
      try{
        tag(id).value=BookStorage[var_name]()
      }catch(e){
        //console.error(e)
        // on error, ignore.  It means there is no matching value in bookStorage
      }
    }
  }
  function setup_wizard_change(select_changed){
    // respond when the users makes a choice in the setup wizard
    log(select_changed.id, select_changed.value, select_changed.selectedIndex)
    const code= "" +
          (tag("privacy").selectedIndex+1).toString() +
          (tag("authentication").selectedIndex+1).toString() +
          (tag("database").selectedIndex+1).toString() +
          (tag("ai").selectedIndex+1).toString() +
          //(tag("report").selectedIndex+1).toString() +
          (tag("contents-list").selectedIndex+1).toString()  

    tag("config-code").value=code
    configure_choices()
  }

  function configure_choices(){
    // used for the setup wizard makes the choices visible for the user to fill out.
    const options=[
      tag("privacy"),
      tag("authentication"),
      tag("database"),
      tag("ai"),
      //tag("report"),
      tag("contents-list")
    ]
 

    clear_messages()


    // check inter-select dependencies

    // oracle only valid when we have an authentication service
    if(options[2].dataset.priorChoice!==undefined && options[1].dataset.priorChoice!==undefined && tag("authentication").selectedIndex<2 && tag("database").value==="oracle" ){
      // either no Authentication or Local authentication is selected
      let error_message=`You have chosen "${tag("authentication").options[tag("authentication").selectedIndex].text}" and to configure an Oracle Autonomous Database.  The Oracle option is only available for the authentication options of "${tag("authentication").options[2].text}" and "${tag("authentication").options[3].text}".`
      message({
        message: error_message,
        title: "Invalid Combination",
        kind: "error",
        seconds:8,
        show: true
      })
     //revert which ever select changed to trigger the problem
      for(let x=1;x<3;x++){
        if(options[x].selectedIndex !== parseInt(options[x].dataset.priorChoice)){
          //revert authentication  or database
          options[x].selectedIndex = parseInt(options[x].dataset.priorChoice)
        }
       }
      return
    }

 
    //set values 
    for(let x=0;x<options.length && x<6;x++){
      //clear all but selected choice descriptions
      //log(options[x].length,options[x].id, x)

      // remember prior choices
      options[x].dataset.priorChoice=options[x].selectedIndex

      // hide all choices
      for(let y=0;y<options[x].length;y++){
           
            for(const elem of document.querySelectorAll("." + options[x].id + "-" + y)){
              //log("elem", elem)
              elem.style.display="none"
            }
      }

      for(let y=0;y<options[x].length;y++){
        if(options[x].selectedIndex===y){
          // the selected option
          //log("found selected at ", y)
          for(const elem of document.querySelectorAll("." + options[x].id + "-" + y)){
            //log("elem", elem)
            elem.style.display=""
          }
        }
         
      }
      
    }
    // number the configuration steps
    let step_number=0
    for (var i = 0, row; row = tag("configuration-steps-table").rows[i]; i++) {
      //iterate through rows
      //rows would be accessed using the "row" variable assigned in the for loop
      if(row.style.display===""){
        row.querySelector(".wizard-number").innerHTML=`<div>${++step_number}.</div>`
      }
    }

    if(step_number===0){
      // no steps are visible
      tag("configuration-steps-message").innerHTML='Congratulations! The configuration you have chosen requires no additional setup.  Just click the "Apply Configuration" button below to configure your book as you have specified above.'
    }else if(step_number===1){
      // only one step is visbile
      tag("configuration-steps-message").innerHTML='There is only one more step required to get you up and running.  After you have filled in the requested information below, click the "Apply Configuration" button at the bottom of this section to configure your book as you have specified.'
    }else{
      // at least o
      tag("configuration-steps-message").innerHTML='This sections gives you step-by-step instructions to complete the setup as you configured above. After you have filled in the requested information below, click the "Apply Configuration" button at the bottom of this section to configure your book as you have specified.'
    }

  }
  function save_wizard_choices(){
    // writes all input and select choices to session storage so we can read them back after returning from stripe
    const values={}
    for(item of document.querySelectorAll("input, select, textarea")){
      if(!["privacy","authentication","database","ai","contents-list"].includes(item.id)){
      values[item.id]=item.value
      }
    }
    sessionStorage.setItem("HbXA0Z", btoa(btoa(JSON.stringify(values))))
    log("session set")
    
  }


  async function init_setup_wizard(){
    // url to prefill the code: http://127.0.0.1:5501/?page=setup-wizard&code=11212
    const url_params = get_params()
    //log("initializing setup wizard", url_params)

    const toc_list = await get_post_json(get_url("toc-list-json"))
    log("toc_list", toc_list)
    for(let x=0;x<toc_list.length;x++){
      const book=toc_list[x]
      log("book-----------",book)
      let option = document.createElement("option")
      option.value=book.post
      option.text =  book.label
      tag("contents-list").add(option)

      let p=document.createElement("p")
      p.className="contents-list-" + x
      p.innerHTML=`You chose the "${book.label}" option, which is describe as: ${book.description}` 
      tag("book-contents-container").appendChild(p)


    }


    let values_to_restore=sessionStorage.getItem("HbXA0Z")
    let new_code=[]// used for building the code to pre-configure choices

    if(values_to_restore){
      // reads all input and select choices from session storage and writes them to the page.  Used to restore values after a trip to stripe
      values_to_restore=JSON.parse(atob(atob(values_to_restore)))
      log("values",values_to_restore)
      new_code=values_to_restore["config-code"].split("")
      delete values_to_restore["config-code"]// remove the congig code so it does not get re entered
      sessionStorage.removeItem("HbXA0Z")
    }else if(url_params.code){
      // read config code from URL
      new_code=url_params.code.split("")

    }else{
      // generate code based on current configuration settings
      if(get_from_book_storage("isPrivateComputer",false)){
        new_code.push(1)
      }else{
        new_code.push(2)
      }
      //log("new_code  1",new_code)
      if(get_from_book_storage("loginType","none")==="none"){new_code.push(1)}
      if(get_from_book_storage("loginType","none")==="local"){new_code.push(2)}
      if(get_from_book_storage("loginType","none")==="gas"){new_code.push(3)}
      if(get_from_book_storage("loginType","none")==="paid"){new_code.push(4)}
      //log("new_code 2",new_code)

      if(get_from_book_storage("dbType","sqlite")==="book"){new_code.push(1)}
      if(get_from_book_storage("dbType","sqlite")==="sqlite"){new_code.push(2)}
      if(get_from_book_storage("dbType","sqlite")==="dataworld"){new_code.push(3)}
      if(get_from_book_storage("dbType","sqlite")==="oracle"){new_code.push(4)}
      //log("new_code 3",new_code)

      if(get_from_book_storage("aiType","none")==="noai"){new_code.push(1)}
      if(get_from_book_storage("aiType","none")==="gpt"){new_code.push(2)}
      //log("new_code 4",new_code)

      // //log('get_from_book_storage("reportScores","none")',get_from_book_storage("reportScores","none"))
      // if(get_from_book_storage("reportScores","none")==="none"){new_code.push(1)}
      // if(get_from_book_storage("reportScores","none")==="prof"){new_code.push(2)}
      // //("new_code 5",new_code)

      for(let x=0;x<toc_list.length;x++){
        //log("======================== toc_list[x]", x,toc_list[x])
        if(get_from_book_storage("bookContents","toc-json")===toc_list[x].post){
          new_code.push(x+1)
          break
        }
      }
      //log("new_code 6",new_code)

    }


    // amend code for when auth or db match current config and reconfiguring woudl requie information not stored.

    if(get_from_book_storage("loginType","none")==="local"){
      option = document.createElement("option")
      option.value="unchanged"
      option.text =  tag("local-auth").innerHTML
      tag("local-auth").innerHTML=tag("local-auth").innerHTML + " (reconfigure)"
      tag("authentication").add(option)
      if(new_code[1]===2){new_code[1]=5}
    }else if(get_from_book_storage("loginType","none")==="gas"){
      option = document.createElement("option")
      option.value="unchanged"
      option.text =  tag("gas-auth").innerHTML
      tag("gas-auth").innerHTML=tag("gas-auth").innerHTML + " (reconfigure)"
      tag("authentication").add(option)
      if(new_code[1]===3){new_code[1]=5}
    }

    if(get_from_book_storage("dbType","sqlite")==="oracle"){
      option = document.createElement("option")
      option.value="unchanged"
      option.text =  tag("db-oracle").innerHTML
      tag("db-oracle").innerHTML=tag("db-oracle").innerHTML + " (reconfigure)"
      tag("database").add(option)
      if(new_code[2]===4){new_code[2]=5}
    }

    //set up the page according to the config code
    tag("config-code").value=new_code.join("")      
    log(tag("config-code").value,new_code)
    config_code_onkeyup(tag("config-code"))


    
    
    tag("wizard-config").style.width = tag("wizard-config").offsetWidth + "px"
    configure_choices()
    paidUserInfo()// build the paid user interface


    if(values_to_restore){
      //fill any values from session storage in case we are returning from stripe  
      for(const [id, val] of Object.entries(values_to_restore)){
        tag(id).value=val
       // log("----->",id,val)
      }
    }else{
      // enter default values from bookStorgae
      tag("gas-deployment-id").value=get_from_book_storage("deploymentId","")
      tag("dw-read-write-token").value=get_from_book_storage("dwToken","")
      // tag("student-first-name").value=get_from_book_storage("studentFirstName","")
      // tag("student-last-name").value=get_from_book_storage("studentLastName","")
      // tag("student-email").value=get_from_book_storage("studentEmail","")
      // tag("student-id").value=get_from_book_storage("studentId","")
      // tag("course-code").value=get_from_book_storage("courseCode","")
    }

  }
  function get_step_number(doc_elem){
    // gets the step number for a step in the setup wizard. used for giving error messages
      let elem = doc_elem
      while (elem?.firstElementChild?.className !== "wizard-number") {
        elem = elem.parentNode
      }
      return elem.firstElementChild.firstElementChild.innerHTML
  }
  async function setup_wizard_apply_configuration(){
  // validates and processes the user's entered values and sets values in bookstorage. settinng up data in oracle if needed
    clear_messages()
    let p
    let gas_preconfigured // if connecting to gas, we need to know if there is an existing configuration
    let error_count=0
    let warning_count=0
    let auth_message=""// used to place a note about authorization at the end of the setup wizard's messages

    const today = new Date();
    const date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
    const time = today.getHours() + ":" + today.getMinutes().toString().padStart(2, '0') + ":" + today.getSeconds().toString().padStart(2, '0');
     
    tag("script-message").style.display="block"
    p=add_message(`Setup Wizard started woking at: ${date+' '+time}`,"lightgreen")
    p.style.fontWeight="bold"
    p.style.textAlign="center"
    p.style.backgroundColor="green"

    p.style.marginTop=".7rem"
    p.style.marginBottom=".5rem"

    add_console_dot()



    // make sure a password is supplied
    if(tag("authentication").value==="gas" || tag("authentication").value==="local") {
      p=add_message(`Evaluating password strength...`,null,"check_box_outline_blank")
      if(tag("local-login-pwd").value.length<8){

        error_count++
        add_message(`The password you supply in step ${get_step_number(tag("local-login-pwd"))} must be at least 8 characters long.  Please try again.`,"red")
        p = add_message("*** Configuration halted. ***", "red")
        p.style.paddingBottom = "1rem"
        p.style.fontWeight="bold"
        p.style.marginBottom="2rem"
        return

      }else{
        succeed_message(p)
        //p.appendChild(document.createTextNode("passed."))
      }
    }

    // check presence of validity of deployment id


    if(tag("authentication").value==="local"){

        
        auth_message="You are now logged in to this computer.  If you close your browser, you will need to supply your password again to access your saved settings."
          // we have a new local password.  Use it to encrypt values in bookStorage
       
        set_login_password(tag("local-login-pwd").value)
        BookStorage.localCanary(ncrypt("logged in",BookStorage.token()))




    }else if(tag("authentication").value==="gas"){

      p=add_message(`Checking Deployment ID...`,null,"check_box_outline_blank")

      if(tag("gas-deployment-id").value.length===0){
        fail_message(p,`You must supply a Deploymnet ID in step ${get_step_number(tag("gas-deployment-id"))}`)
        error_count++
      }else{
        // deployment ID has been supplied, check to see if we can talk to that instance
        let data = await server_post({mode:"is-configured"}, get_gas_endpoint(tag("gas-deployment-id").value))
        gas_preconfigured=data.isConfigured
        if(data?.status ==="success"){
          //p.appendChild(document.createTextNode("passed."))
          succeed_message(p)
          
          //BookStorage.loginType("gas")
          //BookStorage.deploymentId(tag("gas-deployment-id").value)
          if(gas_preconfigured){
            // we are already configured.  Need to validate if the user is allowed to reset frelay
            // first check to see if any local token is valid
            add_message("Your authentication service has already been configured.")
            p = add_message("Checking to see if the current session has authority to modify the configuration...",null,"check_box_outline_blank")
            log("Frelay is already configured")
            data = await server_post({mode:"connect"}, get_gas_endpoint(tag("gas-deployment-id").value))
            log("data", data)
            if(data?.status ==="connected"){
              // the gas token was valid, user is authorized
              set_login_password(uuid())
              server_properties_to_book_storage(data)
              succeed_message(p, "yes.")
              
              log("The token was valid")
              BookStorage.gasToken(data.token)

            }else{
              no_message(p)
              p = add_message("Checking to see if the password you supplied authorizes you to change your authentication service...",null,"check_box_outline_blank")
              log("the token was not valid")
              // token was not valid, try to login using the password
              let data = await server_post({mode:"connect",password:tag("local-login-pwd").value}, get_gas_endpoint(tag("gas-deployment-id").value))
              if(data?.status ==="connected"){
                set_login_password(uuid())
                server_properties_to_book_storage(data)
                // the password entered into the wizard is the correct one
                succeed_message(p, "yes.")
                log("the password entered was valid")
                BookStorage.gasToken(data.token)
              }else{
                no_message(p)
                p = add_message("Requesting prior password or password reset...",null,"check_box_outline_blank")
                log("the pasword was not valid")
                // neither the token nor the password supplied are valid
                // need to ask the user to supply the old password
                const login_result = await setup_wizard_login_gas()
                log("login_result",login_result) 
                if(login_result?.status==="success"){
                  succeed_message(p)
                  BookStorage.gasToken(login_result.token)
                }else{
                  fail_message(p,"Failed to connect to your authentication sevice using the deployment id and password provided.  Please check the configuration and try again.")
                  p.style.paddingBottom = "1rem"
                  error_count++
                }   
              }
            }
          }else{
            // not yet confiured
            log("frelay is not yet configured")
            data = await server_post({mode:"login",password:tag("local-login-pwd").value}, get_gas_endpoint(tag("gas-deployment-id").value))  
            log("just tried to set up", data)
            if(data?.status==="success" && data?.token){
              BookStorage.gasToken(data.token)
            }else{
              // we really don't expect to get here
              message({
                message: "Failed settiong up your authentication service.",
                title: "Unnexpected Error",
                kind: "error",
                show: true
              })
              return
            }
          }
        }else{
          fail_message(p,"Failed to connect to your authentication sevice using the deployment id provided.  Please check the configuration and try again.")
          error_count++
        }
      }
    }else if(tag("authentication").value==="paid"){
      // do we need to check paylay configuration?????????
      p = add_message("Checking for an authenticated user on this book's authentication service...",null,"check_box_outline_blank")
      const paylay_user=await getUser(false)
      if(paylay_user){
        succeed_message(p)
        p = add_message("Checking for an active subscription on this book's authentication service...",null,"check_box_outline_blank")
        // user is logged in, check for active subscription
        const userHasActiveSubscription = await PaylayClient.userHasActiveSubscription(paylay_user)
        if(userHasActiveSubscription){
          succeed_message(p)
        }else{
          fail_message(p,"When using this book's authentication serivce, you must purchase a subscription before proceeding.")
          error_count++  
        }
      }else{
        fail_message(p,"When using this book's authentication serivce, you must purchase a subscription and log in before proceeding.")
        error_count++
      }

    }  


  if(error_count===0){
    // passed all checks for authentication.  Let's set up this authenticatoin
    
    // setting the database parameter
    p = add_message(`Recording authentication choice...`,null,"check_box_outline_blank")
    if(tag("authentication").value!=="unchanged"){
      BookStorage.loginType(tag("authentication").value)
    }
    succeed_message(p, "done.")
    

    


    if(tag("authentication").value==="gas"){
      BookStorage.deploymentId(tag("gas-deployment-id").value)
      p = add_message("Setting password on your authentication service...",null,"check_box_outline_blank")
      data = await server_post({mode:"change-password",password:tag("local-login-pwd").value})  
      log("set passwprd", data)
      if(data.status==="success"){
        succeed_message(p,"done.")
        BookStorage.gasToken(data.token)

        // // get properties from backend
        // const book_storage_from_gas = await get_server_property({key:"book_storage"})
        // log("&&&&&&&&&&&&&&&&&&&&book_sorage_from_gas",book_storage_from_gas)
        // if(book_storage_from_gas.status==='success'){
        //   // we we have pulled data from gas, now write it to book storage
        //   //debugger
        //   for(const[key,val] of Object.entries(book_storage_from_gas.property)){
        //     console.log(key, val.value, typeof BookStorage[key])
        //     if(typeof BookStorage[key]!=="function"){
        //       BookStorage.addItem
        //     }
        //     BookStorage[key](JSON.parse(val.value))
        //   }
          
        //}

      }else{
        fail_message(p,data.message)
        error_count++
      }
    }

  }else{
    p.style.paddingTop = "1rem"
    p = add_message("*** Configuration halted. ***","red")
    p.style.fontWeight="bold"
    p.style.marginBottom="2rem"

    return

  }

  // check to see if a submissionInfo package is pending, if so, let's record it
  const configData = window.sessionStorage.getItem("configData")
  if(configData){
    p=add_message(`Recording your assessment submission details...`,null,"check_box_outline_blank")

    const data=JSON.parse(b64DecodeUnicode(configData.replace(/_/g, '/').replace(/-/g, '+')))
    BookStorage.submissionInfo(data.sub)

    const payload = {
      submissionType: "register",
      studentId: get_from_book_storage("submissionInfo").id
    }

    const response = await submit_backend_package(payload)

    succeed_message(p,"done.")
    // decided not to clear the configdata from session storage.  It will go away when the user closes the session , otherwise will be there for other setup wizard runnings 

  }

  //p.appendChild(document.createTextNode("passed."))
    
    if(tag("database").value==="dataworld"){
      // test data.world connection ###########################################

      p=add_message(`Checking for data.world Read/Write token...`,null,"check_box_outline_blank")

      if(tag("dw-read-write-token").value.length===0){
        fail_message(p,`You must supply your Read/write token in step ${get_step_number(tag("dw-read-write-token"))}`)
        error_count++
      }else{
        succeed_message(p)
        p=add_message(`Using token to check connection to data.world...`,null,"check_box_outline_blank")

        // check to see if the read/write token is valid
        const response = await run_db_query({
          engine:   "dataworld",
          schema:   "canvas",
          owner:    "atlas-query",
          query:    "select count(*) as museum_count from museum",
          token:    tag("dw-read-write-token").value
        })

        log("dw rewponse", response)
        if(response?.items[0]?.resultSet?.items[0]?.museum_count===undefined){
          // failed to execute query
          fail_message(p,`The Read/Write token you supplied was rejected by data.world.`)
          error_count++
        }else{
          // we got back a result
          succeed_message(p)
          BookStorage.dwToken(tag("dw-read-write-token").value)
        }
        
      }

    }else if(tag("database").value==="oracle"){
      //making sure all fields are supplied

      p = add_message(`Checking administrator username...`,null,"check_box_outline_blank")
      if(tag("username-input").value.length===0){
        fail_message(p,`You must supply the username for an Oracle database account that has permissions to create users, schema and tables.  This is usally "ADMIN".`)
        error_count++
      }else{
        succeed_message(p)
      }

      p = add_message(`Checking Oracle conneciton URL...`,null,"check_box_outline_blank")
      if(tag("url-input").value.length===0){
        fail_message(p,`You must supply the connection URL for the administrator user account.`)
        error_count++
      }else{
        succeed_message(p)
      }

      p = add_message(`Checking administrator password...`,null,"check_box_outline_blank")
      if(tag("password-input").value.length===0){
        fail_message(p,`You must supply the password for the administrator user account.`)
        error_count++
      }else{
        succeed_message(p)
      }

      if(error_count > 0){
        p = add_message("*** Configuration halted. ***", "red")
        p.style.paddingtop = "1rem"
        p.style.fontWeight="bold"
        p.style.marginBottom="2rem"

        return
      }      

      //checking oracle connection
      p=add_message(`Checking connection to Oracle...`,null,"check_box_outline_blank")
      const response = await check_oracle_connection(tag("url-input").value,tag("username-input").value,tag("password-input").value)
      switch(response.code){
          case 3: //Credentials supplied are unauthorized as server
              // bad, we have not authenticated with the admin username and passord
              fail_message(p,"The username and pasword you supplied are unable to connect.  Please check them and try again.")
              error_count++
              break
          case 10: //good credentials, not configured
              // ok, we have authenticated with the admin username and password, time to bulid
              succeed_message(p,"connected.")

              const result =  await configure_book_db(tag("username-input").value,tag("password-input").value,tag("url-input").value)
              break
          case 20: //good credentials, fully configured              
              succeed_message(p,"connected.")
              if(tag("data-use").value==="force-rebuild"){
                resp =  await configure_book_db(tag("username-input").value,tag("password-input").value,tag("url-input").value)
            
              }else{
                // attempting to update credentials without rebuilding data
                p=add_message(`Updating database user credentials with authentication service...`,null,"check_box_outline_blank")

                // rebuild the book_user connection
                const pw = genPassword()
                const response = await save_connection({ 
                  name: "SQL-Book Queries", 
                  username: "BOOK_USER", 
                  password: pw, 
                  description: "Account used for executing queries at SQL-Book.blogspot.com" ,
                  url:tag("url-input").value.split("/ords/")[0] + "/ords/book_user/_/sql",
                  id:"sql_book_connection",
                  protect:true
                })
                
                if(response.status==="success"){
                  succeed_message(p,"done.")
                  p=add_message(`Updating database user credentials on Oracle...`,null,"check_box_outline_blank")

                  const package={
                    "mode":"run-oracle-script",
                    "sql": `ALTER USER BOOK_USER IDENTIFIED BY ${pw}`,
                    "url":tag("url-input").value.split("/ords/")[0] + "/ords/"+tag("username-input").value.toLowerCase()+"/_/sql",
                    "username":tag("username-input").value,
                    "password":tag("password-input").value,
                  }

                  log("package", package)

                  let resp = await server_post(package)
                  
                  if(resp?.items[0]?.response[0]?.includes("User BOOK_USER altered")){
                    succeed_message(p,"done.")
                  }else{
                    // we don't really expect to get here
                    no_message(p,"failed.")
                    resp =  await configure_book_db(tag("username-input").value,tag("password-input").value,tag("url-input").value)
                  }
                

                }else{// could not update connection detials on backend
                  fail_message(p,response.message)
                  error_count++
    
                }
              }
              
              break
          default:    
            error_count++
            if(response.message){                
              fail_message(p,response.message)
            }else{
              fail_message(p,"Something very unexpected happened.")
            }
      }
    }


    if(error_count>0){
      p.style.paddingTop = "1rem"
      p = add_message("*** Configuration halted. ***","red")
      p.style.fontWeight="bold"
      p.style.marginBottom="2rem"

      return
    }

    // record privacy
    p = add_message(`Recording privacy choice...`,null,"check_box_outline_blank")
    BookStorage.isPrivateComputer(tag("privacy").value==="private")
    succeed_message(p, "done.")


    // setting the database parameter
    p = add_message(`Recording database choice...`,null,"check_box_outline_blank")
      if(tag("database").value!=="unchanged"){
        BookStorage.dbType(tag("database").value)
      }
    succeed_message(p, "done.")
    

    // setting ai options
    p = add_message(`Recording AI choice...`,null,"check_box_outline_blank")
    BookStorage.aiType(tag("ai").value)
    succeed_message(p, "done.")


    // // setting reporting options
    // p = add_message(`Recording reporting choice...`,null,"check_box_outline_blank")
    // BookStorage.reportScores(tag("report").value)
    // succeed_message(p, "done.")
    // if(tag("report").value==="prof"){
    //   // record the detailed fields
    //   BookStorage.studentFirstName(tag("student-first-name").value)
    //   BookStorage.studentLastName(tag("student-last-name").value)
    //   BookStorage.studentEmail(tag("student-email").value)
    //   BookStorage.studentId(tag("student-id").value)
    //   BookStorage.courseCode(tag("course-code").value)

    //   p = add_message(`Recording first name...`,null,"check_box_outline_blank")
    //   if(tag("student-first-name").value.length===0){
    //     warn_message(p,`You probably should supply a student first name.`)
    //     warning_count++
    //   }else{
    //     succeed_message(p, "done.")
    //   }
    //   p = add_message(`Recording last name...`,null,"check_box_outline_blank")
    //   if(tag("student-last-name").value.length===0){
    //     warn_message(p,`You probably should supply a student last name.`)
    //     warning_count++
    //   }else{
    //     succeed_message(p, "done.")
    //   }
    //   p = add_message(`Recording student ID...`,null,"check_box_outline_blank")
    //   if(tag("student-id").value.length===0){
    //     warn_message(p,`You probably should supply a student ID.`)
    //     warning_count++
    //   }else{
    //     succeed_message(p, "done.")
    //   }
    //   p = add_message(`Recording email...`,null,"check_box_outline_blank")
    //   if(tag("student-email").value.length===0){
    //     warn_message(p,`You probably should supply a student email.`)
    //     warning_count++
    //   }else{
    //     succeed_message(p, "done.")
    //   }
    //   p = add_message(`Recording course code...`,null,"check_box_outline_blank")
    //   if(tag("course-code").value.length===0){
    //     warn_message(p,`You probably should supply a course code.`)
    //     warning_count++
    //   }else{
    //     succeed_message(p, "done.")
    //   }
      
    // }
    

    // setting toc options
    p = add_message(`Recording Book Contents choice...`,null,"check_box_outline_blank")
    BookStorage.bookContents(tag("contents-list").value)
    succeed_message(p, "done.")




    // if we made it here, we ahve completed all valdiation and configuration
    p = add_message("Congratulations!  Your configuration is complete.")
    if(warning_count==1){
      append_to_message(p,`You had a warning that you might want to review.`,"yellow")
    }else if(warning_count>1){
      append_to_message(p,` You had ${warning_count} warnings that you should review.`,"yellow")
    }
    p.style.marginTop="1rem"
    p.style.marginBottom="2rem"

  }


  function expand_section(object_clicked){
    // toggles visibility on the next div from an h2
    let elem = object_clicked
    while (elem.tagName.toUpperCase() !== 'H2') {
      elem = elem.parentNode
    }
    const icon=elem.querySelector("span")
    elem=elem.nextElementSibling
    if(elem.style.display==="none"){
      elem.style.display=""
      icon.innerHTML="expand_less"
    }else{
      elem.style.display="none"
      icon.innerHTML="expand_more"
    }
    
  }

  function toggle_password_in_prior_cell(object_clicked){
    // toggles the password visibility in the cell directly to the left of the cell holding the object that calls this function
    let elem = object_clicked
    while (elem.tagName.toUpperCase() !== 'TD') {
      elem = elem.parentNode
    }
    elem=elem.previousElementSibling
    elem=elem.querySelector("input")
    //log("elem",elem)
    if(elem.type==="password"){
      elem.type="text"
      object_clicked.innerHTML="visibility_off"
      object_clicked.title="Hide password"
    }else{
      elem.type="password"
      object_clicked.innerHTML="visibility"
      object_clicked.title="Show password"
    }


  }

  function config_code_onkeyup(config_code_textbox){
    // used for the setup wizard.
    const options=[
      tag("privacy"),
      tag("authentication"),
      tag("database"),
      tag("ai"),
      //tag("report"),
      tag("contents-list")
    ]
    const code=config_code_textbox.value
    //validate code
    for(let x=0;x<code.length && x<6;x++){
      if(options[x].length < code[x]){
        message({
          message: "The configuration code you entered is not valid.",
          title: "Invalid Code",
          kind: "error",
          show: true
        })
        return
      }
    }

    //set values 
    for(let x=0;x<code.length && x<6;x++){
      options[x].selectedIndex=code[x]-1
    }

    configure_choices()
  }

  function init_user_profile(){
    // sets up the user-profile page when it is loaded
    tag(get_from_book_storage("aiType", "gpt")).innerHTML="check_box"
    tag(get_from_book_storage("dbType", "sqlite")).innerHTML="check_box"
    show_shared_private_details()   
  
    // check the current authentication method
    const elem = tag("login-"+BookStorage.loginType())
    elem.innerHTML="check_box"
    elem.parentNode.nextElementSibling.style.display="block"

    // speacial things we do for each login type
    if (BookStorage.loginType() === "paid") {
      //log("paid");
      paidUserInfo() // this renders the UI for this section
    }else{
      // default handling
    }

    fill_server_configuration()
    tag('uploadInput').addEventListener('change', function() {
            const fr=new FileReader();
            fr.onload=function(){import_student_data(fr.result)}
            fr.readAsText(this.files[0]);
    })
  }

function save_student_data(){
  // saves the stduent data
  const promises = []
  for(const [key,value] of Object.entries(get_data_from_element(tag("student-data")))){
      // set value in book storage
      promises.push(BookStorage[key](value))
  }

  Promise.all(promises).then(()=>{
    message({
      message: "Successfully saved your user information.",
      title: "User Information Saved",
      seconds: 8,
      show: true
    })
  }).catch(err=>{
    message({
      message: err.message,
      title: "Problem Saving value to server",
      kind: "error",
      show: true
  })
  })
}


async function get_dw_token(){
  // an awaitable dialog box
    const value = await new Promise(
      (resolve, reject)=>{
        document.body.append(ui_modal("Read/Write Token",get_dw_token_form(resolve),resolve))
        tag("token-input").focus()
      }
    )
    return value
  
    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function get_dw_token_form(resolve = () => { }, reject = () => { }) {
      const form = ui_form("auth-container ui-inline-block")
      const token_input = ui_input("ui-input ui-full-width mb2")
      token_input.id="token-input"
      token_input.value=get_from_book_storage("dwToken")
      const button_label="Save"
      const submit = ui_btn(button_label)
      const error_message = ui_div("ui-bg-clear error-message ")
      const message=ui_p()
      message.innerHTML='The data.world <a href="https://data.world/settings/advanced" target="blank">Read/Write token</a> authorizes this site to interact with data.world on your behalf so you can execute queries and see your results.'
      submit.onclick = async (e) => {
        error_message.replaceChildren()
        e.preventDefault()

        if(token_input.value.length===0){
          error_message.replaceChildren(ui_span("", "The token is required."))
        }else{
          submit.replaceChildren(ui_loading())
          submit.disabled = true
          const result=await check_dw_connection(token_input.value)
          if(result.status==="success"){
            error_message.replaceChildren()
            tag("overlay").remove()
            resolve(token_input.value)
          }else{
            error_message.replaceChildren(ui_span("", result.message))
            submit.replaceChildren(button_label)
            submit.disabled = false
          }
        }
      }
      form.append(
        message,
        ui_label("", "data.world Read/Write Token"), ui_br(),
        token_input,
        submit,
        error_message
      )
      return form
    }
  
  }

async function get_oracle_configuration(){
  // an awaitable dialog box
    const value = await new Promise(
      (resolve, reject)=>{
        document.body.append(ui_modal("Oracle Autonomous Database",get_oracle_configuration_form(resolve),resolve))
        tag("url-input").focus()
      }
    )
    return value
  
    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function get_oracle_configuration_form(resolve = () => { }, reject = () => { }) {
      const form = ui_form("auth-container ui-inline-block")
      const url_input = ui_input("ui-input ui-full-width mb2")
      url_input.id="url-input"
      url_input.value=get_from_book_storage("oracleURL")
      let button_label
      const error_message = ui_div("ui-bg-clear error-message")
      const message=ui_p("mt0")

      const username_input = ui_input("ui-input ui-full-width mb2")
      username_input.id="username-input"
      username_input.value="ADMIN"


      const password_block = ui_input_password_reveal("ui-input ui-full-width")
      const password_input = password_block.getElementsByTagName("input")[0]
      password_input.id="oracle-admin-pwd"

      const script_message  =   ui_div("script-message")
      script_message.id="script-message"
      script_message.style.display="none"
      
      const auth_block =  ui_div("",
        ui_label("", "Administrator Username"), ui_br(),username_input,
        ui_label("", "Administrator Password"), ui_br(),password_block,
      )

      const url_block = ui_div("",ui_label("", "Oracle Connection URL"), ui_br(),url_input)

      const connection_block=ui_div("",url_block,auth_block,script_message)

      if(get_from_book_storage("loginType")==='gas' || get_from_book_storage("loginType")==='paid'){
        //login type allows oracle
        message.innerHTML='Provide the connection URL for any user on your Oracle Autonomous Database.  You may need to follow the <a target="_blank" href="https://goog.le.com">instructions to configure your Oracle Autonomous Database</a> to work with this book.'
        button_label="Initiate Connection"
      }else{
        //login type does not allow oracle
        message.innerHTML='To use your Oracle Autonomous Database, you must configure this book to authenticate with either "Your Own Authentication Server" or with "This Book\'s Authentication Server".'
        button_label="OK"
        connection_block.style.display="none"
      } 

      const submit = ui_btn(button_label)
      submit.style.marginTop="1rem"

      submit.onclick = async (e) => {
        //log("clicked", e)
        error_message.replaceChildren()
        e.preventDefault()

        switch(e.target.innerHTML){
            case "OK":
                tag("overlay").remove()
                resolve(null)
                return
                break
            case "Close":
                if(submit.dataset.result==="error"){
                    tag("overlay").remove()
                    resolve(null)
                }else{
                    tag("overlay").remove()
                    resolve("connected")
                }
                return
                break
            case "Configure Datasets":

                if(username_input.value.length===0 || password_input.value.length===0){
                    error_message.replaceChildren(ui_span("", "The username and password are both required."))
                }else{
                    // we have a username and password, let's check if the are valid
                    submit.replaceChildren(ui_loading())
                    const response = await check_oracle_connection(url_input.value,username_input.value,password_input.value)
                    //response.code=10    
                    switch(response.code){
                        case 3: //Credentials supplied are unauthorized as server
                            // ok, we have authenticated with the admin username and passord
                            url_block.style.display="none"
                            auth_block.style.display="block"
                            submit.innerHTML="Configure Datasets"
                            error_message.replaceChildren(ui_span("", "The username and pasword you supplied are unable to connect.  Please check them and try again."))
                            break
                        case 10: //good credentials, not configured
                            // ok, we have authenticated with the admin username and passord, time to bulid
                            url_block.style.display="none"
                            auth_block.style.display="none"
                            script_message.style.display="block"
                            submit.style.display="none"
                            submit.dataset.result =  await configure_book_db(username_input.value, password_input.value, url_input.value)
                            submit.style.display=""
                            submit.innerHTML="Close"
                            break
                        default:    
                            if(response.message){
                                error_message.replaceChildren(ui_span("", response.message))  
                            }else{
                              error_message.replaceChildren(ui_span("", "Something very unexpected happened."))  
                            }
                    }
                }    
                break
            case "Initiate Connection":
              //debugger
                if(url_input.value.length===0){
                    error_message.replaceChildren(ui_span("", "The connection URL is required."))
                }else{
                    // try to talk to the server at the url
                    submit.replaceChildren(ui_loading())
                    const response = await check_oracle_connection(url_input.value,username_input.value,password_input.value)
                    //response.code=10
                    switch(response.code){
                        case 10: //connected but no datqabase
                            message.innerHTML = "Successfully connected to your server, yay! It looks as though we need to configure this book's data on your server.  Provide the additional information below."
                            url_block.style.display="none"
                            auth_block.style.display="block"
                            submit.innerHTML="Configure Datasets"
                            break
                        case 20: //fully configured
                            tag("overlay").remove()
                            resolve("connected")
                            break
                        default:   
                            //log("response",response) 
                            submit.innerHTML="Initiate Connection"
                            if(response.message){
                                error_message.replaceChildren(ui_span("", response.message))  
                            }else{
                              error_message.replaceChildren(ui_span("", "Something very unexpected happened."))  
                            }
                    }
                    // if(response.status="success"){
                    //     //log("oracle responded")
                    // }else{
                    //     //log("oracle failed")
                    // }

                    // submit.replaceChildren(ui_loading())
                    // submit.disabled = true
                    // const result=await check_dw_connection(url_input.value)
                    // if(result.status==="success"){
                    //     error_message.replaceChildren()
                    //     tag("overlay").remove()
                    //     resolve(url_input.value)
                    // }else{
                    //     error_message.replaceChildren(ui_span("", result.message))
                    //     submit.replaceChildren(button_label)
                    //     submit.disabled = false
                    // }
                }
                break
            default:
                console.error("button Label not recognized")    
                resolve(null)
                return                
        }

      }
      form.append(
        message,
        connection_block,
        submit,
        error_message
      )
      return form
    }
  
  }

  async function check_oracle_connection(url, username, password){
    // accepts a token and checks to see if we can connect to data.world
    const payload = {
        mode: "check-oracle-connection",
        url: url,
        update_connection_on_success:true
    }
    if(username){payload.username=username}
    if(password){payload.password=password}
    log("check_oracle_connection",payload)
    return await server_post(payload)
  }

  async function check_dw_connection(token){
    // accepts a token and checks to see if we can connect to data.world
    const url = `https://api.data.world/v0/sql/hudsonu/hudsonu`
    const options = {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token,
      },
      'method': 'POST',
      'body': JSON.stringify({
        "query": "select * from approval",
        "includeTableSchema": true,
        "queryRunToken": uuid()
      })
    }
    let response
    try {
      response = await fetch(url, options)
    } catch (e) {
      ;log("http error", e.message)
      return {status:"failure", message:e.message}
    }
    try{
      if(response.status===200){
        // OK--everything is valid
        return {status:"success", message:"Connection successful."}
      }else if(response.status===401){
        // unauthorized
        return {status:"failure", message:"The Read/Write token was rejected by data.world.  Please check it and try again."}
      }else if(response.status===404){
        return {status:"failure", message:"Contacted data.world, but could not find the verification project.  This is unexpected."}
      }
    }catch(e){  
      return {status:"failure", message:"Unexpected error: " + e.message}
    }
  }

const paidUserInfo = (() => {
  const {
    getAuth,
    onAuthStateChanged,
    signOut,
  } = firebase.auth
  const { getFunctions, httpsCallableFromURL } = firebase.functions
  const { collection, getDocs, addDoc, onSnapshot, db } = firebase.firestore

  const auth = getAuth();

  const loading = ui_div("center",
    ui_loading("")
  )



  /**
   * This method must be called once the user has been authenticated
   * @returns a url string that can be used to log in the user to thier stripe account or an 
   * empty string if there was an error in the backend.
   */
  async function getStripePortalLink() {
    try {
      const functions = getFunctions()
      const createPortalLink = httpsCallableFromURL(
        functions,
        "https://us-central1-prime-micron-374215.cloudfunctions.net/stripeCreatePortalLink"
      );
      const { data } = await createPortalLink({
        returnUrl: window.location.origin,
      })
      return data.url
    } catch (error) {
      return ""
    }
  }


  async function productAndPriceData() {
    const products = []
    const querySnapshot = await getDocs(collection(db, "products"));
    querySnapshot.forEach(async (productDoc) => {
      const product_data = productDoc.data()
      //log("product data", product_data)
      if (product_data.active) {
        products.push({
          docID: productDoc.id,
          ...product_data
        })
      }
    })
    const prices_snapshot_promise = []
    for (const product of products) {
      prices_snapshot_promise.push(getDocs(collection(db, "products", product.docID, "prices")))
    }
    const product_and_price = []
    const snapshots = await Promise.all(prices_snapshot_promise)
    for (const priceSnapshot of snapshots) {
      priceSnapshot.forEach(priceDoc => {
        const price = priceDoc.data()
        if (price.active) {
          product_and_price.push({
            product: products.find(x => x.docID === price.product),
            price: price,
            productID: price.product,
            priceID: priceDoc.id,
          })
        }
      })
    }
    return product_and_price
  }

  function managePurchaseCard(product_data, description, features, stripeLink) {
    const buy_btn = ui_btn_info("Loading")
    buy_btn.replaceChildren("Manage")
    buy_btn.onclick = () => window.location.assign(stripeLink)
    const head = ui_card_head(product_data.name, ui_first_letter_upper_case(product_data.description))
    const card = ui_card_medium(head, description, buy_btn, features)
    return card
  }

  /**
   * gets the users purchased products. If the user did not buy anything, or
   * the user is not signed in, then this method will return null. 
   * @returns
   */
  async function getPurchasedProducts(user) {
    if (!user) { return [] }
    const usersSubsSnapshot = await getDocs(collection(db, "customers", user.uid, "subscriptions"))
    const subs = []
    usersSubsSnapshot.forEach(x => x = subs.push(x.data()))
    return subs.map(x => ({ ...x, productID: x.items[0].plan.product }))
  }

  async function checkout_product(price_id, price_type, user) {
    //debugger
    if (!user) {
      user = await getUser()
    }
    const checkoutPayload = {
      price: price_id,
      success_url: window.location.origin,
      cancel_url: window.location.origin,
    }
    if (price_type === "one_time") { checkoutPayload.mode = "payment" }


    const checkout_session_ref = collection(db, "customers", user.uid, "checkout_sessions");
    const ref = await addDoc(checkout_session_ref, checkoutPayload)
    await new Promise((resolve) => {
      onSnapshot(ref, (snap) => {
        const { error, url } = snap.data();
        if (error) {
          resolve()
          alert(`An error occured: ${error.message}`);
        }
        if (url) {
          // We have a Stripe Checkout URL, let's redirect.
          resolve()
          window.location.assign(url);
        }
      });
    })



  }

  function markProductsAsPurchased(products_and_prices, purchased_products) {
    return products_and_prices.map(product_and_price => {
      const purchased_product = purchased_products.find(purchased_product => purchased_product.productID === product_and_price.productID)
      if (purchased_product) {
        return { ...product_and_price, purchased: true, }
      }
      return product_and_price 
    })
  }

  function uiProductsWithPrices(product_and_price, stripe_link, user) {
    const masterDiv = ui_div("ui-top-padding")
    const grid = ui_grid()
    for (const { product, price, priceID, purchased } of product_and_price) {
      const dollar_amount = price.unit_amount / 100
      const product_features = Object.entries(product.metadata)
        .filter((([key]) => key.match(/feature_\d+/)))
        .sort(function (a, b) {
          if (a[0] < b[0]) { return -1; }
          if (a[0] > b[0]) { return 1; }
          return 0;
        })
        .map(([_, value]) => ui_first_letter_upper_case(value))

      log(product_features)

      let price_div
      if (price.type === "one_time") {
        price_div = ui_div("center price-tag", "$", dollar_amount)
      } else {
        price_div = ui_div("center price-tag", "$", dollar_amount, " / ", price.interval)
      }

      const description = ui_card_body_item("", price_div, ui_br())
      const features = ui_div("", ui_ul("card-ul-padding", ...product_features.map(x => ui_li("", x))))
      let card
      if (purchased) {
        card = managePurchaseCard(product, description, features, stripe_link)
      } else {
        const buy_btn = ui_btn("Buy Now")
        buy_btn.onclick = async () => {
          // try to save the values on the wizard page
          try{save_wizard_choices()}catch(e){/*nothing to do on catch*/}

          buy_btn.disabled = true
          buy_btn.innerText = "Heading to checkout..."
          try {
            await checkout_product(priceID, price.type, user)
          } catch (error) {
            if (error === "user abort") {
              // the user simply quit. So we dont have to do anything.
            } else {
              console.error(error)
            }
          } finally {
            buy_btn.innerText = "Buy Now"
            buy_btn.disabled = false
          }
        }

        const head = ui_card_head(product.name, ui_first_letter_upper_case(product.description))
        card = ui_card_medium(head, description, buy_btn, features)
        
      }
      if (product_and_price.length <= 1) {
        masterDiv.append(card)
      }else{
        grid.append(ui_grid_item(card))
        masterDiv.append(grid)
      }
    }
    return masterDiv
  }

  return async () => {
    const root_node = document.getElementById("user-profile-asd")
    root_node.replaceChildren(loading)
    const product_and_price = await productAndPriceData()
    await new Promise(() => {
      onAuthStateChanged(auth, async (user) => {
        let p_a_p = product_and_price
        let stripe_link = ""
        if (user) {
          let purchased_products
          [purchased_products, stripe_link] = await Promise.all([getPurchasedProducts(user), getStripePortalLink()])
          p_a_p = markProductsAsPurchased(p_a_p, purchased_products)
          root_node.replaceChildren(profile(user))
        }else{
          root_node.replaceChildren()
        }

        const signInButton = ui_button("ui-button-link", "Have an account? Sign in")
        signInButton.onclick = getUser

        root_node.append(
          uiProductsWithPrices(p_a_p, stripe_link, user),
          ui_div("center",
            user ? "" : signInButton,
          ),
        )
      })
    })
  }
  function profile(user) {
    return ui_div("center",
      ui_div("user-info",
        ui_div("user-icon", user.email[0].toUpperCase()),
        ui_div("user-email", user.email),
        signOutUI(auth),
      ),
    )
  }
  
  
  function signOutUI(firebaseAuth) {
    const signOutBtn = ui_btn_error("Sign Out")
    signOutBtn.onclick = async () => await signOut(firebaseAuth)
    return signOutBtn
  }  
})()


