"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAliasesFromBasePath = createAliasesFromBasePath;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const chalk_1 = __importDefault(require("chalk"));
/**
 * Create or update aliases in vite.config based on actual file locations under basePath
 */
async function createAliasesFromBasePath(cwd, basePath, componentName) {
    const viteConfigPaths = [
        path_1.default.resolve(cwd, 'vite.config.ts'),
        path_1.default.resolve(cwd, 'vite.config.js'),
    ];
    const normalizedBasePath = path_1.default.join(basePath).replace(/\\/g, '/').replace(/\/$/, '');
    const componentBaseDir = path_1.default.resolve(cwd, basePath, componentName);
    const basePathDir = path_1.default.resolve(cwd, basePath);
    // Scan the component directory structure recursively to find where constants, utils, etc. actually are
    const subdirs = {};
    async function scanDirectory(dirPath, relativePath = '', isBasePathLevel = false) {
        if (!await fs_extra_1.default.pathExists(dirPath))
            return;
        const entries = await fs_extra_1.default.readdir(dirPath, { withFileTypes: true });
        for (const entry of entries) {
            if (entry.isDirectory()) {
                const dirName = entry.name.toLowerCase();
                const fullRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
                // Check if this directory contains relevant files
                if (['constants', 'utils', 'types', 'hooks', 'assets', 'mocks', 'components'].includes(dirName)) {
                    let fullPath;
                    if (isBasePathLevel) {
                        // Supporting files are at basePath level (e.g., src/formbuilder/constants/)
                        fullPath = path_1.default.join(basePath, fullRelativePath).replace(/\\/g, '/');
                    }
                    else {
                        // Component files are under component directory (e.g., src/formbuilder/formbuilder/components/)
                        fullPath = path_1.default.join(basePath, componentName, fullRelativePath).replace(/\\/g, '/');
                    }
                    // Prefer basePath level directories over component-level ones for supporting files
                    // (except for 'components' which should point to the component directory)
                    if (dirName === 'components') {
                        if (!subdirs[dirName]) {
                            subdirs[dirName] = fullPath;
                        }
                    }
                    else {
                        if (!subdirs[dirName] || (isBasePathLevel && !subdirs[dirName].includes(componentName))) {
                            subdirs[dirName] = fullPath;
                        }
                    }
                }
                // Recursively scan subdirectories
                await scanDirectory(path_1.default.join(dirPath, entry.name), fullRelativePath, isBasePathLevel);
            }
        }
    }
    // Component root itself for components (alias should point to the shared base path, not a specific component)
    subdirs['components'] = normalizedBasePath;
    // First scan basePath level for supporting files (constants, utils, hooks, assets, mocks)
    await scanDirectory(basePathDir, '', true);
    // Then scan the component directory
    await scanDirectory(componentBaseDir);
    // Find vite config file
    let viteConfigFile = '';
    for (const configPath of viteConfigPaths) {
        if (await fs_extra_1.default.pathExists(configPath)) {
            viteConfigFile = configPath;
            break;
        }
    }
    if (!viteConfigFile) {
        return; // No vite config found
    }
    try {
        let viteConfig = await fs_extra_1.default.readFile(viteConfigFile, 'utf-8');
        // Check if project uses ES modules
        const packageJsonPath = path_1.default.resolve(cwd, 'package.json');
        let isESModule = false;
        if (await fs_extra_1.default.pathExists(packageJsonPath)) {
            try {
                const packageJson = await fs_extra_1.default.readJson(packageJsonPath);
                isESModule = packageJson.type === 'module';
            }
            catch {
                // Ignore errors
            }
        }
        // Determine __dirname syntax based on ES module
        const dirnameSyntax = isESModule
            ? "path.dirname(fileURLToPath(import.meta.url))"
            : "__dirname";
        // Check if resolve.alias exists
        const hasResolveAlias = /resolve:\s*\{[^}]*alias:\s*\{/s.test(viteConfig);
        // Build aliases based on actual structure
        const aliasesToAdd = [];
        if (subdirs.components) {
            aliasesToAdd.push(`      '#formickComponents': path.resolve(${dirnameSyntax}, '${subdirs.components}'),`);
        }
        if (subdirs.constants) {
            aliasesToAdd.push(`      '#formickConstants': path.resolve(${dirnameSyntax}, '${subdirs.constants}'),`);
        }
        if (subdirs.utils) {
            aliasesToAdd.push(`      '#formickUtils': path.resolve(${dirnameSyntax}, '${subdirs.utils}'),`);
        }
        if (subdirs.types) {
            aliasesToAdd.push(`      '#formickTypes': path.resolve(${dirnameSyntax}, '${subdirs.types}'),`);
        }
        if (subdirs.hooks) {
            aliasesToAdd.push(`      '#formickHooks': path.resolve(${dirnameSyntax}, '${subdirs.hooks}'),`);
        }
        if (subdirs.assets) {
            aliasesToAdd.push(`      '#formickAssets': path.resolve(${dirnameSyntax}, '${subdirs.assets}'),`);
        }
        if (subdirs.mocks) {
            aliasesToAdd.push(`      '#formickMocks': path.resolve(${dirnameSyntax}, '${subdirs.mocks}'),`);
        }
        if (aliasesToAdd.length === 0) {
            return; // No aliases to add
        }
        // Add necessary imports for ES modules
        if (isESModule && !viteConfig.includes('fileURLToPath')) {
            if (!viteConfig.includes('import path from')) {
                viteConfig = viteConfig.replace(/import\s+{[^}]+}\s+from\s+['"]vite['"];?/, (match) => `import path from 'path';\nimport { fileURLToPath } from 'url';\n${match}`);
            }
            else if (!viteConfig.includes('from \'url\'')) {
                viteConfig = viteConfig.replace(/import\s+path\s+from\s+['"]path['"];?/, (match) => `${match}\nimport { fileURLToPath } from 'url';`);
            }
            // Add __dirname constant if not present
            if (!viteConfig.includes('const __dirname')) {
                const importMatch = viteConfig.match(/import\s+{[^}]+}\s+from\s+['"]url['"];?/);
                if (importMatch) {
                    viteConfig = viteConfig.replace(importMatch[0], `${importMatch[0]}\n\nconst __dirname = ${dirnameSyntax};`);
                }
            }
        }
        else if (!isESModule && !viteConfig.includes('import path from')) {
            // Add path import for CommonJS
            viteConfig = viteConfig.replace(/import\s+{[^}]+}\s+from\s+['"]vite['"];?/, (match) => `import path from 'path';\n${match}`);
        }
        if (hasResolveAlias) {
            // Find the alias block - match the entire alias object
            // Use a more robust pattern that matches from alias: { to the closing }
            const aliasBlockMatch = viteConfig.match(/(alias:\s*\{)([\s\S]*?)(\n\s*\})/);
            if (aliasBlockMatch) {
                const [, aliasStart, aliasContent, closingBrace] = aliasBlockMatch;
                // Extract existing valid aliases (non-formick aliases that are properly formatted)
                // Use multiline matching to find complete alias entries
                const existingValidAliases = [];
                const lines = aliasContent.split('\n');
                for (const line of lines) {
                    const trimmedLine = line.trim();
                    // Match properly formatted alias: 'aliasName': path.resolve(...),
                    const validAliasMatch = trimmedLine.match(/^['"]([^'"]+)['"]\s*:\s*path\.resolve\([^)]+\)\s*,?\s*$/);
                    if (validAliasMatch) {
                        const aliasName = validAliasMatch[1];
                        // Keep non-formick aliases (preserve user's custom aliases)
                        if (!aliasName.startsWith('#formick')) {
                            // Preserve original indentation (6 spaces to match our format)
                            existingValidAliases.push('      ' + trimmedLine);
                        }
                    }
                }
                // Build the complete alias block with all formick aliases
                const allFormickAliases = aliasesToAdd;
                const allAliases = [...existingValidAliases, ...allFormickAliases];
                // Create properly formatted alias block with consistent indentation
                const formattedAliases = allAliases.length > 0
                    ? allAliases.join('\n') + '\n'
                    : '';
                // Replace the entire alias block
                viteConfig = viteConfig.replace(aliasBlockMatch[0], `${aliasStart}\n${formattedAliases}${closingBrace}`);
            }
        }
        else {
            // Create new resolve object
            const newAliases = aliasesToAdd.join('\n');
            const aliasConfig = `
    resolve: {
      alias: {
${newAliases}
      },
    },`;
            if (viteConfig.includes('export default defineConfig({')) {
                viteConfig = viteConfig.replace(/export default defineConfig\(\{/, `export default defineConfig({${aliasConfig}`);
            }
        }
        await fs_extra_1.default.writeFile(viteConfigFile, viteConfig);
    }
    catch (error) {
        console.warn(chalk_1.default.yellow('⚠️ Could not update Vite config aliases automatically.'));
    }
    // Also update tsconfig.json paths
    const tsconfigPath = path_1.default.resolve(cwd, 'tsconfig.json');
    if (await fs_extra_1.default.pathExists(tsconfigPath)) {
        try {
            let tsconfigContent = await fs_extra_1.default.readFile(tsconfigPath, 'utf-8');
            // Remove comments from JSON (TypeScript allows comments but JSON.parse doesn't)
            tsconfigContent = tsconfigContent.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/.*/g, '');
            const tsconfig = JSON.parse(tsconfigContent);
            if (!tsconfig.compilerOptions) {
                tsconfig.compilerOptions = {};
            }
            if (!tsconfig.compilerOptions.paths) {
                tsconfig.compilerOptions.paths = {};
            }
            // Add path mappings based on actual structure
            const pathMappings = {};
            if (subdirs.components) {
                pathMappings['#formickComponents/*'] = [`./${subdirs.components}/*`];
                pathMappings['#formickComponents'] = [`./${subdirs.components}`];
            }
            if (subdirs.constants) {
                pathMappings['#formickConstants/*'] = [`./${subdirs.constants}/*`];
                pathMappings['#formickConstants'] = [`./${subdirs.constants}`];
            }
            if (subdirs.utils) {
                pathMappings['#formickUtils/*'] = [`./${subdirs.utils}/*`];
                pathMappings['#formickUtils'] = [`./${subdirs.utils}`];
            }
            if (subdirs.types) {
                pathMappings['#formickTypes/*'] = [`./${subdirs.types}/*`];
                pathMappings['#formickTypes'] = [`./${subdirs.types}`];
            }
            if (subdirs.hooks) {
                pathMappings['#formickHooks/*'] = [`./${subdirs.hooks}/*`];
                pathMappings['#formickHooks'] = [`./${subdirs.hooks}`];
            }
            if (subdirs.assets) {
                pathMappings['#formickAssets/*'] = [`./${subdirs.assets}/*`];
                pathMappings['#formickAssets'] = [`./${subdirs.assets}`];
            }
            if (subdirs.mocks) {
                pathMappings['#formickMocks/*'] = [`./${subdirs.mocks}/*`];
                pathMappings['#formickMocks'] = [`./${subdirs.mocks}`];
            }
            // Only add if not already present
            let updated = false;
            for (const [alias, paths] of Object.entries(pathMappings)) {
                if (!tsconfig.compilerOptions.paths[alias]) {
                    tsconfig.compilerOptions.paths[alias] = paths;
                    updated = true;
                }
            }
            if (updated) {
                await fs_extra_1.default.writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2));
                console.log(chalk_1.default.green(`✓ Updated tsconfig.json with path aliases for ${componentName}`));
            }
        }
        catch (error) {
            console.warn(chalk_1.default.yellow('⚠️ Could not update tsconfig.json paths automatically.'));
            if (error instanceof Error) {
                console.warn(chalk_1.default.yellow(`   Error: ${error.message}`));
            }
        }
    }
    else {
        console.warn(chalk_1.default.yellow('⚠️ tsconfig.json not found. Path aliases will not be configured.'));
    }
}
//# sourceMappingURL=aliasManager.js.map