export function unwrapExpression(node) {
    let n = node;
    while (n) {
        if (n.type === 'TSAsExpression' || n.type === 'TSSatisfiesExpression') {
            n = n.expression;
            continue;
        }
        if (n.type === 'TypeCastExpression') {
            n = n.expression;
            continue;
        }
        if (n.type === 'ParenthesizedExpression') {
            n = n.expression;
            continue;
        }
        break;
    }
    return n;
}
function getPropKeyName(key) {
    return key?.type === 'Identifier'
        ? key.name
        : key?.type === 'StringLiteral'
            ? key.value
            : undefined;
}
/**
 * Extract a static string from:
 * - 'string literal'
 * - `template literal` with NO ${...} expressions
 * Also supports common TS wrappers like: (`...` as const)
 */
export function extractStaticString(node) {
    const n = unwrapExpression(node);
    if (!n)
        return null;
    if (n.type === 'StringLiteral')
        return n.value;
    if (n.type === 'TemplateLiteral') {
        if ((n.expressions?.length ?? 0) !== 0)
            return null;
        const quasis = n.quasis ?? [];
        return quasis.map((q) => q.value?.cooked ?? '').join('');
    }
    return null;
}
/**
 * SQL-specific variant:
 * - supports string literal / no-subst template literal
 * - supports ref('...') / shallowRef('...') wrappers
 */
export function extractStaticStringLikeSql(node) {
    const n = unwrapExpression(node);
    if (!n)
        return null;
    const direct = extractStaticString(n);
    if (direct != null)
        return direct;
    if (n.type === 'CallExpression') {
        const callee = unwrapExpression(n.callee);
        const calleeName = callee?.type === 'Identifier'
            ? callee.name
            : callee?.type === 'MemberExpression' &&
                !callee.computed &&
                callee.property?.type === 'Identifier'
                ? callee.property.name
                : null;
        // common Vue patterns: ref('...'), shallowRef('...')
        if (calleeName === 'ref' || calleeName === 'shallowRef') {
            const a0 = n.arguments?.[0];
            if (!a0)
                return null;
            return extractStaticString(a0);
        }
    }
    return null;
}
export function getObjectPropValue(objExpr, propName) {
    const obj = unwrapExpression(objExpr);
    if (!obj || obj.type !== 'ObjectExpression')
        return undefined;
    for (const p of obj.properties ?? []) {
        if (p?.type !== 'ObjectProperty')
            continue;
        if (p.computed)
            continue;
        const keyName = getPropKeyName(p.key);
        if (keyName === propName)
            return p.value;
    }
    return undefined;
}
