export function format(first, middle, last) {
    return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');
}
export function toKebabCase(str) {
    return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
}
export function formatDate(date) {
    const parts = date.split('-');
    return `${parts[2]}/${parts[1]}/${parts[0]}`;
}
export function stripHtmlContent(content) {
    const div = document.createElement('div');
    div.innerHTML = content;
    return div.textContent || div.innerText || '';
}
const description = (prop) => (prop.docs || '').trim();
const isText = (prop) => prop.type === 'string';
const isBoolean = (prop) => prop.type === 'boolean';
const isEnum = (prop) => prop.type.includes('|');
const isNumber = (prop) => prop.type === 'number';
const enumOptions = (prop) => prop.type
    .split('|')
    .map(t => t.trim())
    .map(t => (t === '""' ? 'default' : t))
    .map(t => t.replace(/^"(.*)"$/, '$1'));
const generateProp = (prop, componentTag, prefixPropName = false) => {
    const category = componentTag ? `Props - ${componentTag}` : 'properties';
    const propName = prefixPropName && componentTag ? `${componentTag}__${prop.name}` : prop.name;
    const kebabCaseName = toKebabCase(prop.name);
    const baseTableConfig = {
        category: category,
        defaultValue: { summary: prop.default },
    };
    if (isText(prop)) {
        return {
            [propName]: {
                control: 'text',
                description: description(prop),
                defaultValue: prop.default,
                name: kebabCaseName,
                table: Object.assign(Object.assign({}, baseTableConfig), { type: { summary: 'string' } }),
            },
        };
    }
    if (isBoolean(prop)) {
        return {
            [propName]: {
                control: 'boolean',
                description: description(prop),
                defaultValue: prop.default,
                name: kebabCaseName,
                table: Object.assign(Object.assign({}, baseTableConfig), { type: { summary: 'boolean' } }),
            },
        };
    }
    if (isNumber(prop)) {
        return {
            [propName]: {
                control: 'number',
                description: description(prop),
                defaultValue: prop.default,
                name: kebabCaseName,
                table: Object.assign(Object.assign({}, baseTableConfig), { type: { summary: 'number' } }),
            },
        };
    }
    if (isEnum(prop)) {
        return {
            [propName]: {
                control: 'select',
                defaultValue: prop.default,
                options: enumOptions(prop),
                description: description(prop),
                name: kebabCaseName,
                table: Object.assign(Object.assign({}, baseTableConfig), { type: { summary: 'enum' } }),
            },
        };
    }
    return {};
};
const generateProps = (props, componentTag, prefixPropName = false) => {
    let args = {};
    props.forEach(prop => (args = Object.assign(Object.assign({}, args), generateProp(prop, componentTag, prefixPropName))));
    return args;
};
const generateEvent = (event, componentTag, prefixEventName = false) => {
    function capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    }
    const category = componentTag ? `Events - ${componentTag}` : 'events';
    const originalEventName = `on${capitalizeFirstLetter(event.event)}`;
    const eventName = prefixEventName && componentTag ? `${componentTag}__${originalEventName}` : originalEventName;
    return {
        [eventName]: {
            action: event.event,
            description: description(event),
            name: originalEventName,
            table: {
                defaultValue: { summary: event.event },
                category: category,
                type: { summary: event.detail },
            },
        },
    };
};
const generateEvents = (events, componentTag, prefixEventName = false) => {
    let args = {};
    events.forEach(event => (args = Object.assign(Object.assign({}, args), generateEvent(event, componentTag, prefixEventName))));
    return args;
};
const generateMethod = (method, componentTag, prefixMethodName = false) => {
    const category = componentTag ? `Methods - ${componentTag}` : 'methods';
    const methodName = prefixMethodName && componentTag ? `${componentTag}__${method.name}` : method.name;
    return {
        [methodName]: {
            action: method.name,
            description: description(method),
            name: method.name,
            table: {
                category: category,
                type: { summary: method.signature },
                defaultValue: { summary: method.returns.type },
            },
        },
    };
};
const generateMethods = (methods, componentTag, prefixMethodName = false) => {
    let args = {};
    methods.forEach(method => (args = Object.assign(Object.assign({}, args), generateMethod(method, componentTag, prefixMethodName))));
    return args;
};
const generateStyle = (style, componentTag, prefixStyleName = false) => {
    const category = componentTag ? `Tokens - ${componentTag}` : 'Tokens';
    const styleName = prefixStyleName && componentTag ? `${componentTag}__${style.name}` : style.name;
    return {
        [styleName]: {
            control: false,
            description: style.docs || '',
            name: style.name,
            table: {
                category: category,
                type: { summary: 'CSS Variable' },
            },
        },
    };
};
const generateStyles = (styles, componentTag, prefixStyleName = false) => {
    let args = {};
    styles.forEach(style => (args = Object.assign(Object.assign({}, args), generateStyle(style, componentTag, prefixStyleName))));
    return args;
};
const extractComponentInfoByTag = (componentsData, tag) => {
    const component = componentsData.components.find(c => c.tag === tag);
    if (!component) {
        console.error(`Component with tag ${tag} not found`);
        return null;
    }
    const { props, events, methods } = component;
    const propInfo = props.map(prop => ({
        name: prop.name,
        type: prop.type,
        docs: prop.docs,
        default: prop.default || '',
    }));
    const eventInfo = events.map(event => ({
        event: event.event,
        docs: event.docs,
        detail: event.detail,
    }));
    const methodInfo = methods.map(method => ({
        name: method.name,
        signature: method.signature,
        docs: method.docs,
        returns: method.returns,
        parameters: method.parameters,
    }));
    return {
        name: tag,
        props: propInfo,
        events: eventInfo,
        methods: methodInfo,
    };
};
const generateHTMLTable = (componentInfo) => {
    if (!componentInfo) {
        return `<p>Component not found</p>`;
    }
    const { props, events, methods } = componentInfo;
    const propsRows = props
        .map(prop => `
    <tr>
      <td>${prop.name}</td>
      <td>${prop.type}</td>
      <td>${prop.docs}</td>
      <td>${prop.default}</td>
    </tr>
  `)
        .join('');
    const eventsRows = events
        .map(event => `
    <tr>
      <td>${event.event}</td>
      <td>${event.detail}</td>
      <td>${event.docs}</td>
    </tr>
  `)
        .join('');
    const methodsRows = methods
        .map(method => `
    <tr>
      <td>${method.name}</td>
      <td>${method.signature}</td>
      <td>${method.returns.type}</td>
      <td>${method.docs}</td>
    </tr>
  `)
        .join('');
    return `
    <h3>Propriétés</h3>
    <table class="w-full">
      <thead>
        <tr>
          <th>Propriété</th>
          <th>Type</th>
          <th>Description</th>
          <th>Valeur par défaut</th>
        </tr>
      </thead>
      <tbody>
        ${propsRows}
      </tbody>
    </table>
    <h3>Événements</h3>
    <table class="w-full">
      <thead>
        <tr>
          <th>Événement</th>
          <th>Détail</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        ${eventsRows}
      </tbody>
    </table>
    <h3>Méthodes</h3>
    <table class="w-full">
      <thead>
        <tr>
          <th>Méthode</th>
          <th>Signature</th>
          <th>Retour</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        ${methodsRows}
      </tbody>
    </table>
  `;
};
export const generateComponentTable = (componentsData, tag) => {
    const componentInfo = extractComponentInfoByTag(componentsData, tag);
    return generateHTMLTable(componentInfo);
};
export const withComponentControls = (componentsData, { tag, prefixNames = false }) => {
    const component = componentsData.components.find(c => c.tag === tag);
    const props = (component === null || component === void 0 ? void 0 : component.props) || [];
    const events = (component === null || component === void 0 ? void 0 : component.events) || [];
    const methods = (component === null || component === void 0 ? void 0 : component.methods) || [];
    const styles = (component === null || component === void 0 ? void 0 : component.styles) || [];
    const propControls = generateProps(props, tag, prefixNames);
    const eventControls = generateEvents(events, tag, prefixNames);
    const methodControls = generateMethods(methods, tag, prefixNames);
    const styleControls = generateStyles(styles, tag, prefixNames);
    const allControls = Object.assign(Object.assign(Object.assign(Object.assign({}, propControls), eventControls), methodControls), styleControls);
    Object.defineProperty(allControls, '__realProps', {
        value: Object.keys(propControls).concat(Object.keys(styleControls)),
        enumerable: false,
    });
    return allControls;
};
export function extractArgTypes(componentsData, subComponentTags) {
    return subComponentTags.reduce((acc, tag) => {
        const subComponentArgTypes = withComponentControls(componentsData, { tag, prefixNames: true });
        return Object.assign(Object.assign({}, acc), subComponentArgTypes);
    }, {});
}
export function formatFileSize(sizeInBytes) {
    const sizeInMB = sizeInBytes / (1024 * 1024);
    let formattedSize = sizeInMB.toFixed(2).replace('.', ',');
    if (sizeInMB > 0 && sizeInMB < 0.01) {
        formattedSize = '0,01';
    }
    else if (sizeInMB === 0) {
        formattedSize = '0,00';
    }
    return `${formattedSize} Mo`;
}
export function hasSlotContent(el) {
    const slot = el.querySelector('slot');
    return slot && slot.assignedNodes().length > 0;
}
