"use strict";
/**
 * Component Analyzer Service
 * Analyzes React components for accessibility issues
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComponentAnalyzer = void 0;
const parser_1 = require("@babel/parser");
const traverse_1 = __importDefault(require("@babel/traverse"));
const t = __importStar(require("@babel/types"));
const logger_1 = require("@bluefly/llmcli/utils/logger");
class ComponentAnalyzer {
    constructor() { }
    static getInstance() {
        if (!ComponentAnalyzer.instance) {
            ComponentAnalyzer.instance = new ComponentAnalyzer();
        }
        return ComponentAnalyzer.instance;
    }
    async analyzeComponent(componentCode, options = {}) {
        try {
            // Parse the component code
            const ast = (0, parser_1.parse)(componentCode, {
                sourceType: 'module',
                plugins: ['jsx', 'typescript']
            });
            const componentNodes = [];
            const results = [];
            // Traverse the AST to extract component information
            (0, traverse_1.default)(ast, {
                JSXElement(path) {
                    const node = path.node;
                    const componentNode = this.extractComponentNode(node);
                    if (componentNode) {
                        componentNodes.push(componentNode);
                    }
                }
            });
            // Analyze each component node
            for (const node of componentNodes) {
                const nodeResults = await this.analyzeComponentNode(node, options);
                results.push(...nodeResults);
            }
            return results;
        }
        catch (error) {
            logger_1.logger.error('Component analysis failed:', error);
            throw new Error('Failed to analyze component');
        }
    }
    extractComponentNode(node) {
        if (!t.isJSXIdentifier(node.openingElement.name)) {
            return null;
        }
        const props = {};
        node.openingElement.attributes.forEach(attr => {
            if (t.isJSXAttribute(attr)) {
                const name = attr.name.name;
                let value = null;
                if (attr.value) {
                    if (t.isStringLiteral(attr.value)) {
                        value = attr.value.value;
                    }
                    else if (t.isJSXExpressionContainer(attr.value)) {
                        if (t.isStringLiteral(attr.value.expression)) {
                            value = attr.value.expression.value;
                        }
                    }
                }
                props[name] = value;
            }
        });
        const children = [];
        node.children.forEach(child => {
            if (t.isJSXElement(child)) {
                const childNode = this.extractComponentNode(child);
                if (childNode) {
                    children.push(childNode);
                }
            }
        });
        return {
            type: 'JSXElement',
            name: node.openingElement.name.name,
            props,
            children,
            location: node.loc ? {
                start: { line: node.loc.start.line, column: node.loc.start.column },
                end: { line: node.loc.end.line, column: node.loc.end.column }
            } : undefined
        };
    }
    async analyzeComponentNode(node, options) {
        const results = [];
        // Check for common accessibility issues
        if (node.name === 'img' && !node.props.alt) {
            results.push({
                criterion: '1.1.1',
                severity: 'error',
                message: 'Image missing alt text',
                details: `Image element at line ${node.location?.start.line} has no alt attribute`,
                fix: 'Add alt="description" to the image element',
                component: node.name,
                code: generateComponentCode(node),
                aiSuggestions: ['Consider adding descriptive alt text for screen readers']
            });
        }
        if (node.name === 'button' && !node.props['aria-label'] && !node.props.children) {
            results.push({
                criterion: '4.1.2',
                severity: 'error',
                message: 'Button missing accessible name',
                details: `Button at line ${node.location?.start.line} has no accessible name`,
                fix: 'Add aria-label="description" or text content to the button',
                component: node.name,
                code: generateComponentCode(node),
                aiSuggestions: ['Add descriptive text or aria-label to the button']
            });
        }
        if (node.name === 'div' && node.props.role === 'button' && !node.props.tabIndex) {
            results.push({
                criterion: '2.1.1',
                severity: 'error',
                message: 'Custom button missing keyboard accessibility',
                details: `Div with role="button" at line ${node.location?.start.line} is not keyboard focusable`,
                fix: 'Add tabIndex={0} to make the element keyboard focusable',
                component: node.name,
                code: generateComponentCode(node),
                aiSuggestions: ['Make the element keyboard focusable and add keyboard event handlers']
            });
        }
        // Check children recursively
        for (const child of node.children) {
            const childResults = await this.analyzeComponentNode(child, options);
            results.push(...childResults);
        }
        return results;
    }
}
exports.ComponentAnalyzer = ComponentAnalyzer;
function generateComponentCode(node) {
    const props = Object.entries(node.props)
        .map(([key, value]) => {
        if (typeof value === 'string') {
            return `${key}="${value}"`;
        }
        return `${key}={${JSON.stringify(value)}}`;
    })
        .join(' ');
    return `<${node.name} ${props}>${node.children.map(generateComponentCode).join('')}</${node.name}>`;
}
//# sourceMappingURL=component-analyzer.js.map