{{ define "schema-form" }}
  {{ $readonly := .ReadOnly }}
  {{ $networks := .AvailableNetworks }}
  {{ $clusters := .AvailableClusters }}
  {{ $data := .Data }}
  {{ range $f := .Schema.Fields }}
  {{ $name := $f.Name }}
  {{ $schema := $f.Schema }}
    {{ if eq $schema.Kind 0 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
		  <input type="checkbox" role="swtich" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.checked)" {{ if $readonly }}disabled{{ end }} {{ if index $data $name }}checked{{ end }} />
          {{ $schema.Name }}
      </label>
    {{ else if eq $schema.Kind 7 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          {{ $schema.Name }}
		  <input type="text" name="{{ $name }}" oninput="valueChanged({{ $name }}, parseInt(this.value))" {{ if $readonly }}disabled{{ end }} value="{{ index $data $name }}" />
      </label>
    {{ else if eq $schema.Kind 1 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          {{ $schema.Name }}
		  <input type="text" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.value)" {{ if $readonly }}disabled{{ end }} value="{{ index $data $name }}" />
	  </label>
    {{ else if eq $schema.Kind 4 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          {{ $schema.Name }}
		  <input type="text" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.value)" {{ if $readonly }}disabled{{ end }} value="{{ index $data $name }}" />
      </label>
	{{ else if eq $schema.Kind 12 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          {{ $schema.Name }}
		  <details class="dropdown">
			  {{ $selectedCluster := index $data $name }}
			  {{ if not $selectedCluster }}
 			    {{ $selectedCluster = "default" }}
			  {{ end }}
			  <summary id="{{ $name }}">{{ $selectedCluster }}</summary>
			  <ul>
				  {{ range $clusters }}
					  {{ $selected := eq $selectedCluster .Name }}
					  <li>
						  <label>
							  <input type="radio" name="{{ $name }}" oninput="clusterSelected('{{ $name }}', '{{ .Name }}', this.checked)" {{ if $selected }}checked{{ end }} />
							  {{ .Name }}
						  </label>
					  </li>
				  {{ end }}
			  </ul>
		  </details>
      </label>
	{{ else if eq $schema.Kind 3 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          {{ $schema.Name }}
		  <details class="dropdown">
			  {{ $selectedNetwork := index $data $name }}
			  <summary id="{{ $name }}">{{ $selectedNetwork }}</summary>
			  <ul>
				  {{ range $networks }}
					  {{ $selected := eq $selectedNetwork .Name }}
					  <li>
						  <label>
							  <input type="radio" name="{{ $name }}" oninput="networkSelected('{{ $name }}', '{{ .Name }}', '{{ .Name }} - {{ .Domain }}', this.checked)" {{ if $selected }}checked{{ end }} />
							  {{ .Name }} - {{ .Domain }}
						  </label>
					  </li>
				  {{ end }}
			  </ul>
		  </details>
      </label>
	{{ else if eq $schema.Kind 10 }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          {{ $schema.Name }}
		  <details class="dropdown">
			  {{ $selectedNetworks := index $data $name }}
			  <summary id="{{ $name }}">{{ $selectedNetworks | join "," }}</summary>
			  <ul>
				  {{ range $networks }}
					  {{ $networkName := .Name }}
					  {{ $selected := false }}
					  {{ range $selectedNetworks }}
						  {{ if eq . $networkName }}
							  {{ $selected = true }}
						  {{ end }}
				      {{ end }}
					  <li>
						  <label>
							  <input type="checkbox" name="{{ $networkName }}" oninput="multiNetworkSelected('{{ $name }}', '{{ $networkName }}', this.checked)" {{ if $selected }}checked{{ end }} />
							  {{ .Name }} - {{ .Domain }}
						  </label>
					  </li>
				  {{ end }}
			  </ul>
		  </details>
      </label>
	{{ else if eq $schema.Kind 5 }}
	  {{ $auth := index $data $name }}
	  {{ $authEnabled := false }}
	  {{ $authGroups := "" }}
	  {{ if and $auth (index $auth "enabled") }}{{ $authEnabled = true }}{{ end }}
	  {{ if and $auth (index $auth "groups") }}{{ $authGroups = index $auth "groups" }}{{ end }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
		  <input type="checkbox" role="swtich" name="authEnabled" oninput="valueChanged('{{- $name -}}.enabled', this.checked)" {{ if $readonly }}disabled{{ end }} {{ if $authEnabled  }}checked{{ end }} />
          <span>Require authentication</span>
      </label>
      <label for="authGroups">
          <span>Authentication groups</span>
		  <input type="text" name="authGroups" oninput="valueChanged('{{- $name -}}.groups', this.value)" {{ if $readonly }}disabled{{ end }} value="{{ $authGroups }}" />
      </label>
	{{ else if eq $schema.Kind 6 }}
 	  {{ $sshKey := index $data $name }}
	  {{ $public := "" }}
	  {{ $private := "" }}
	  {{ if $sshKey }}{{ $public = index $sshKey "public" }}{{ end }}
	  {{ if $sshKey }}{{ $private = index $sshKey "private" }}{{ end }}
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          <span>Public Key</span>
		  <textarea name="{{ $name }}-public" disabled>{{ $public }}</textarea>
      </label>
      <label {{ if $schema.Advanced }}hidden{{ end }}>
          <span>Private Key</span>
		  <textarea name="{{ $name }}-private" disabled>{{ $private }}</textarea>
      </label>
    {{ end }}
  {{ end }}
{{ end }}

{{ define "header" }}
  {{ .App.Icon }}
  <h1>{{ .App.Name }}</h1>
{{ end }}

{{ define "extra_menu" }}
  <li><a href="/app/{{ .App.Slug }}" {{ if eq $.CurrentPage .App.Name }}class="primary"{{ end }}>{{ .App.Name }}</a></li>
  {{ range .Instances }}
  <li><a href="/instance/{{ .Id }}" {{ if eq $.CurrentPage .Id }}class="primary"{{ end }}>{{ .Id }}</a></li>
  {{ end }}
{{ end }}

{{ define "content"}}
  {{ $schema := .App.Schema }}
  {{ $networks := .AvailableNetworks }}
  {{ $clusters := .AvailableClusters }}
  {{ $instance := .Instance }}

  <form id="config-form">
	  {{ if $instance }}
		{{ template "schema-form" (dict "Schema" $schema "AvailableNetworks" $networks "AvailableClusters" $clusters "ReadOnly" false "Data" ($instance.InputToValues $schema)) }}
	  {{ else }}
		{{ template "schema-form" (dict "Schema" $schema "AvailableNetworks" $networks "AvailableClusters" $clusters "ReadOnly" false "Data" (dict)) }}
	  {{ end }}
	  {{ if $instance }}
		<div class="grid">
		  <button type="submit" id="submit" name="update">Update</button>
		  <button type="submit" id="uninstall" name="remove">Uninstall</button>
		</div>
	  {{ else }}
		<button type="submit" id="submit">{{ if $instance }}Update{{ else }}Install{{ end }}</button>
	  {{ end }}
  </form>

<div id="toast-failure" class="toast hidden">
  <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2S2 6.477 2 12s4.477 10 10 10Zm3-6L9 8m0 8l6-8"/></svg> {{ if $instance }}Update failed{{ else}}Install failed{{ end }}
</div>

<div id="toast-uninstall-failure" class="toast hidden">
  <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2S2 6.477 2 12s4.477 10 10 10Zm3-6L9 8m0 8l6-8"/></svg> Failed to uninstall application
</div>

<script>
 let config = {{ if $instance }}JSON.parse({{ toJson ($instance.InputToValues $schema) }}){{ else }}{}{{ end }};

 function setValue(name, value, config) {
  let items = name.split(".")
  for (let i = 0; i < items.length - 1; i++) {
    if (!(items[i] in config)) {
      config[items[i]] = {}
    }
    config = config[items[i]];
  }
  config[items[items.length - 1]] = value;
 }

 function getValue(name, value) {
  let items = name.split(".")
  for (let i = 0; i < items.length - 1; i++) {
    if (!(items[i] in config)) {
      config[items[i]] = {}
    }
    config = config[items[i]];
  }
  return config[items[items.length - 1]];
 }

 function valueChanged(name, value) {
	 setValue(name, value, config);
 }

 function clusterSelected(name, cluster, selected) {
	console.log(selected);
	setValue(name, cluster, config);
	let summary = document.getElementById(name);
	summary.innerHTML = cluster;
	summary.parentNode.removeAttribute("open");
 }

 function networkSelected(name, network, label, selected) {
	console.log(selected);
	setValue(name, network, config);
	let summary = document.getElementById(name);
	summary.innerHTML = label;
	summary.parentNode.removeAttribute("open");
 }

 function multiNetworkSelected(name, network, selected) {
	 let v = getValue(name, config);
	 if (v === undefined) {
		 v = [];
	 }
	 if (selected) {
		 v.push(network);
	 } else {
		 v = v.filter((n) => n != network);
	 }
	 setValue(name, v, config);
	 document.getElementById(name).innerHTML = v.join(",");
 }

 function disableForm() {
     document.querySelectorAll("#config-form input").forEach((i) => i.setAttribute("disabled", ""));
     document.querySelectorAll("#config-form select").forEach((i) => i.setAttribute("disabled", ""));
     document.querySelectorAll("#config-form button").forEach((i) => i.setAttribute("disabled", ""));
 }

 function enableForm() {
     document.querySelectorAll("[aria-busy]").forEach((i) => i.removeAttribute("aria-busy"));
     document.querySelectorAll("#config-form input").forEach((i) => i.removeAttribute("disabled"));
     document.querySelectorAll("#config-form select").forEach((i) => i.removeAttribute("disabled"));
     document.querySelectorAll("#config-form button").forEach((i) => i.removeAttribute("disabled"));
 }

 function installStarted() {
     const submit = document.getElementById("submit");
     submit.setAttribute("aria-busy", true);
     submit.innerHTML = {{ if $instance }}"Updating ..."{{ else }}"Installing ..."{{ end }};
     disableForm();
 }

 function uninstallStarted() {
     const submit = document.getElementById("uninstall");
     submit.setAttribute("aria-busy", true);
     submit.innerHTML = "Uninstalling ...";
     disableForm();
 }

 function actionFinished(toast) {
     enableForm();
     toast.classList.remove("hidden");
     setTimeout(
         () => toast.classList.add("hidden"),
         2000,
     );
 }

 function installFailed() {
     actionFinished(document.getElementById("toast-failure"));
 }

 function uninstallFailed() {
     actionFinished(document.getElementById("toast-uninstall-failure"));
 }

 const submitAddr = {{ if $instance }}"/api/instance/{{ $instance.Id }}/update"{{ else }}"/api/app/{{ .App.Slug }}/install"{{ end }};

 async function install() {
     installStarted();
	 const resp = await fetch(submitAddr, {
		 method: "POST",
		 headers: {
			 "Content-Type": "application/json",
			 "Accept": "application/json",
		 },
		 body: JSON.stringify(config),
	 });
     if (resp.status === 200) {
		 window.location = await resp.text();
	 } else {
         installFailed();
     }
 }

 async function uninstall() {
     {{ if $instance }}
     uninstallStarted();
	 const resp = await fetch("/api/instance/{{ $instance.Id }}/remove", {
         method: "POST",
     });
     if (resp.status === 200) {
		 window.location = await resp.text();
     } else {
         uninstallFailed();
     }
     {{ end }}
 }

 const configForm = document.getElementById("config-form");
 if (configForm) {
	 configForm.addEventListener("submit", (event) => {
		 event.preventDefault();
		 if (event.submitter.id === "submit") {
			 install();
		 } if (event.submitter.id === "uninstall") {
			 uninstall();
		 }
	 });
 }
</script>

{{end}}
