#!/usr/bin/env node

const fs = require("fs");
const path = require("path");
const { parseCollectionYaml } = require("./yaml-parser");

/**
 * Simple YAML parser for configuration files
 */
function parseConfigYamlContent(content) {
  const lines = content.split("\n");
  const result = {};
  let currentSection = null;

  for (const line of lines) {
    const trimmed = line.trim();

    // Skip comments and empty lines
    if (!trimmed || trimmed.startsWith("#")) continue;

    if (!trimmed.includes(":")) {
      continue;
    }

    const colonIndex = trimmed.indexOf(":");
    const key = trimmed.substring(0, colonIndex).trim();
    let value = trimmed.substring(colonIndex + 1).trim();

    // Remove quotes if present
    if ((value.startsWith('"') && value.endsWith('"')) ||
        (value.startsWith("'") && value.endsWith("'"))) {
      value = value.slice(1, -1);
    }

    // Handle sections (no value)
    if (!value) {
      currentSection = key;
      if (!result[currentSection]) {
        result[currentSection] = {};
      }
      continue;
    }

    // Handle boolean values
    if (value === "true") value = true;
    else if (value === "false") value = false;

    if (currentSection) {
      result[currentSection][key] = value;
    } else {
      result[key] = value;
    }
  }

  return result;
}

function parseConfigYaml(filePath) {
  try {
    const content = fs.readFileSync(filePath, "utf8");
    return parseConfigYamlContent(content);
  } catch (error) {
    console.error(`Error parsing config file ${filePath}: ${error.message}`);
    return null;
  }
}

/**
 * Apply configuration and copy enabled files to project
 */
async function applyConfig(configPath = "awesome-copilot.config.yml") {
  if (!fs.existsSync(configPath)) {
    console.error(`Configuration file not found: ${configPath}`);
    console.log("Run 'node generate-config.js' to create a configuration file first.");
    process.exit(1);
  }

  const config = parseConfigYaml(configPath);
  if (!config) {
    console.error("Failed to parse configuration file");
    process.exit(1);
  }

  console.log("Applying awesome-copilot configuration...");

  const rootDir = __dirname;
  const outputDir = config.project?.output_directory || ".github";

  // Create output directory structure
  ensureDirectoryExists(outputDir);
  ensureDirectoryExists(path.join(outputDir, "prompts"));
  ensureDirectoryExists(path.join(outputDir, "instructions"));
  ensureDirectoryExists(path.join(outputDir, "chatmodes"));

  let copiedCount = 0;
  const summary = {
    prompts: 0,
    instructions: 0,
    chatmodes: 0,
    collections: 0
  };

  // Import config manager for effective state computation
  const { computeEffectiveItemStates } = require("./config-manager");

  // Compute effective states using precedence rules
  const effectiveStates = computeEffectiveItemStates(config);

  // Create sets of effectively enabled items for performance
  const effectivelyEnabledSets = {
    prompts: new Set(),
    instructions: new Set(),
    chatmodes: new Set()
  };

  for (const section of ["prompts", "instructions", "chatmodes"]) {
    for (const [itemName, state] of Object.entries(effectiveStates[section])) {
      if (state.enabled) {
        effectivelyEnabledSets[section].add(itemName);
      }
    }
  }

  // Count enabled collections for summary
  if (config.collections) {
    for (const [collectionName, enabled] of Object.entries(config.collections)) {
      if (enabled) {
        const collectionPath = path.join(rootDir, "collections", `${collectionName}.collection.yml`);
        if (fs.existsSync(collectionPath)) {
          const collection = parseCollectionYaml(collectionPath);
          if (collection && collection.items) {
            summary.collections++;
            console.log(`✓ Enabled collection: ${collectionName} (${collection.items.length} items)`);
          }
        }
      }
    }
  }

  // Clean up files that are no longer enabled (requirement #3: Toggling instructions off will remove them)
  const cleanupSummary = cleanupDisabledFiles(outputDir, effectivelyEnabledSets, rootDir);
  
  // Process prompts using effective states
  for (const promptName of effectivelyEnabledSets.prompts) {
    const sourcePath = path.join(rootDir, "prompts", `${promptName}.prompt.md`);
    if (fs.existsSync(sourcePath)) {
      const destPath = path.join(outputDir, "prompts", `${promptName}.prompt.md`);
      if (copyFile(sourcePath, destPath)) {
        copiedCount++;
      }
      summary.prompts++;
    }
  }

  // Process instructions using effective states
  for (const instructionName of effectivelyEnabledSets.instructions) {
    const sourcePath = path.join(rootDir, "instructions", `${instructionName}.instructions.md`);
    if (fs.existsSync(sourcePath)) {
      const destPath = path.join(outputDir, "instructions", `${instructionName}.instructions.md`);
      if (copyFile(sourcePath, destPath)) {
        copiedCount++;
      }
      summary.instructions++;
    }
  }

  // Process chat modes using effective states
  for (const chatmodeName of effectivelyEnabledSets.chatmodes) {
    const sourcePath = path.join(rootDir, "chatmodes", `${chatmodeName}.chatmode.md`);
    if (fs.existsSync(sourcePath)) {
      const destPath = path.join(outputDir, "chatmodes", `${chatmodeName}.chatmode.md`);
      if (copyFile(sourcePath, destPath)) {
        copiedCount++;
      }
      summary.chatmodes++;
    }
  }

  // Generate summary
  console.log("\n" + "=".repeat(50));
  console.log("Configuration applied successfully!");
  console.log("=".repeat(50));
  console.log(`📂 Output directory: ${outputDir}`);
  console.log(`📝 Total files copied: ${copiedCount}`);
  console.log(`🎯 Prompts: ${summary.prompts}`);
  console.log(`📋 Instructions: ${summary.instructions}`);
  console.log(`💭 Chat modes: ${summary.chatmodes}`);
  console.log(`📦 Collections: ${summary.collections}`);

  if (config.project?.name) {
    console.log(`🏷️  Project: ${config.project.name}`);
  }

  console.log("\nNext steps:");
  console.log("1. Add the files to your version control system");
  console.log("2. Use prompts with /awesome-copilot command in GitHub Copilot Chat");
  console.log("3. Instructions will automatically apply to your coding");
  console.log("4. Import chat modes in VS Code settings");
}

/**
 * Ensure directory exists, create if it doesn't
 */
function ensureDirectoryExists(dirPath) {
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath, { recursive: true });
    console.log(`📁 Created directory: ${dirPath}`);
  }
}

/**
 * Copy file from source to destination with idempotency check
 */
function copyFile(sourcePath, destPath) {
  // Check if destination exists and has same content (idempotency)
  if (fs.existsSync(destPath)) {
    const sourceContent = fs.readFileSync(sourcePath, 'utf8');
    const destContent = fs.readFileSync(destPath, 'utf8');
    
    if (sourceContent === destContent) {
      console.log(`✓ Already exists and up-to-date: ${path.basename(sourcePath)}`);
      return false; // No copy needed
    }
  }
  
  fs.copyFileSync(sourcePath, destPath);
  console.log(`✓ Copied: ${path.basename(sourcePath)}`);
  return true; // File was copied
}

/**
 * Cleans up files in the output directory that are no longer enabled.
 *
 * @param {string} outputDir - The root directory where generated files are stored.
 * @param {Object} effectivelyEnabledSets - An object mapping section names to Sets of enabled item names.
 * @param {string} rootDir - The root directory of the project (used for path resolution).
 * @returns {Object} Summary of the number of files removed per section.
 */
function cleanupDisabledFiles(outputDir, effectivelyEnabledSets, rootDir) {
  const removedCounts = {
    prompts: 0,
    instructions: 0,
    chatmodes: 0
  };

  const sections = [
    { name: "prompts", ext: ".prompt.md" },
    { name: "instructions", ext: ".instructions.md" },
    { name: "chatmodes", ext: ".chatmode.md" }
  ];

  for (const section of sections) {
    const sectionDir = path.join(outputDir, section.name);
    if (!fs.existsSync(sectionDir)) continue;

    const existingFiles = fs.readdirSync(sectionDir);
    for (const fileName of existingFiles) {
      if (!fileName.endsWith(section.ext)) continue;
      
      const itemName = fileName.replace(section.ext, '');
      
      // Check if this item is still enabled
      if (!effectivelyEnabledSets[section.name].has(itemName)) {
        const filePath = path.join(sectionDir, fileName);
        fs.unlinkSync(filePath);
        cleanupSummary[section.name]++;
        console.log(`🗑️  Removed: ${section.name}/${fileName}`);
      }
    }
  }

  return cleanupSummary;
}

// CLI usage
if (require.main === module) {
  const configPath = process.argv[2] || "awesome-copilot.config.yml";
  applyConfig(configPath).catch(error => {
    console.error("Error applying configuration:", error.message);
    process.exit(1);
  });
}

module.exports = {
  applyConfig,
  parseConfigYaml,
  parseConfigYamlContent
};
