/*!
 * Custom elements for Nanopore-Digital Web applications
 */
import { dashToPascalCase } from "./utils";
export const createComponentDefinition = (importTypes, componentModelConfig, includeCustomElement = false) => (cmpMeta) => {
    const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
    const importAs = includeCustomElement
        ? 'define' + tagNameAsPascal
        : 'undefined';
    let props = [];
    let attrs = [];
    if (Array.isArray(cmpMeta.properties) && cmpMeta.properties.length > 0) {
        attrs = cmpMeta.properties.filter((prop) => prop.attribute).map((prop) => `${prop.name}: '${prop.attribute}'`);
    }
    if (Array.isArray(cmpMeta.properties) && cmpMeta.properties.length > 0) {
        props = cmpMeta.properties.map((prop) => `'${prop.name}'`);
    }
    if (Array.isArray(cmpMeta.events) && cmpMeta.events.length > 0) {
        props = [...props, ...cmpMeta.events.map((event) => `'${event.name}'`)];
    }
    let templateString = `
export const ${tagNameAsPascal} = /*@__PURE__*/ defineContainer<${importTypes}.${tagNameAsPascal}>('${cmpMeta.tagName}', ${importAs}`;
    const findModel = componentModelConfig &&
        componentModelConfig.find((config) => config.elements.includes(cmpMeta.tagName));
    if (attrs.length > 0) {
        templateString += `, {
    ${attrs.length > 0 ? attrs.join(',\n  ') : ''}
}`;
    }
    else if (findModel || !!props.length) {
        /**
         * If there are no attr but v-model or props used:
         * pass an empty array so defineContainer properties
         * isn't off by one space
         **/
        templateString += `, {}`;
    }
    if (props.length > 0) {
        templateString += `, [
  ${props.length > 0 ? props.join(',\n  ') : ''}
]`;
    }
    else if (findModel) {
        /**
         * If there are no attr but v-model or props used:
         * pass an empty array so defineContainer properties
         * isn't off by one space
         * Note: If you are using v-model then
         * the both props and attrs array should never be empty
         * as there must be a prop for v-model to update,
         * but this check is there so builds do not crash.
         */
        templateString += `, []`;
    }
    if (findModel) {
        const targetProp = findModel.targetAttr;
        /**
         * If developer is trying to bind v-model support to a component's
         * prop, but that prop was not defined, warn them of this otherwise
         * v-model will not work as expected.
         */
        if (!props.includes(`'${targetProp}'`) && !attrs.includes(`'${targetProp}'`)) {
            console.warn(`Your '${cmpMeta.tagName}' component is configured to have v-model support bound to '${targetProp}', but '${targetProp}' is not defined as a property on the component. v-model integration may not work as expected.`);
        }
        templateString += `,\n`;
        templateString += `'${targetProp}', '${findModel.event}'`;
        if (findModel.externalEvent) {
            templateString += `, '${findModel.externalEvent}'`;
        }
    }
    templateString += `);\n`;
    return templateString;
};
