export class UI {
	constructor(version, theme) {//{{{
		document.getElementById('button-run').
			addEventListener('click', evt => evt.preventDefault())

		document.addEventListener('keydown', evt => this.keyHandler(evt))

		document.querySelector('input[name="name"]').focus()

		this.version = version
		this.theme = theme
		this.datapoints = []
	}//}}}
	render() {//{{{
		document.querySelectorAll('.datapoints .datapoint').forEach(el => el.remove());

		const datapoints = document.querySelector('.datapoints')

		let html = Object.keys(this.trigger.datapoints).sort().map(dpName => {
			const dp = this.trigger.datapoints[dpName]
			return `
				<div class="datapoint name ${dp.Found ? 'valid' : 'invalid'}"><b>${dp.Name}</b></div>
				<div class="datapoint value">${dp.Found ? dp.LastDatapointValue.TemplateValue : ''}</div>
				<div class="daatpoint values"><a href="/datapoint/values/${dp.ID}"><img src="/images/${this.version}/${this.theme}/values.svg"></a></div>
				<div class="datapoint delete"><a href="#" onclick="_ui.deleteDatapoint('${dp.Name}')"><img src="/images/${this.version}/${this.theme}/delete.svg"></a></div>
			`
		}).join('')
		datapoints.innerHTML += html
	}//}}}
	setTrigger(t) {//{{{
		this.trigger = t
	}//}}}
	run() {//{{{
		this.trigger.run()
	}//}}}
	keyHandler(evt) {//{{{
		if (!(evt.altKey && evt.shiftKey))
			return

		evt.preventDefault()
		evt.stopPropagation()

		switch (evt.key) {
			case 'T':
				this.run()
				break

			case 'S':
				this.update()
				break
		}
	}//}}}
	addDatapoint() {//{{{
		const dlg = document.getElementById('dlg-datapoints')
		const datalist = document.getElementById('list-datapoints')
		dlg.showModal()

		fetch('/datapoints?format=json')
			.then(data => data.json())
			.then(json => {
				this.datapoints = json

				let html = ''
				this.datapoints.forEach(dp => {
					html += `<option value="${dp.Name}">`
				})
				datalist.innerHTML = html
			})
			.catch(err => alert(err))
	}//}}}
	async chooseDatapoint() {//{{{
		const dlg = document.getElementById('dlg-datapoints')
		const datapoint = document.getElementById('datapoint').value
		const dp = this.datapoints.find(dp => dp.Name == datapoint)

		if (dp === undefined) {
			alert('Invalid datapoint')
			return
		}

		this.trigger.addDatapoint(dp)
			.then(() => {
				dlg.close()
				this.render()
			})
	}//}}}
	deleteDatapoint(name) {//{{{
		if (!confirm(`Remove datapoint ${name} from this trigger?`)) {
			return
		}

		delete this.trigger.datapoints[name]
		_ui.update(true)
	}//}}}
	update(stayOnSamePage) {//{{{
		const form = document.getElementById('form-trigger')
		var formData = new FormData(form)
		Object.keys(this.trigger.datapoints).forEach(name => formData.append("datapoints[]", name))
		fetch(form.action, {
			method: 'POST',
			body: formData,
		})
			.then(resp => {
				if (stayOnSamePage) {
					location.reload()
					return
				}

				if (resp.redirected) {
					location.href = resp.url
					return
				}
				return resp.json()
			})
			.then(json => {
				if (json)
					alert(json.Error)
			})
			.catch(err => alert(err))
	}//}}}
}

export class Trigger {
	constructor(id, name, datapoints) {//{{{
		this.id = id
		this.name = name
		this.datapoints = datapoints
	}//}}}
	run() {//{{{
		const result = document.getElementById('run-result')
		const classes = result.classList
		const expr = document.getElementById('expr').value

		fetch(`/trigger/run/${this.id}`, {
			method: 'POST',
			cache: 'no-cache',
			body: expr,
		})
			.then(data => data.json())
			.then(json => {
				if (!json.OK) {
					classes.remove('ok')
					classes.add('error')
					result.innerText = json.Error
					return
				}

				classes.remove('error')
				classes.add('ok')
				result.innerText = json.Output
			})
			.catch(err => alert(err))
	}//}}}
	async addDatapoint(dp) {//{{{
		return fetch(`/trigger/addDatapoint/${this.id}/${dp.Name}`)
			.then(data => data.json())
			.then(json => {
				if (!json.OK) {
					alert(json.Error)
					return
				}
				this.datapoints[dp.Name] = json.Datapoint
			})
	}//}}}
}
