import { get, isEmpty } from "lodash-es";
import React from "react";
import { isArrayType, isObjectType } from "../schema";
/**
 *
 * @param title
 */
export function renderTitle(title) {
    if (!title) {
        return;
    }
    return React.createElement('h1', { className: 'mdc-typography mdc-typography--headline1' }, title);
}
/**
 *
 * @param description
 */
export function renderDescription(description) {
    if (!description) {
        return;
    }
    return React.createElement('limel-markdown', {
        value: description,
    });
}
/**
 * Find a suitable title for a nested structure.
 *
 * If an object has the key 'title' it will have priority, followed by the key 'name'.
 * If 'title' nor 'name' is found, a required item will be considered.
 * Otherwise the first occurrence of a nonempty string is chosen.
 *
 * @param data - the data to find the title for
 * @param fieldSchema - schema for the item
 * @param formSchema - schema for the form
 * @returns describing title of the data
 */
export function findTitle(data, fieldSchema, formSchema) {
    if (!data) {
        return null;
    }
    if (Array.isArray(data) && isObjectType(fieldSchema.items)) {
        return findTitle(data[0], fieldSchema, formSchema);
    }
    if (Array.isArray(data) || typeof data !== 'object') {
        return findSchemaTitle(data, fieldSchema);
    }
    const subSchema = findSubSchema(fieldSchema, formSchema);
    data = sortDataByProperties(data, subSchema.properties);
    const firstEntry = findFirstEntry(data, subSchema);
    if (!firstEntry) {
        return null;
    }
    if (!subSchema.properties) {
        return null;
    }
    const [key, value] = firstEntry;
    return findTitle(value, subSchema.properties[key], formSchema);
}
function sortDataByProperties(data, properties) {
    if (!properties || isEmpty(properties)) {
        return data;
    }
    const newData = {};
    for (const key of Object.keys(properties))
        newData[key] = data[key];
    return newData;
}
function findFirstEntry(data, subSchema) {
    const entries = [
        ['title', data.title],
        ['name', data.name],
        getRequiredEntry(data, subSchema),
        ...Object.entries(data),
    ];
    return entries.find((entry) => {
        const value = entry[1];
        return !!value && typeof value !== 'boolean';
    });
}
function getRequiredEntry(data, subSchema) {
    if (!('required' in subSchema)) {
        return [null, null];
    }
    const firstNonEmptyRequiredKey = Object.keys(data).find((key) => subSchema.required.includes(key));
    if (!firstNonEmptyRequiredKey) {
        return [null, null];
    }
    return [firstNonEmptyRequiredKey, data[firstNonEmptyRequiredKey]];
}
function findSubSchema(schema, formSchema) {
    let subSchema = schema;
    if (isArrayType(schema)) {
        subSchema = schema.items;
    }
    if (subSchema.$ref) {
        const path = subSchema.$ref.split('/').slice(1).join('.');
        subSchema = get(formSchema, path);
    }
    return subSchema;
}
function findSchemaTitle(value, schema) {
    var _a;
    if (isArrayType(schema) &&
        schema.items.anyOf) {
        const titles = schema.items.anyOf
            .filter((item) => value.includes(item.const))
            .map((item) => item.title);
        return titles.join(', ');
    }
    if (schema.oneOf) {
        return (((_a = schema.oneOf.find((item) => value === item.const)) === null || _a === void 0 ? void 0 : _a.title) || `${value} is an invalid option`);
    }
    return value;
}
