import fs from 'fs';
import path from 'path';
import readline from 'readline';

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

console.log('🚀 Configurando nuevo proyecto basado en el template...');

// Preguntar por el nombre del proyecto
rl.question('¿Cuál es el nombre del nuevo proyecto? ', (projectName) => {
  
  // Modificar package.json
  const packageJsonPath = path.join(process.cwd(), 'package.json');
  try {
    const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
    
    // Guardar el nombre original para reportar cambios
    const originalName = packageJson.name;
    
    // Actualizar el nombre del proyecto
    packageJson.name = projectName;
    
    // Actualizar versión y descripción
    packageJson.version = '0.1.0';
    packageJson.description = `${projectName} - Proyecto generado desde template`;
    
    // Guardar los cambios
    fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
    console.log(`✅ package.json actualizado: nombre cambiado de ${originalName} a ${projectName}`);
  } catch (error) {
    console.error('❌ Error al modificar package.json:', error);
  }
  
  // Modificar angular.json
  const angularJsonPath = path.join(process.cwd(), 'angular.json');
  try {
    const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, 'utf8'));
    
    // Obtener el nombre del proyecto original (la primera clave en el objeto projects)
    const originalProjectName = Object.keys(angularJson.projects)[0];
    
    // Crear nuevo objeto con el nuevo nombre del proyecto
    const projectConfig = angularJson.projects[originalProjectName];
    
    // Buscar otros nombres de proyectos en el archivo (como en outputPath o en configuraciones)
    // Este es un enfoque para encontrar nombres de proyectos "ocultos" en otras partes del archivo
    let angularJsonString = JSON.stringify(angularJson);
    const possibleProjectNames = new Set();
    
    // Buscar patrones como "dist/nombre-proyecto" o "nombre-proyecto:build"
    const outputPathRegex = /dist\/([a-zA-Z0-9-_]+)/g;
    const buildTargetRegex = /([a-zA-Z0-9-_]+):build/g;
    
    let match;
    while (match = outputPathRegex.exec(angularJsonString)) {
      possibleProjectNames.add(match[1]);
    }
    
    while (match = buildTargetRegex.exec(angularJsonString)) {
      possibleProjectNames.add(match[1]);
    }
    
    // Actualizar el outputPath
    if (projectConfig.architect?.build?.options?.outputPath) {
      const oldOutputPath = projectConfig.architect.build.options.outputPath;
      projectConfig.architect.build.options.outputPath = `dist/${projectName}`;
      console.log(`✅ Actualizado outputPath: de "${oldOutputPath}" a "dist/${projectName}"`);
    }
    
    // Actualizar referencias en las configuraciones de serve
    if (projectConfig.architect?.serve?.configurations) {
      Object.keys(projectConfig.architect.serve.configurations).forEach(configKey => {
        const config = projectConfig.architect.serve.configurations[configKey];
        if (config.buildTarget) {
          // Buscar el patrón "nombreProyecto:build:config"
          const parts = config.buildTarget.split(':');
          if (parts.length === 3) {
            const oldValue = config.buildTarget;
            config.buildTarget = `${projectName}:${parts[1]}:${parts[2]}`;
            console.log(`✅ Actualizada configuración de serve '${configKey}': de "${oldValue}" a "${config.buildTarget}"`);
          }
        }
      });
    }
    
    // Buscar y reemplazar todas las posibles ocurrencias de otros nombres de proyectos
    possibleProjectNames.forEach(oldName => {
      if (oldName !== originalProjectName && oldName !== projectName) {
        // Convertir a string para hacer reemplazos globales
        const jsonStr = JSON.stringify(projectConfig);
        if (jsonStr.includes(oldName)) {
          const updatedJsonStr = jsonStr.replace(new RegExp(oldName, 'g'), projectName);
          // Convertir de vuelta a objeto
          const updatedConfig = JSON.parse(updatedJsonStr);
          // Reemplazar la configuración con la versión actualizada
          Object.assign(projectConfig, updatedConfig);
          console.log(`✅ Reemplazado nombre de proyecto adicional: "${oldName}" por "${projectName}"`);
        }
      }
    });
    
    // Eliminar la entrada original
    delete angularJson.projects[originalProjectName];
    
    // Agregar nueva entrada con el nombre del proyecto
    angularJson.projects[projectName] = projectConfig;
    
    // Actualizar defaultProject si existe
    if (angularJson.defaultProject === originalProjectName) {
      angularJson.defaultProject = projectName;
    }
    
    // Actualizar rutas dentro de la configuración
    if (projectConfig.root === originalProjectName) {
      projectConfig.root = projectName;
    }
    
    // Guardar los cambios
    fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2));
    console.log(`✅ angular.json actualizado: nombre del proyecto cambiado de ${originalProjectName} a ${projectName}`);
  } catch (error) {
    console.error('❌ Error al modificar angular.json:', error);
  }
  
  // Modificar también src/index.html para actualizar el título
  try {
    const indexHtmlPath = path.join(process.cwd(), 'src', 'index.html');
    let indexHtml = fs.readFileSync(indexHtmlPath, 'utf8');
    
    // Reemplazar el título
    indexHtml = indexHtml.replace(/<title>.*<\/title>/, `<title>${projectName}</title>`);
    
    // Guardar los cambios
    fs.writeFileSync(indexHtmlPath, indexHtml);
    console.log('✅ src/index.html actualizado: título actualizado');
  } catch (error) {
    console.error('❌ Error al modificar src/index.html:', error);
  }
  
  console.log('\n🎉 Configuración completada! El proyecto está listo para ser usado.');
  console.log('Ejecuta `ng serve` para iniciar el servidor de desarrollo.');
  
  rl.close();
});