// global state window.State = {

active_tab: 'response',
request:    {},
full_url:   '',

set_request: (full_url) => {
  State.full_url = full_url

  parts    = full_url.split('?')
  parts[1] = parts[1] || ''

  State.request = {
    host:   api_opts.mount_on,
    path:   parts[0].replace(api_opts.mount_on, ''),
    params: parts[1],
    object: {}
  }

  for (el of parts[1].split('&')) {
    let [key, value] = el.split('=', 2)
    State.request.object[key] = value
  }

  return State.request
},

}

// generic modal interface window.Modal = {

render: (title, data) => {
  $('#modal .modal-title').html(title)
  $('#modal .modal-body').html(data)
  $('#modal').show()
},
close: () => {
  $('#modal').hide()
}

}

// form in modal box window.ModalForm = {

render: (title, params) => {
  let data = []

  data.push(`<form onsubmit="TabResponse.render('${title}', this); return false;">`)
  data.push(`  <table class="table">`)

    if (title.includes('/:id/')) {
      data.push(`    <tr><td><label>ID</label></td><td><input id="api_id_value" type="text" class="form-control" value="" autocomplete="off"  /></td></tr>`)
    }

  for (let [name, vals] of Object.entries(params)) {
    data.push(`  <tr>`)
    data.push(`    <td><label>${name}</label></td><td>`)

    if (vals.type == 'boolean') {
      data.push(`    <input type="checkbox" class="form-control" name="${name}" style="width: 20px; height: 20px;" />`)
    } else {
      data.push(`    <input type="text" class="form-control" name="${name}" value="" autocomplete="off" />`)
    }

    if (vals.default) {
      data.push(`<small class="form-text text-muted">default: ${vals.default}</small>`)
    }

    data.push(`    </td></tr>`)
  }

  data.push(`  <tr><td></td><td><button class="btn btn-outline-primary">Execute API request</button></td></tr>`)
  data.push(`  </table>`)
  data.push(`</form>`)

  data = `${data.join("\n")}<div id="api_result"></div>`

  Modal.render(title, data);
}

}

// backend api call window.TabResponse = {

render: (url, form) => {
  let post   = $(form).serialize()
  let id_val = $('#api_id_value').val()

  if (id_val) {
    url = url.replace('/:id/', () => '/'+id_val+'/' )
  }

  full_url = url
  if (post) full_url += `?${post}`

  if (url.includes('/:id/')) {
    alert('ID is not defined')
    return
  }

  State.set_request(full_url)

  TabResponse.render_tab_data()

  let bearer = AuthButton.get()
  if (bearer) {
    post += post ? '&' : ''
    post += 'api_token=' + bearer
  }

  $.ajax({
    type: 'POST',
    url: url,
    data: post,
    complete: (response) => {
      State.response = JSON.parse(response.responseText);
      TabResponse.render_tab_data()
    }
  })
},

setActiveTab: (node, name) => {
  let el = $(node)
  // debugger
  el.parents('ul').find('a').removeClass('active')
  el.addClass('active')

  State.active_tab = name
  TabResponse.render_tab_data()
},

render_tab_data: () => {
  let tabs   = ['response', 'curl', 'javascript', 'ruby']

  let out = []
  out.push(`<div id="api_response"><br /><button class="btn btn-sm btn-outline-info" style="float: right; margin-top: -4px; margin-bottom: -30px;" onclick="$('#api_response').remove()">close</button>`)

  out.push(`<ul class="nav nav-tabs" style="margin-left:0; margin-bottom: 15px;">`)

  for (name of tabs) {
    let is_active = State.active_tab == name ? ' active' : ''
    out.push(`<li class="nav-item"><a class="nav-link ${is_active}" href="#" onclick="TabResponse.setActiveTab(this, '${name}'); return false;">${name}</a></li>`)
  }

  out.push(`</ul>`)

  out.push(TabResponse.format[State.active_tab]())
  $('#api_result').html(out.join("\n\n"))
},

format: {
  response: () => {
    let data = JSON.stringify(State.response || {}, null, 2)
    let url  = `<a href="${State.full_url}">${State.full_url}</a>`

    return `<p>${url}</p><pre class="code">${data}</pre></div>`
  },

  curl: () => {
    out = []

    out.push(`# PS: you can send post data as JSON as well`)
    out.push(`# JSON export is a default, "Accept: application/json" header is not needed`)
    out.push(``)

    out.push(`curl -s -X POST\\`)

    let token = AuthButton.get()
    if (token) {
      out.push(`  -H "Authorization: Bearer ${token}"\\`)
    }

    url = State.request

    if (url.params) out.push(`  --data '${url.params}'\\`)

    out.push(`  ${url.host}${url.path}`)

    let parts = url.path.split('/')

    let opts = {
      id:     'foo-rand',
      class:  parts.shift(),
      action: parts,
      params: State.request.object,
      token:  token
    }

    out.push(``)
    out.push(`# or json rpc style`)
    out.push(`curl -s -X POST\\`)
    out.push(`  --data '${JSON.stringify(opts)}'\\`)
    out.push(`  ${url.host.replace(/\/$/, '')}`)

    return `<pre class="code">${out.join("\n")}</pre></div>`
  },

  ruby: () => {
    out = []

    let params = JSON.stringify(State.request.object)
    let parts  = State.request.path.split('/')

    out.push `# gem install 'joshua'`
    out.push `require 'joshua/remote'\n`

    out.push(`api = JoshuaRemote.new '${State.request.host.replace(/\/$/, '')}'`)

    let token = AuthButton.get()
    if (token) {
      out.push(`api.auth_token = '${token}'`)
    }

    if (parts[2]) {
      out.push(`api.${parts[0]}(${parts[1]}).${parts[2]}(${params})`)
      out.push(`# or -> api.call('${parts[0]}/${parts[1]}/${parts[2]}', ${params})`)
      out.push(`# or -> api.call(:${parts[0]}, ${parts[1]}, :${parts[2]}, ${params})`)
    } else {
      out.push(`api.${parts[0]}.${parts[1]}(${params})`)
      out.push(`# or -> api.call('${parts[0]}/${parts[1]}', ${params})`)
      out.push(`# or -> api.call(:${parts[0]}, :${parts[1]}, ${params})`)
    }

    out.push(`api.success?`)
    out.push(`api.response`)
    return `<pre class="code">${out.join("\n")}</pre></div>`
  },

  javascript: () => {
    out = []
    out.push(`const axios = require('axios').default;`)
    out.push(``)
    out.push(`axios.post(`)
    out.push(`  '${State.full_url.split('?')[0]}',`)
    out.push(`  ${JSON.stringify(State.request.object)},`)

    let token = AuthButton.get()
    if (token) {
      out.push(`  { headers: { Authorization: 'Bearer ${token}' } }`)
    }

    out.push(`).then((response) => { });`)
    return `<pre class="code">${out.join("\n")}</pre></div>`
  }
}

}

// auth botton window.AuthButton = {

set: () => {
  if (api_opts.bearer) {
    Modal.render('Bearer token', api_opts.bearer)
  } else {
    let token = prompt('Bearer token?', AuthButton.get() || '')

    if (token != null) {
      localStorage.setItem('auth_token', token)
    }
 }

  AuthButton.draw()
},

get: () => {
  return api_opts.bearer || localStorage.getItem('auth_token')
},

draw: () => {
  let value = AuthButton.get()
  let text  = value ? `Yes` : 'n/a'

  $('#bearer_button').html(`Bearer Auth: <bold>${text}</bold>`)
}

}

AuthButton.draw()

// close dialog on escape document.onkeydown = (evt) => {

evt = evt || window.event;
if (evt.keyCode == 27) {
  Modal.close();
}

};