'use strict';

var jsxRuntime = require('react/jsx-runtime');
var React = require('react');

/* ── Default config ── */
const DEFAULT_CONFIG = {
    framework: 'react',
    componentName: 'MyIcon',
    extractColors: true,
    useClassNames: false,
    typescript: true,
    optimize: true,
    sizeProps: true,
    useCurrentColor: false,
    memo: true,
    defaultExport: true,
    ariaLabel: true,
};
/* ── SVG Parser (simple regex-based for browser) ── */
const METADATA_TAGS = new Set(['metadata', 'title', 'desc', 'defs', 'comment']);
const REMOVABLE_ATTRS = new Set([
    'xmlns:xlink', 'xml:space', 'xmlns:svg', 'version',
    'xmlns:dc', 'xmlns:cc', 'xmlns:rdf', 'xmlns:sodipodi', 'xmlns:inkscape',
    'sodipodi:docname', 'inkscape:version', 'data-name',
]);
function parseSvgString(svg) {
    // Use DOMParser for safe parsing
    if (typeof DOMParser === 'undefined')
        return null;
    const parser = new DOMParser();
    const doc = parser.parseFromString(svg, 'image/svg+xml');
    const error = doc.querySelector('parsererror');
    if (error)
        return null;
    function elementToNode(el) {
        const attrs = {};
        for (const attr of Array.from(el.attributes)) {
            attrs[attr.name] = attr.value;
        }
        const children = [];
        for (const child of Array.from(el.children)) {
            children.push(elementToNode(child));
        }
        const text = el.childNodes.length === 1 && el.childNodes[0].nodeType === 3
            ? el.childNodes[0].textContent || undefined
            : undefined;
        return { tag: el.tagName.toLowerCase(), attrs, children, text };
    }
    const svgEl = doc.querySelector('svg');
    if (!svgEl)
        return null;
    return elementToNode(svgEl);
}
function optimizeSvgNode(node) {
    // Remove metadata tags
    const filteredChildren = node.children
        .filter((c) => !METADATA_TAGS.has(c.tag))
        .map(optimizeSvgNode);
    // Remove removable attrs
    const cleanAttrs = {};
    for (const [key, val] of Object.entries(node.attrs)) {
        if (!REMOVABLE_ATTRS.has(key) && !key.startsWith('inkscape:') && !key.startsWith('sodipodi:')) {
            cleanAttrs[key] = val;
        }
    }
    return { tag: node.tag, attrs: cleanAttrs, children: filteredChildren, text: node.text };
}
function extractColorsFromNode(node, colors) {
    for (const val of Object.values(node.attrs)) {
        if (/^#[0-9a-fA-F]{3,8}$/.test(val))
            colors.add(val.toLowerCase());
        if (/^rgb\(/.test(val))
            colors.add(val);
    }
    for (const style of (node.attrs.style || '').split(';')) {
        const match = style.match(/(fill|stroke|color)\s*:\s*(#[0-9a-fA-F]{3,8}|rgb\([^)]+\))/i);
        if (match)
            colors.add(match[2].toLowerCase());
    }
    for (const child of node.children)
        extractColorsFromNode(child, colors);
}
function replaceColorsInNode(node, replacement) {
    const newAttrs = {};
    for (const [key, val] of Object.entries(node.attrs)) {
        if (/^#[0-9a-fA-F]{3,8}$/.test(val) && (key === 'fill' || key === 'stroke')) {
            newAttrs[key] = replacement;
        }
        else {
            newAttrs[key] = val;
        }
    }
    return {
        tag: node.tag,
        attrs: newAttrs,
        children: node.children.map((c) => replaceColorsInNode(c, replacement)),
        text: node.text,
    };
}
/* ── SVG attribute → JSX attribute mapping ── */
const SVG_TO_JSX = {
    'class': 'className',
    'clip-path': 'clipPath',
    'clip-rule': 'clipRule',
    'fill-opacity': 'fillOpacity',
    'fill-rule': 'fillRule',
    'font-family': 'fontFamily',
    'font-size': 'fontSize',
    'font-weight': 'fontWeight',
    'letter-spacing': 'letterSpacing',
    'marker-end': 'markerEnd',
    'marker-mid': 'markerMid',
    'marker-start': 'markerStart',
    'stop-color': 'stopColor',
    'stop-opacity': 'stopOpacity',
    'stroke-dasharray': 'strokeDasharray',
    'stroke-dashoffset': 'strokeDashoffset',
    'stroke-linecap': 'strokeLinecap',
    'stroke-linejoin': 'strokeLinejoin',
    'stroke-miterlimit': 'strokeMiterlimit',
    'stroke-opacity': 'strokeOpacity',
    'stroke-width': 'strokeWidth',
    'text-anchor': 'textAnchor',
    'text-decoration': 'textDecoration',
    'transform-origin': 'transformOrigin',
    'xlink:href': 'xlinkHref',
    'xml:lang': 'xmlLang',
    'xml:space': 'xmlSpace',
    'xmlns:xlink': '',
    'xmlns': '',
};
function attrToJsx(name) {
    if (name in SVG_TO_JSX)
        return SVG_TO_JSX[name];
    // camelCase any remaining kebab-case
    return name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
}
/* ── Code Generators ── */
function nodeToJsx(node, indent = 2) {
    const pad = ' '.repeat(indent);
    const attrs = Object.entries(node.attrs)
        .map(([k, v]) => {
        const jsxKey = attrToJsx(k);
        if (!jsxKey)
            return '';
        return `${jsxKey}="${v}"`;
    })
        .filter(Boolean)
        .join(' ');
    if (node.children.length === 0 && !node.text) {
        return `${pad}<${node.tag}${attrs ? ' ' + attrs : ''} />`;
    }
    const inner = node.text
        ? node.text
        : '\n' + node.children.map((c) => nodeToJsx(c, indent + 2)).join('\n') + '\n' + pad;
    return `${pad}<${node.tag}${attrs ? ' ' + attrs : ''}>${inner}</${node.tag}>`;
}
function nodeToHtml(node, indent = 2) {
    const pad = ' '.repeat(indent);
    const attrs = Object.entries(node.attrs)
        .map(([k, v]) => `${k}="${v}"`)
        .filter(Boolean)
        .join(' ');
    if (node.children.length === 0 && !node.text) {
        return `${pad}<${node.tag}${attrs ? ' ' + attrs : ''} />`;
    }
    const inner = node.text
        ? node.text
        : '\n' + node.children.map((c) => nodeToHtml(c, indent + 2)).join('\n') + '\n' + pad;
    return `${pad}<${node.tag}${attrs ? ' ' + attrs : ''}>${inner}</${node.tag}>`;
}
function generateReact(node, config) {
    const { componentName, typescript, sizeProps, memo, defaultExport, ariaLabel } = config;
    // Build props interface
    const propsLines = [];
    if (sizeProps) {
        propsLines.push('  width?: number | string;');
        propsLines.push('  height?: number | string;');
    }
    if (ariaLabel)
        propsLines.push("  'aria-label'?: string;");
    propsLines.push('  className?: string;');
    propsLines.push('  style?: React.CSSProperties;');
    // Modify SVG node for props
    const svgNode = { ...node, attrs: { ...node.attrs } };
    if (sizeProps) {
        svgNode.attrs.width = '{width}';
        svgNode.attrs.height = '{height}';
    }
    const jsxBody = nodeToJsx({ ...svgNode, tag: 'svg' }, 4);
    const lines = [];
    lines.push("import React from 'react';");
    lines.push('');
    if (typescript) {
        lines.push(`interface ${componentName}Props {`);
        lines.push(...propsLines);
        lines.push('}');
        lines.push('');
    }
    const propsType = typescript ? `${componentName}Props` : 'any';
    const propsDestructure = [
        sizeProps ? `width = ${JSON.stringify(node.attrs.width || '24')}` : '',
        sizeProps ? `height = ${JSON.stringify(node.attrs.height || '24')}` : '',
        ariaLabel ? "'aria-label': ariaLabel" : '',
        'className',
        'style',
    ].filter(Boolean).join(', ');
    if (memo) {
        lines.push(`const ${componentName} = React.memo<${propsType}>(({ ${propsDestructure} }) => (`);
    }
    else {
        lines.push(`const ${componentName}: React.FC<${propsType}> = ({ ${propsDestructure} }) => (`);
    }
    lines.push(jsxBody);
    if (memo) {
        lines.push('));');
    }
    else {
        lines.push(');');
    }
    lines.push('');
    lines.push(`${componentName}.displayName = '${componentName}';`);
    lines.push('');
    if (defaultExport) {
        lines.push(`export default ${componentName};`);
    }
    else {
        lines.push(`export { ${componentName} };`);
    }
    return lines.join('\n');
}
function generateVue(node, config) {
    const { componentName, sizeProps, typescript } = config;
    const svgHtml = nodeToHtml(node, 2);
    const lines = [];
    lines.push('<template>');
    lines.push(svgHtml);
    lines.push('</template>');
    lines.push('');
    lines.push(`<script${typescript ? ' lang="ts"' : ''} setup>`);
    if (sizeProps) {
        if (typescript) {
            lines.push('interface Props {');
            lines.push("  width?: string | number;");
            lines.push("  height?: string | number;");
            lines.push('}');
            lines.push('');
            lines.push("const props = withDefaults(defineProps<Props>(), {");
            lines.push(`  width: '${node.attrs.width || '24'}',`);
            lines.push(`  height: '${node.attrs.height || '24'}',`);
            lines.push('});');
        }
        else {
            lines.push('const props = defineProps({');
            lines.push("  width: { type: [String, Number], default: '24' },");
            lines.push("  height: { type: [String, Number], default: '24' },");
            lines.push('});');
        }
    }
    lines.push('</script>');
    lines.push('');
    lines.push(`<!-- ${componentName}.vue -->`);
    return lines.join('\n');
}
function generateWebComponent(node, config) {
    const { componentName, sizeProps } = config;
    const tagName = componentName.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');
    const svgHtml = nodeToHtml(node, 6);
    const lines = [];
    lines.push(`class ${componentName} extends HTMLElement {`);
    lines.push('  constructor() {');
    lines.push('    super();');
    lines.push("    this.attachShadow({ mode: 'open' });");
    lines.push('  }');
    lines.push('');
    lines.push('  connectedCallback() {');
    lines.push('    this.render();');
    lines.push('  }');
    lines.push('');
    if (sizeProps) {
        lines.push("  static get observedAttributes() { return ['width', 'height']; }");
        lines.push('');
        lines.push('  attributeChangedCallback() { this.render(); }');
        lines.push('');
    }
    lines.push('  render() {');
    if (sizeProps) {
        lines.push(`    const width = this.getAttribute('width') || '${node.attrs.width || '24'}';`);
        lines.push(`    const height = this.getAttribute('height') || '${node.attrs.height || '24'}';`);
    }
    lines.push('    if (this.shadowRoot) {');
    lines.push('      this.shadowRoot.innerHTML = `');
    lines.push(svgHtml);
    lines.push('      `;');
    lines.push('    }');
    lines.push('  }');
    lines.push('}');
    lines.push('');
    lines.push(`customElements.define('${tagName}', ${componentName});`);
    lines.push('');
    lines.push(`export { ${componentName} };`);
    return lines.join('\n');
}
function generateTypeScript(node, config) {
    const { componentName, sizeProps } = config;
    const svgHtml = nodeToHtml(node, 2);
    const lines = [];
    lines.push(`export interface ${componentName}Options {`);
    if (sizeProps) {
        lines.push('  width?: string | number;');
        lines.push('  height?: string | number;');
    }
    lines.push('  className?: string;');
    lines.push('}');
    lines.push('');
    lines.push(`export function render${componentName}(container: HTMLElement, options: ${componentName}Options = {}): void {`);
    if (sizeProps) {
        lines.push(`  const width = options.width ?? '${node.attrs.width || '24'}';`);
        lines.push(`  const height = options.height ?? '${node.attrs.height || '24'}';`);
    }
    lines.push('  container.innerHTML = `');
    lines.push(svgHtml);
    lines.push('  `;');
    lines.push('}');
    lines.push('');
    lines.push(`export const ${componentName}SVG = \``);
    lines.push(svgHtml);
    lines.push('`;');
    return lines.join('\n');
}
/* ── Main conversion function ── */
function convertSvgToCode(svgString, config) {
    let node = parseSvgString(svgString);
    if (!node)
        return null;
    if (config.optimize) {
        node = optimizeSvgNode(node);
    }
    // Extract colors
    const colors = new Set();
    extractColorsFromNode(node, colors);
    if (config.useCurrentColor) {
        node = replaceColorsInNode(node, 'currentColor');
    }
    let code;
    let ext;
    switch (config.framework) {
        case 'react':
            code = generateReact(node, config);
            ext = config.typescript ? 'tsx' : 'jsx';
            break;
        case 'vue':
            code = generateVue(node, config);
            ext = 'vue';
            break;
        case 'web-component':
            code = generateWebComponent(node, config);
            ext = config.typescript ? 'ts' : 'js';
            break;
        case 'typescript':
            code = generateTypeScript(node, config);
            ext = 'ts';
            break;
        default:
            return null;
    }
    return {
        code,
        framework: config.framework,
        componentName: config.componentName,
        fileName: `${config.componentName}.${ext}`,
        extractedColors: [...colors],
    };
}
/* ── Hook ── */
function useSvgToCode() {
    const [svgInput, setSvgInput] = React.useState('');
    const [config, setConfig] = React.useState({ ...DEFAULT_CONFIG });
    const [result, setResult] = React.useState(null);
    const convert = React.useCallback(() => {
        if (!svgInput.trim()) {
            setResult(null);
            return;
        }
        const r = convertSvgToCode(svgInput, config);
        setResult(r);
    }, [svgInput, config]);
    const updateConfig = React.useCallback((partial) => {
        setConfig((prev) => ({ ...prev, ...partial }));
    }, []);
    return { svgInput, setSvgInput, config, updateConfig, convert, result };
}
/* ── Component ── */
const NiceSvgToCode = ({ initialSvg = '', onConvert, className = '', }) => {
    const { svgInput, setSvgInput, config, updateConfig, convert, result } = useSvgToCode();
    // Initialize with provided SVG
    React.useEffect(() => {
        if (initialSvg)
            setSvgInput(initialSvg);
    }, [initialSvg, setSvgInput]);
    const handleConvert = () => {
        convert();
        if (result && onConvert)
            onConvert(result);
    };
    const handleCopy = () => {
        if (result)
            navigator.clipboard.writeText(result.code);
    };
    return (jsxRuntime.jsxs("div", { className: `nice-svg-to-code ${className}`, style: { display: 'grid', gap: 8, fontSize: 13 }, children: [jsxRuntime.jsx("strong", { children: "\uD83D\uDD04 SVG \u2192 Code" }), jsxRuntime.jsx("textarea", { value: svgInput, onChange: (e) => setSvgInput(e.target.value), placeholder: "Paste SVG markup here\u2026", rows: 6, style: { width: '100%', fontFamily: 'monospace', fontSize: 11, padding: 6, borderRadius: 4,
                    border: '1px solid var(--border, #e2e8f0)' } }), jsxRuntime.jsxs("div", { style: { display: 'grid', gap: 4 }, children: [jsxRuntime.jsxs("label", { children: ["Framework:", jsxRuntime.jsxs("select", { value: config.framework, onChange: (e) => updateConfig({ framework: e.target.value }), style: { width: '100%' }, children: [jsxRuntime.jsx("option", { value: "react", children: "React (JSX/TSX)" }), jsxRuntime.jsx("option", { value: "vue", children: "Vue (SFC)" }), jsxRuntime.jsx("option", { value: "web-component", children: "Web Component" }), jsxRuntime.jsx("option", { value: "typescript", children: "TypeScript (utility)" })] })] }), jsxRuntime.jsxs("label", { children: ["Component name:", jsxRuntime.jsx("input", { type: "text", value: config.componentName, onChange: (e) => updateConfig({ componentName: e.target.value.replace(/[^a-zA-Z0-9]/g, '') }), style: { width: '100%', padding: '3px 6px' } })] }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 8, flexWrap: 'wrap', fontSize: 11 }, children: [jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.typescript, onChange: (e) => updateConfig({ typescript: e.target.checked }) }), " TypeScript"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.optimize, onChange: (e) => updateConfig({ optimize: e.target.checked }) }), " Optimize"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.sizeProps, onChange: (e) => updateConfig({ sizeProps: e.target.checked }) }), " Size props"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.useCurrentColor, onChange: (e) => updateConfig({ useCurrentColor: e.target.checked }) }), " currentColor"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.memo, onChange: (e) => updateConfig({ memo: e.target.checked }) }), " memo"] })] })] }), jsxRuntime.jsxs("button", { type: "button", onClick: handleConvert, disabled: !svgInput.trim(), style: {
                    background: 'var(--accent, #6366f1)', color: '#fff', border: 'none',
                    borderRadius: 4, padding: '8px 12px', cursor: 'pointer',
                }, children: ["\uD83D\uDD04 Convert to ", config.framework.charAt(0).toUpperCase() + config.framework.slice(1)] }), result && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }, children: [jsxRuntime.jsx("span", { style: { fontSize: 11, color: 'var(--muted, #64748b)' }, children: result.fileName }), jsxRuntime.jsx("button", { type: "button", onClick: handleCopy, style: { fontSize: 10, padding: '2px 8px', cursor: 'pointer', borderRadius: 3,
                                    border: '1px solid var(--border, #e2e8f0)', background: 'transparent' }, children: "\uD83D\uDCCB Copy" })] }), jsxRuntime.jsx("pre", { style: {
                            background: 'var(--code-bg, #1e293b)', color: 'var(--code-fg, #e2e8f0)',
                            padding: 8, borderRadius: 4, fontSize: 11, overflow: 'auto', maxHeight: 300,
                            whiteSpace: 'pre-wrap',
                        }, children: result.code }), result.extractedColors.length > 0 && (jsxRuntime.jsxs("div", { style: { fontSize: 11, marginTop: 4 }, children: ["Kolory: ", result.extractedColors.map((c) => (jsxRuntime.jsx("span", { style: { display: 'inline-block', width: 12, height: 12, background: c,
                                    border: '1px solid #ccc', borderRadius: 2, marginRight: 4, verticalAlign: 'middle' } }, c)))] }))] }))] }));
};

exports.NiceSvgToCode = NiceSvgToCode;
exports.convertSvgToCode = convertSvgToCode;
exports.useSvgToCode = useSvgToCode;
//# sourceMappingURL=NiceSvgToCode.js.map
