import Immutable from 'immutable'

import yaml from 'js-yaml'
import enhanceHanson from '../lib/enhance-hanson'
import findAreaPath from '../lib/find-area-path'
import isArray from 'lodash/lang/isArray'
import some from 'lodash/collection/some'
import max from 'lodash/collection/max'
const debug = require('debug')('gobbldygook:models')

export async function loadArea({name, type, revision, source, isCustom}) {
	if (isCustom && source) {
		return {...enhanceHanson(yaml.safeLoad(source), {topLevel: true}), source}
	}

	const db = require('../lib/db')

	if (!name) {
		throw new Error(`loadArea(): 'name' must be provided`)
	}
	if (!type) {
		throw new Error(`loadArea(): 'type' must be provided`)
	}

	let query = {name: [name], type: [type]}
	if (revision) {
		query.revision = [revision]
	}

	let data
	try {
		data = await db.store('areas').query(query)
	}
	catch (err) {
		throw new Error(`Could not find area ${JSON.stringify(query)}`)
	}

	if (isArray(data) && data.length) {
		if (some(data, possibility => 'dateAdded' in possibility)) {
			data = max(data, 'dateAdded')
		}
		else {
			data = max(data, possibility => possibility.sourcePath.length)
		}
	}

	if (typeof data === 'undefined' || isArray(data)) {
		throw new Error(`the area "${name}" (${type}) could not be found with the query {name: ${name}, type: ${type}, revision: ${revision}}`)
	}

	const enhanced = enhanceHanson(data, {topLevel: true})

	return enhanced
}

export function buildAreaId({name, type, revision}) {
	return findAreaPath({name, type, revision})
}

export const StudyRecord = Immutable.Record({
	id: '',
	type: '',
	name: '',
	revision: null,
	isCustom: false,
	source: '',
	data: Promise.resolve({}),
})

export default class Study extends StudyRecord {
	constructor(args) {
		let {name, type, revision, isCustom, source} = args

		const data = loadArea({name, type, revision, source, isCustom})
			.catch(err => ({_error: err.message}))

		super({
			name,
			type,
			revision,
			isCustom,
			source,
			data,
			id: buildAreaId({name, type, revision}),
		})
	}

	edit(newSource) {
		debug('editing', this.name)
		debug(newSource)
		return this.withMutations(area => {
			area = area.set('source', newSource)
			area = area.set('isCustom', true)
			area = area.set('data', loadArea(area))
			return area
		})
	}

	toJSON() {
		return {
			type: this.type,
			name: this.name,
			revision: this.revision,
			isCustom: this.isCustom,
			source: this.source,
		}
	}
}

@@ -31,64 +31,31 @@
 le'%0A
-%0A
 import 
-yaml from 'js-yaml'%0Aimport enhanceHanson
+loadArea
  from '.
 ./li
@@ -54,28 +54,18 @@
 m '.
-.
 /l
-ib/enhance-hanson
+oad-area
 '%0Aim
@@ -91,19 +91,23 @@
 rom '../
-lib
+helpers
 /find-ar
@@ -119,1286 +119,60 @@
 th'%0A
-import isArray from 'lodash/lang/isArray'%0Aimport some from 'lodash/collection/some'%0Aimport max from 'lodash/collection/max'%0Aconst debug = require('debug')('gobbldygook:models')%0A%0Aexport async function loadArea(%7Bname, type, revision, source, isCustom%7D) %7B%0A%09if (isCustom && source) %7B%0A%09%09return %7B...enhanceHanson(yaml.safeLoad(source), %7BtopLevel: true%7D), source%7D%0A%09%7D%0A%0A%09const db = require('../lib/db')%0A%0A%09if (!name) %7B%0A%09%09throw new Error(%60loadArea(): 'name' must be provided%60)%0A%09%7D%0A%09if (!type) %7B%0A%09%09throw new Error(%60loadArea(): 'type' must be provided%60)%0A%09%7D%0A%0A%09let query = %7Bname: %5Bname%5D, type: %5Btype%5D%7D%0A%09if (revision) %7B%0A%09%09query.revision = %5Brevision%5D%0A%09%7D%0A%0A%09let data%0A%09try %7B%0A%09%09data = await db.store('areas').query(query)%0A%09%7D%0A%09catch (err) %7B%0A%09%09throw new Error(%60Could not find area $%7BJSON.stringify(query)%7D%60)%0A%09%7D%0A%0A%09if (isArray(data) && data.length) %7B%0A%09%09if (some(data, possibility =%3E 'dateAdded' in possibility)) %7B%0A%09%09%09data = max(data, 'dateAdded')%0A%09%09%7D%0A%09%09else %7B%0A%09%09%09data = max(data, possibility =%3E possibility.sourcePath.length)%0A%09%09%7D%0A%09%7D%0A%0A%09if (typeof data === 'undefined' %7C%7C isArray(data)) %7B%0A%09%09throw new Error(%60the area %22$%7Bname%7D%22 ($%7Btype%7D) could not be found with the query %7Bname: $%7Bname%7D, type: $%7Btype%7D, revision: $%7Brevision%7D%7D%60)%0A%09%7D%0A%0A%09const enhanced = enhanceHanson(data, %7BtopLevel: true%7D)%0A%0A%09return enhanced%0A%7D
+const debug = require('debug')('gobbldygook:models')
 %0A%0Aex

use loadArea in Study()