const fs = require("fs")
const path = require("path")

/**
 * 
 * .vscode/tasks.json
VS code Task
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Find Unused i18n Keys",
      "type": "shell",
      "command": "node",
      "args": [
        "./scripts/find-i18n-keys.cjs",
        "${workspaceFolder}",
        "../app/client/src/orchestrator/i18n/de/index.ts"
      ],
      "group": "build",
      "presentation": {
        "reveal": "always",
        "panel": "new"
      },
      "options": {
        "cwd": "${workspaceFolder}"
      }
    }
  ]
}
 */

class I18nKeyFinder {
  constructor(workspaceRoot, i18nKeysFile) {
    this.workspaceRoot = workspaceRoot
    this.i18nKeysFile = i18nKeysFile
    this.usedKeys = new Set()
    this.possiblyUsedKeys = new Set()
    this.allKeys = new Set()

    // Patterns to search for definite usage
    this.definitePatterns = [
      /\bt\(['"]([^'"]+)['"]\)/g, // t('key') or t("key")
      /\bt\(['"]([^'"]+)['"],/g, // t('key', ...) or t("key", ...)
      /\$t\(['"]([^'"]+)['"]\)/g, // $t('key') or $t("key")
      /\$t\(['"]([^'"]+)['"],/g, // $t('key', ...) or $t("key", ...)
    ]

    // Patterns to search for possible usage (i18n object keys)
    this.possiblePatterns = [
      /i18n:\s*['"]([^'"]+)['"]/g, // i18n: "key" or i18n: 'key'
    ]
  }

  // Load all i18n keys from your translation file
  loadI18nKeys() {
    try {
      const content = fs.readFileSync(this.i18nKeysFile, "utf8")
      const data = JSON.parse(content)

      // Recursively extract all keys from nested object
      const extractKeys = (obj, prefix = "") => {
        Object.keys(obj).forEach((key) => {
          const fullKey = prefix ? `${prefix}.${key}` : key

          if (typeof obj[key] === "object" && obj[key] !== null) {
            extractKeys(obj[key], fullKey)
          } else {
            this.allKeys.add(fullKey)
          }
        })
      }

      extractKeys(data)
      console.log(`Loaded ${this.allKeys.size} i18n keys`)
    } catch (error) {
      console.error("Error loading i18n keys:", error)
    }
  }

  // Search for translation key usage in a file
  searchInFile(filePath) {
    try {
      const content = fs.readFileSync(filePath, "utf8")

      // Search for definite usage patterns
      this.definitePatterns.forEach((pattern) => {
        let match

        while ((match = pattern.exec(content)) !== null) {
          this.usedKeys.add(match[1])
        }
      })

      // Search for possible usage patterns
      this.possiblePatterns.forEach((pattern) => {
        let match

        while ((match = pattern.exec(content)) !== null) {
          this.possiblyUsedKeys.add(match[1])
        }
      })
    } catch (error) {
      // Skip files that can't be read
    }
  }

  // Recursively search through directories
  searchDirectory(dir) {
    const items = fs.readdirSync(dir)

    items.forEach((item) => {
      const fullPath = path.join(dir, item)
      const stat = fs.statSync(fullPath)

      if (stat.isDirectory()) {
        // Skip common directories that won't contain translation calls
        if (
          !["node_modules", ".git", "dist", "build", ".next"].includes(item)
        ) {
          this.searchDirectory(fullPath)
        }
      } else if (stat.isFile()) {
        // Only search in relevant file types
        const ext = path.extname(item).toLowerCase()

        if ([".js", ".ts", ".jsx", ".tsx", ".vue", ".svelte"].includes(ext)) {
          this.searchInFile(fullPath)
        }
      }
    })
  }

  // Main function to find unused keys
  findUnusedKeys() {
    console.log("Loading i18n keys...")
    this.loadI18nKeys()

    console.log("Searching for key usage in workspace...")
    this.searchDirectory(this.workspaceRoot)

    console.log(`Found ${this.usedKeys.size} definitely used keys`)
    console.log(`Found ${this.possiblyUsedKeys.size} possibly used keys`)

    // Combine all used keys (definite + possible)
    const allUsedKeys = new Set([...this.usedKeys, ...this.possiblyUsedKeys])

    // Find unused keys
    const unusedKeys = Array.from(this.allKeys).filter(
      (key) => !allUsedKeys.has(key),
    )

    // Generate report
    console.log("\n=== REPORT ===")
    console.log(`Total i18n keys: ${this.allKeys.size}`)
    console.log(`Definitely used keys: ${this.usedKeys.size}`)
    console.log(`Possibly used keys: ${this.possiblyUsedKeys.size}`)
    console.log(`Total used keys: ${allUsedKeys.size}`)
    console.log(`Unused keys: ${unusedKeys.length}`)

    // Show definitely used keys
    if (this.usedKeys.size > 0) {
      console.log("\nDefinitely used keys (t() and $t() functions):")
      Array.from(this.usedKeys)
        .sort()
        .forEach((key) => console.log(`  ✓ ${key}`))
    }

    // Show possibly used keys
    if (this.possiblyUsedKeys.size > 0) {
      console.log('\nPossibly used keys (i18n: "key" patterns):')
      Array.from(this.possiblyUsedKeys)
        .sort()
        .forEach((key) => console.log(`  ? ${key}`))
    }

    // Show unused keys
    if (unusedKeys.length > 0) {
      console.log("\nUnused keys:")
      unusedKeys.sort().forEach((key) => console.log(`  - ${key}`))

      // Save to file
      fs.writeFileSync("unused-i18n-keys.txt", unusedKeys.join("\n"))
      console.log("\nUnused keys saved to: unused-i18n-keys.txt")
    }

    // Save detailed report
    const report = {
      summary: {
        total: this.allKeys.size,
        definitelyUsed: this.usedKeys.size,
        possiblyUsed: this.possiblyUsedKeys.size,
        totalUsed: allUsedKeys.size,
        unused: unusedKeys.length,
      },
      definitelyUsed: Array.from(this.usedKeys).sort(),
      possiblyUsed: Array.from(this.possiblyUsedKeys).sort(),
      unused: unusedKeys.sort(),
    }

    fs.writeFileSync("i18n-usage-report.json", JSON.stringify(report, null, 2))
    console.log("Detailed report saved to: i18n-usage-report.json")
  }
}

// Usage
const workspaceRoot = process.argv[2] || "./"
const i18nKeysFile = process.argv[3] || "./src/i18n/en.json"

const finder = new I18nKeyFinder(workspaceRoot, i18nKeysFile)

finder.findUnusedKeys()
