import R from 'ramda';
import isObject from 'lodash/isObject';
import isNumber from 'lodash/isNumber';
import isBoolean from 'lodash/isBoolean';
import { createElement } from 'react';

var li = R.partial(createElement, ['li', null]);
var dl = R.partial(createElement, ['dl', null]);
var dtAttrs = R.partial(createElement, ['dt']);
var ddAttrs = R.partial(createElement, ['dd']);
var ol = R.partial(createElement, ['ol', null]);
var code = R.partial(createElement, ['code', null]);
var em = R.partial(createElement, ['em', null]);
var p = R.partial(createElement, ['p', null]);

var renderObjectItem = function renderObjectItem(key, value) {
	return [dtAttrs({ key: 'key-' + key }, key), ddAttrs({ key: 'value-' + key }, renderJSON(value))];
};

var renderArrayItem = function renderArrayItem(value) {
	return li(renderJSON(value));
};

var renderObject = R.pipe(R.toPairs,
//R.sortBy(R.prop(0)),
R.map(R.apply(renderObjectItem)), R.tap(function (items) {
	return console.log('rendered', items);
}), R.flatten, dl);

var renderArray = R.pipe(R.map(renderArrayItem), ol);

var renderNumber = R.pipe(code, p);

var renderBoolean = R.pipe(function (boolean) {
	return boolean ? 'yes' : 'no';
}, em, p);

var renderString = p;

var renderJSON = R.cond([[Array.isArray, renderArray], [isObject, renderObject], [isNumber, renderNumber], [isBoolean, renderBoolean], [R.T, renderString]]);

var renderJSONError = function renderJSONError(error) {
	return createElement('h2', null, 'JSON is invalid ' + error);
};

var renderSerializedJSON = R.tryCatch(R.pipe(JSON.parse, renderJSON), renderJSONError);

var JSONComponent = R.converge(R.call, [R.ifElse(R.prop('isDeserialized'), R.always(renderJSON), R.always(renderSerializedJSON)), R.prop('json')]);

export default JSONComponent;