(function() {
	'use strict';
	// AJ Query
	var $ = window.$;
	var $$ = window.$$;
	var state = { account: { schedules: [] } };
	var $grantTpl;
	var $devTpl;
	var $updateTpl;
	var $headerTpl;
	var $webhookTpl;
	var $webhookHeaderTpl;
	function pad(i) {
		i = String(i);
		while (i.length < 2) {
			i = '0' + i;
		}
		return i;
	}
	function run() {
		$headerTpl = $('.js-new-webhook .js-header').outerHTML;
		$webhookHeaderTpl = $('.js-schedule .js-webhook .js-header').outerHTML;
		$('.js-schedule .js-webhooks .js-headers').innerHTML = '';
		$webhookTpl = $('.js-schedule .js-webhook').outerHTML;
		$('.js-schedule .js-webhooks').innerHTML = '';
		// after blanking all inner templates
		$devTpl = $('.js-schedule').outerHTML;
		var $form = $('.js-new-schedule');
		// Pick a date and time on an even number
		// between 10 and 15 minutes in the future
		var d = new Date(Date.now() + 10 * 60 * 1000);
		var minutes = d.getMinutes() + (5 - (d.getMinutes() % 5)) - d.getMinutes();
		d = new Date(d.valueOf() + minutes * 60 * 1000);
		$('.js-date', $form).value = d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
		$('.js-time', $form).value = pad(d.getHours()) + ':' + pad(d.getMinutes());
		$('.js-url', $form).value = 'https://enfqtbjh5ghw.x.pipedream.net';
		console.log('hello');
		$('body').addEventListener('click', function(ev) {
			if (ev.target.matches('.js-new-header')) {
				newWebhookHeader(ev.target);
			} else if (ev.target.matches('.js-rm-header')) {
				rmWebhookHeader(ev.target);
			} else if (ev.target.matches('.js-delete') && ev.target.closest('.js-webhook')) {
				deleteWebhook(ev.target.closest('.js-webhook'));
			} else {
				return;
			}
			ev.preventDefault();
			ev.stopPropagation();
		});
		$('body').addEventListener('change', function(ev) {
			var $hook = ev.target.closest('.js-new-webhook');
			if (ev.target.matches('.js-url') && $hook) {
				if (!$('.js-comment', $hook).value) {
					$('.js-comment', $hook).value = ev.target.value.replace(/https:\/\//, '').replace(/\/.*/, '');
				}
			}
		});
		$('body').addEventListener('submit', function(ev) {
			if (ev.target.matches('.js-new-schedule')) {
				newSchedule(ev.target);
			} else if (ev.target.matches('.js-schedules-list')) {
				doLogin();
			} else if (ev.target.matches('.js-schedules-new')) {
				scheduleTask();
			} else {
				return;
			}
			ev.preventDefault();
			ev.stopPropagation();
		});
	}
	function newSchedule() {
		var $hook = $('.js-new-schedule');
		//var deviceId = $hook.closest('.js-new-schedule').querySelector('.js-id').value;
		var schedule = {
			date: $('.js-date', $hook).value,
			time: $('.js-time', $hook).value,
			tz: $('.js-tz', $hook).value,
			webhooks: []
		};
		var hook = {
			comment: $('.js-comment', $hook).value,
			method: $('.js-method', $hook).value,
			url: $('.js-url', $hook).value,
			headers: {}
		};
		schedule.webhooks.push(hook);
		console.log('schedule:', schedule);
		$$('.js-header', $hook).forEach(function($head) {
			var key = $('.js-key', $head).value;
			var val = $('.js-value', $head).value;
			if (key && val) {
				hook.headers[key] = val;
			}
		});
		hook.body = $('.js-body-template', $hook).value;
		// TODO update on template change and show preview
		var opts = {
			method: 'POST',
			headers: {
				Accept: 'application/json',
				Authorization: getToken(),
				'Content-Type': 'application/json'
			},
			body: JSON.stringify(schedule),
			cors: true
		};
		/*
      state.account.devices
        .filter(function(d) {
          return d.accessToken == deviceId;
        })[0]
        .webhooks.push(hook);
      displayAccount(state.account);
      return;
    */
		window.fetch('/api/v0/schedules', opts).then(function(resp) {
			return resp
				.json()
				.then(function(data) {
					if (!data.date || !data.webhooks) {
						console.error(data);
						throw new Error('something bad happened');
					}
					state.account.schedules.push(resp.data);
					displayAccount(state.account);
				})
				.catch(function(e) {
					window.alert(e.message);
				});
		});
	}
	function newWebhookHeader($newHeader) {
		var $hs = $newHeader.closest('.js-headers');
		var $h = $newHeader.closest('.js-header');
		var $div = document.createElement('div');
		$div.innerHTML = $headerTpl;
		$hs.append($('.js-header', $div));
		$newHeader.hidden = true;
		$('.js-rm-header', $h).hidden = false;
		$('.js-key', $h).required = 'required';
		$('.js-value', $h).required = 'required';
	}
	function rmWebhookHeader($rmHeader) {
		var $h = $rmHeader.closest('.js-header');
		$h.parentElement.removeChild($h);
	}
	function deleteWebhook($hook) {
		var deviceId = $hook.closest('.js-schedule').querySelector('.js-id').value;
		var id = $('.js-id', $hook).innerText;
		var opts = {
			method: 'DELETE',
			headers: {
				Accept: 'application/json',
				Authorization: getToken()
			},
			cors: true
		};
		window.fetch('/api/iot/devices/' + deviceId + '/webhooks/' + id, opts).then(function(resp) {
			return resp.json().then(function(result) {
				if (!result.webhook) {
					console.error(result);
					window.alert('something went wrong: ' + JSON.stringify(result));
					return;
				}
				var index = -1;
				var dev = state.account.devices.filter(function(d, i) {
					return d.accessToken == deviceId;
				})[0];
				dev.webhooks.some(function(g, i) {
					if (g.id === id) {
						index = i;
						return true;
					}
				});
				if (index > -1) {
					dev.webhooks.splice(index, 1);
					displayAccount(state.account);
				}
			});
		});
	}
	function displayAccount(data) {
		state.account = data;
		console.log('[debug] Display Account:');
		console.log(data);
		var $devs = $('.js-schedules');
		$devs.innerHTML = '';
		data.schedules.forEach(function(d) {
			var $dev = $.create($devTpl);
			$('.js-id', $dev).value = d.id;
			$('.js-date', $dev).value = d.date;
			$('.js-time', $dev).value = d.time;
			$('.js-tz', $dev).value = d.tz;
			d.webhooks.forEach(function(h) {
				console.log('webhook', h);
				var $hook = $.create($webhookTpl);
				$('.js-id', $hook).innerText = h.id;
				$('.js-comment', $hook).innerText = h.comment;
				$('.js-method', $hook).innerText = h.method;
				$('.js-url', $hook).innerText = h.url;
				Object.keys(h.headers || {}).forEach(function(k) {
					var $header = $.create($webhookHeaderTpl);
					var v = h.headers[k];
					$('.js-key', $header).innerText = k;
					$('.js-value', $header).innerText = v;
					$('.js-headers', $hook).innerHTML += $header.innerHTML;
				});
				$('.js-body-template', $hook).innerText = h.body || '';
				$('.js-webhooks', $dev).innerHTML += $hook.innerHTML;
			});
			$devs.appendChild($dev);
		});
	}
	console.info('[tzdb] requesting');
	window.fetch('./tzdb.json').then(function(resp) {
		return resp.json().then(function(tzdb) {
			console.info('[tzdb] received');
			var tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
			var options = $$('.js-tz option');
			var valOpt = options[0].outerHTML; // UTC
			//var spaceOpt = options[1].outerHTML; // ----
			var innerHTML = $('.js-new-schedule .js-tz').innerHTML;
			/*
			innerHTML =
				'' +
				spaceOpt +
				innerHTML.replace(/>UTC/, '>    UTC');
      */
			//$('.js-tz').innerHTML += spaceOpt;
			//$('.js-tz').innerHTML += valOpt.replace(/UTC/g, 'custom');
			Object.keys(tzdb)
				.sort()
				.forEach(function(k) {
					var parts = k.split(' ');
					//var sep = '── ' + parts[0];
					var sep = parts[0];
					if (parts[0] !== parts[1]) {
						sep += ' / ' + parts[1] + ' (DST)';
					}
					//innerHTML += '';
					innerHTML += '';
				});
			$('.js-new-schedule .js-tz').innerHTML = innerHTML;
			console.info('[tzdb] loaded');
			run();
		});
	});
	var allSchedules = [];
	function getToken() {
		return JSON.parse(localStorage.getItem('session')).access_token;
	}
	function doLogin() {
		localStorage.setItem(
			'session',
			JSON.stringify({
				access_token: $('.js-auth-token').value
			})
		);
		$('.js-schedules-list').hidden = true;
		return window
			.fetch('/api/v0/schedules', {
				headers: { Authorization: getToken() }
			})
			.then(function(resp) {
				return resp
					.clone()
					.json()
					.then(function(schedules) {
						console.log('schedules');
						console.log(schedules);
						allSchedules = schedules;
						renderSchedules(schedules);
						state.account.schedules = schedules;
						displayAccount(state.account);
						$('.js-account').hidden = false;
					})
					.catch(function(e) {
						console.error("Didn't parse JSON:");
						console.error(e);
						console.log(resp);
						$('.js-schedules-list').hidden = false;
						window.alert(resp.status + ': ' + resp.statusText);
						return resp.text().then(function(text) {
							window.alert(text);
						});
					});
			})
			.catch(function(e) {
				console.error('Request Error');
				console.error(e);
				window.alert('Network error. Are you online?');
			});
	}
	function renderSchedules(schedules) {
		document.querySelector('.js-schedules-output').innerText = JSON.stringify(schedules, null, 2);
	}
	function scheduleTask() {
		return window
			.fetch('/api/v0/schedules/new', {
				method: 'POST',
				headers: {
					Authorization: getToken(),
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(task)
			})
			.then(function(resp) {
				return resp.json().then(function(schedule) {
					console.log('New Schedule:', schedule);
					allSchedules.push(schedule);
					renderSchedules(allSchedules);
				});
			});
	}
	console.log('whatever');
	$('.js-auth-token').value = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
	//window.addEventListener('load', run);
})();