import { normalizarFimDeLinha, normalizarNewlinesFinais, removerBom } from './commons.js';
function tokenizeCssBlocks(src) {
    const out = [];
    let indice = 0;
    const skipString = (quote) => {
        let posAtual = indice + 1;
        while (posAtual < src.length) {
            if (src[posAtual] === '\\') {
                posAtual += 2;
                continue;
            }
            if (src[posAtual] === quote) {
                posAtual++;
                break;
            }
            posAtual++;
        }
        return posAtual;
    };
    while (indice < src.length) {
        if (src[indice] === '/' && src[indice + 1] === '*') {
            const end = src.indexOf('*/', indice + 2);
            if (end === -1) {
                out.push({
                    kind: 'comment',
                    value: src.slice(indice)
                });
                break;
            }
            out.push({
                kind: 'comment',
                value: src.slice(indice, end + 2)
            });
            indice = end + 2;
            continue;
        }
        if (src[indice] === '"' || src[indice] === "'") {
            const start = indice;
            indice = skipString(src[indice]);
            out.push({
                kind: 'rule',
                value: src.slice(start, indice)
            });
            continue;
        }
        if (src[indice] === '(') {
            const parenStart = indice;
            let depth = 1;
            indice++;
            while (indice < src.length && depth > 0) {
                if (src[indice] === '(')
                    depth++;
                else if (src[indice] === ')')
                    depth--;
                if (depth > 0)
                    indice++;
                else
                    indice++;
            }
            out.push({
                kind: 'rule',
                value: src.slice(parenStart, indice)
            });
            continue;
        }
        if (src[indice] === '@') {
            let depth = 0;
            const atStart = indice;
            let blockStarted = false;
            while (indice < src.length) {
                if (src[indice] === '(') {
                    let pd = 1;
                    indice++;
                    while (indice < src.length && pd > 0) {
                        if (src[indice] === '(')
                            pd++;
                        else if (src[indice] === ')')
                            pd--;
                        indice++;
                    }
                    continue;
                }
                if (src[indice] === '{') {
                    depth++;
                    blockStarted = true;
                }
                if (src[indice] === '}') {
                    if (depth === 0) {
                        indice++;
                        break;
                    }
                    depth--;
                    if (depth === 0 && blockStarted) {
                        indice++;
                        break;
                    }
                }
                if (src[indice] === ';' && depth === 0) {
                    indice++;
                    break;
                }
                indice++;
            }
            out.push({
                kind: 'at-rule',
                value: src.slice(atStart, indice)
            });
            continue;
        }
        if (src[indice] === '{' || src[indice] === '}' || src[indice] === ';') {
            out.push({
                kind: 'text',
                value: src[indice]
            });
            indice++;
            continue;
        }
        {
            const ruleStart = indice;
            while (indice < src.length && src[indice] !== '{' && src[indice] !== '}' && src[indice] !== ';' && src[indice] !== '@' && !(src[indice] === '/' && src[indice + 1] === '*')) {
                if (src[indice] === '"' || src[indice] === "'") {
                    indice = skipString(src[indice]);
                    continue;
                }
                indice++;
            }
            const chunk = src.slice(ruleStart, indice);
            if (chunk.trim()) {
                out.push({
                    kind: 'rule',
                    value: chunk
                });
            }
        }
    }
    return out;
}
function findPropertyColon(str) {
    let depth = 0;
    for (let indice = 0; indice < str.length; indice++) {
        if (str[indice] === '(')
            depth++;
        else if (str[indice] === ')')
            depth--;
        else if (str[indice] === ':' && depth === 0) {
            const rest = str.slice(indice + 1);
            const before = str.slice(0, indice).trim();
            if (/^::[a-zA-Z-]/.test(rest)) {
                if (before.startsWith('--')) {
                    return indice;
                }
                continue;
            }
            if (/^:[a-zA-Z-]/.test(rest)) {
                if (before.startsWith('--')) {
                    return indice;
                }
                if (before.length <= 2 || /[\s>+~\[*.#:]/.test(before)) {
                    continue;
                }
                continue;
            }
            if (before.length > 0 && !before.includes(' ') && !before.includes('>') && !before.includes('+') && !before.includes('~') && !before.includes('[') && !before.startsWith('.') && !before.startsWith('#') && !before.startsWith(':') && !before.startsWith('@') && !before.startsWith('&')) {
                return indice;
            }
            continue;
        }
    }
    return -1;
}
function isCssPropertyName(name) {
    const textoTitulo = name.trim();
    if (!textoTitulo)
        return false;
    if (textoTitulo.startsWith('--'))
        return true;
    const commonTags = new Set(['a', 'b', 'i', 'u', 's', 'em', 'strong', 'code', 'span', 'div', 'html', 'head', 'body', 'title', 'link', 'meta', 'script', 'style', 'header', 'footer', 'nav', 'main', 'section', 'article', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'ul', 'ol', 'li', 'table', 'tr', 'td', 'th', 'form', 'input', 'button', 'label', 'img', 'a', 'br', 'hr', 'pre', 'blockquote', 'iframe']);
    if (commonTags.has(textoTitulo.toLowerCase()))
        return false;
    if (/^-?[a-zA-Z][a-zA-Z0-9-]*$/.test(textoTitulo))
        return true;
    return false;
}
function parseCssTokens(tokenList) {
    const items = [];
    let currentSelector = '';
    function flushSelector() {
        if (currentSelector.trim()) {
            items.push({
                kind: 'block',
                selector: currentSelector.trim(),
                items: []
            });
            currentSelector = '';
        }
    }
    let idx = 0;
    while (idx < tokenList.length) {
        const tok = tokenList[idx];
        if (!tok) {
            idx++;
            continue;
        }
        if (tok.kind === 'comment') {
            items.push({
                kind: 'comment',
                text: tok.value.trim()
            });
            idx++;
            continue;
        }
        if (tok.kind === 'text') {
            if (tok.value === '{') {
                flushSelector();
                const lastBlock = items[items.length - 1];
                if (lastBlock?.kind === 'block') {
                    idx++;
                    const innerTokens = [];
                    let depth = 1;
                    while (idx < tokenList.length && depth > 0) {
                        const innerTok = tokenList[idx];
                        if (!innerTok) {
                            idx++;
                            continue;
                        }
                        if (innerTok.kind === 'text') {
                            if (innerTok.value === '{')
                                depth++;
                            else if (innerTok.value === '}')
                                depth--;
                        }
                        if (depth > 0)
                            innerTokens.push(innerTok);
                        idx++;
                    }
                    lastBlock.items = parseCssTokens(innerTokens);
                }
                else {
                    idx++;
                }
            }
            else if (tok.value === '}') {
                flushSelector();
                idx++;
            }
            else if (tok.value === ';') {
                idx++;
            }
            else {
                idx++;
            }
            continue;
        }
        if (tok.kind === 'at-rule') {
            const trimmed = tok.value.trim();
            if (trimmed.includes('{')) {
                const braceIdx = trimmed.indexOf('{');
                const selector = trimmed.slice(0, braceIdx).trim();
                const lastBrace = trimmed.lastIndexOf('}');
                const innerContent = lastBrace > braceIdx ? trimmed.slice(braceIdx + 1, lastBrace).trim() : '';
                const block = {
                    kind: 'block',
                    selector,
                    items: []
                };
                if (innerContent) {
                    const innerTokens = tokenizeCssBlocks(innerContent);
                    block.items = parseCssTokens(innerTokens);
                }
                items.push(block);
            }
            else {
                const cleaned = trimmed.replace(/;[\s]*$/, '').trim();
                items.push({
                    kind: 'prop',
                    prop: cleaned,
                    value: ''
                });
            }
            idx++;
            continue;
        }
        if (tok.kind === 'rule') {
            const trimmed = tok.value.trim();
            if (!trimmed) {
                idx++;
                continue;
            }
            const colonIdx = findPropertyColon(trimmed);
            if (colonIdx > 0 && !trimmed.includes('{') && !trimmed.includes('}')) {
                const prop = trimmed.slice(0, colonIdx).trim();
                const value = trimmed.slice(colonIdx + 1).trim();
                if (isCssPropertyName(prop)) {
                    items.push({
                        kind: 'prop',
                        prop,
                        value
                    });
                    idx++;
                    continue;
                }
            }
            currentSelector = (currentSelector ? `${currentSelector} ` : '') + trimmed;
            idx++;
            continue;
        }
        idx++;
    }
    flushSelector();
    return items;
}
function renderCssItems(items, depth) {
    const lines = [];
    const indent = (node) => '  '.repeat(Math.max(0, node));
    for (let indice = 0; indice < items.length; indice++) {
        const item = items[indice];
        if (item.kind === 'comment') {
            const commentLines = item.text.split('\n');
            for (const cl of commentLines) {
                lines.push(`${indent(depth)}${cl.trim()}`);
            }
        }
        else if (item.kind === 'prop') {
            if (item.value === '') {
                lines.push(`${indent(depth)}${item.prop};`);
            }
            else {
                lines.push(`${indent(depth)}${item.prop}: ${item.value};`);
            }
        }
        else if (item.kind === 'block') {
            if (depth === 0 && indice > 0) {
                const prevLine = lines[lines.length - 1];
                if (prevLine !== undefined && prevLine !== '') {
                    lines.push('');
                }
            }
            lines.push(`${indent(depth)}${item.selector} {`);
            if (item.items.length > 0) {
                lines.push(...renderCssItems(item.items, depth + 1));
            }
            lines.push(`${indent(depth)}}`);
        }
    }
    return lines;
}
export function formatarCssMinimo(code) {
    const normalized = normalizarFimDeLinha(removerBom(code));
    const tokens = tokenizeCssBlocks(normalized);
    const treeItems = parseCssTokens(tokens);
    const outLines = renderCssItems(treeItems, 0);
    const formatted = normalizarNewlinesFinais(outLines.join('\n').replace(/\n{3,}/g, '\n\n'));
    const baseline = normalizarNewlinesFinais(normalized);
    return {
        ok: true,
        parser: 'css',
        formatted,
        changed: formatted !== baseline,
        reason: 'estilo-tutanus-css'
    };
}
export function formatarScssMinimo(code) {
    const normalized = normalizarFimDeLinha(removerBom(code));
    const lines = normalized.split('\n');
    const out = [];
    let indent = 0;
    let inMultilineComment = false;
    for (let indice = 0; indice < lines.length; indice++) {
        const raw = lines[indice] ?? '';
        const trimmed = raw.trim();
        if (!trimmed) {
            if (out.length > 0 && out[out.length - 1] !== '') {
                out.push('');
            }
            continue;
        }
        if (inMultilineComment) {
            out.push(`${'  '.repeat(indent)}${trimmed}`);
            if (trimmed.includes('*/')) {
                inMultilineComment = false;
            }
            continue;
        }
        if (trimmed.startsWith('/*') && !trimmed.includes('*/')) {
            inMultilineComment = true;
            out.push(`${'  '.repeat(indent)}${trimmed}`);
            continue;
        }
        if (trimmed.startsWith('//') || trimmed.startsWith('/*') && trimmed.includes('*/')) {
            out.push(`${'  '.repeat(indent)}${trimmed}`);
            continue;
        }
        if (trimmed === '}' || trimmed.startsWith('}')) {
            indent = Math.max(0, indent - 1);
            out.push(`${'  '.repeat(indent)}${trimmed}`);
            continue;
        }
        if (trimmed.endsWith('{')) {
            if (out.length > 0 && out[out.length - 1] !== '' && !out[out.length - 1]?.trim().startsWith('//') && !out[out.length - 1]?.trim().startsWith('/*')) {
                const prevTrimmed = (out[out.length - 1] ?? '').trim();
                if (prevTrimmed !== '' && !prevTrimmed.endsWith('{') && prevTrimmed !== '}') {
                    out.push('');
                }
            }
            const selector = trimmed.slice(0, -1).trim();
            out.push(`${'  '.repeat(indent)}${selector} {`);
            indent++;
            continue;
        }
        if (trimmed.includes('{')) {
            const parts = trimmed.split('{');
            const selector = parts[0]?.trim() ?? '';
            out.push(`${'  '.repeat(indent)}${selector} {`);
            indent++;
            const rest = parts.slice(1).join('{').replace(/\s+/g, ' ').trim();
            if (rest && rest !== '}') {
                const declarations = rest.replace(/}.*$/, '').split(';').filter(caminho => caminho.trim());
                for (const decl of declarations) {
                    const td = decl.trim();
                    if (td && td !== '}') {
                        const colonIdx = td.indexOf(':');
                        if (colonIdx > 0) {
                            const prop = td.slice(0, colonIdx).trim();
                            const value = td.slice(colonIdx + 1).replace(/;$/, '').trim();
                            out.push(`${'  '.repeat(indent)}${prop}: ${value};`);
                        }
                        else {
                            out.push(`${'  '.repeat(indent)}${td.endsWith(';') ? td : `${td};`}`);
                        }
                    }
                }
            }
            if (rest.includes('}')) {
                indent = Math.max(0, indent - 1);
                out.push(`${'  '.repeat(indent)}}`);
            }
            continue;
        }
        if (trimmed.startsWith('@')) {
            out.push(`${'  '.repeat(indent)}${trimmed.endsWith(';') ? trimmed : `${trimmed};`}`);
            continue;
        }
        if (trimmed.includes(':')) {
            const colonIdx = trimmed.indexOf(':');
            if (colonIdx > 0) {
                const prop = trimmed.slice(0, colonIdx).trim();
                const rest = trimmed.slice(colonIdx + 1).trim();
                const value = rest.endsWith(';') ? rest.slice(0, -1).trim() : rest;
                out.push(`${'  '.repeat(indent)}${prop}: ${value};`);
                continue;
            }
        }
        out.push(`${'  '.repeat(indent)}${trimmed.endsWith(';') ? trimmed : trimmed}`);
    }
    const formatted = normalizarNewlinesFinais(out.join('\n'));
    const baseline = normalizarNewlinesFinais(normalized);
    return {
        ok: true,
        parser: 'scss',
        formatted,
        changed: formatted !== baseline,
        reason: 'estilo-tutanus-scss'
    };
}
export function formatarLessMinimo(code) {
    return formatarScssMinimo(code);
}
//# sourceMappingURL=css.js.map