<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

class RemoveUnusedTranslationsCommand extends Command
{
    protected $signature = 'translations:remove-unused
                            {--dry-run : Preview changes without applying them}
                            {--backup : Create backup before removing}';

    protected $description = 'Remove unused translation keys from language files';

    private array $usedTranslations = [];
    private array $trTranslations = [];
    private array $enTranslations = [];
    private array $unusedTranslations = [];
    private int $removedCount = 0;

    public function handle(): int
    {
        $this->info('🗑️  Removing unused translations...');
        $this->newLine();

        // Step 1: Analyze translations
        $this->scanForUsedTranslations();
        $this->loadTranslations();
        $this->findUnusedTranslations();

        if (empty($this->unusedTranslations)) {
            $this->components->success('✓ No unused translations found!');
            return Command::SUCCESS;
        }

        $this->info("Found ".count($this->unusedTranslations)." unused translations");

        // Step 2: Backup if requested
        if ($this->option('backup')) {
            $this->createBackup();
        }

        // Step 3: Confirm before removal
        if (!$this->option('dry-run')) {
            if (!$this->confirm('Do you want to remove '.count($this->unusedTranslations).' unused translations?', true)) {
                $this->info('Operation cancelled.');
                return Command::SUCCESS;
            }
        }

        // Step 4: Remove unused translations
        $this->removeUnusedFromFiles();

        // Step 5: Summary
        if ($this->option('dry-run')) {
            $this->components->info("🔍 DRY RUN - No changes were made");
            $this->info("Would remove {$this->removedCount} translation keys");
        } else {
            $this->components->success("✓ Removed {$this->removedCount} unused translation keys");
        }

        return Command::SUCCESS;
    }

    private function scanForUsedTranslations(): void
    {
        $this->info('📂 Scanning for used translations...');

        // Scan Blade files
        $bladeFiles = $this->findFiles(resource_path('views'), '*.blade.php');
        foreach ($bladeFiles as $file) {
            $this->scanFile($file);
        }

        // Scan PHP files
        $phpDirectories = [
            app_path('Http/Controllers'),
            app_path('Services'),
            app_path('Models'),
            app_path('Helpers'),
            app_path('Jobs'),
            app_path('Listeners'),
            app_path('Events'),
            app_path('Console/Commands'),
            app_path('Rules'),
            app_path('Policies'),
        ];

        foreach ($phpDirectories as $dir) {
            if (is_dir($dir)) {
                $phpFiles = $this->findFiles($dir, '*.php');
                foreach ($phpFiles as $file) {
                    $this->scanFile($file);
                }
            }
        }

        $this->info("✓ Found ".count($this->usedTranslations)." used translation keys");
    }

    private function scanFile(string $file): void
    {
        $content = file_get_contents($file);
        if ($content === false) {
            return;
        }

        $patterns = [
            '__\([\'"]([^\'"]+)[\'"]\)',
            '@lang\([\'"]([^\'"]+)[\'"]\)',
            'trans\([\'"]([^\'"]+)[\'"]\)',
            'Lang::get\([\'"]([^\'"]+)[\'"]\)',
        ];

        foreach ($patterns as $pattern) {
            if (preg_match_all('/'.$pattern.'/', $content, $matches)) {
                foreach ($matches[1] as $key) {
                    $this->usedTranslations[$key] = true;
                }
            }
        }
    }

    private function loadTranslations(): void
    {
        $this->info('📚 Loading translation files...');
        $this->trTranslations = $this->loadLanguageDirectory(lang_path('tr'));
        $this->enTranslations = $this->loadLanguageDirectory(lang_path('en'));
    }

    private function loadLanguageDirectory(string $directory): array
    {
        $translations = [];
        $files = $this->findFiles($directory, '*.php');

        foreach ($files as $file) {
            $fileTranslations = require $file;
            if (!is_array($fileTranslations)) {
                continue;
            }

            $fileName = pathinfo($file, PATHINFO_FILENAME);
            if (str_contains($file, '/admin/')) {
                $fileName = 'admin/'.$fileName;
            } elseif (str_contains($file, '/store/')) {
                $fileName = 'store/'.$fileName;
            }

            $flattened = $this->flattenArray($fileTranslations, $fileName);
            $translations = array_merge($translations, $flattened);
        }

        return $translations;
    }

    private function flattenArray(array $array, string $prefix = ''): array
    {
        $result = [];
        foreach ($array as $key => $value) {
            $newKey = $prefix ? $prefix.'.'.$key : $key;
            if (is_array($value)) {
                $result = array_merge($result, $this->flattenArray($value, $newKey));
            } else {
                $result[$newKey] = $value;
            }
        }
        return $result;
    }

    private function findUnusedTranslations(): void
    {
        $this->info('🔬 Finding unused translations...');

        $allKeys = array_unique(array_merge(
            array_keys($this->trTranslations),
            array_keys($this->enTranslations)
        ));

        foreach ($allKeys as $key) {
            if (!isset($this->usedTranslations[$key])) {
                $this->unusedTranslations[$key] = true;
            }
        }
    }

    private function createBackup(): void
    {
        $backupDir = storage_path('backups/translations');
        if (!is_dir($backupDir)) {
            mkdir($backupDir, 0755, true);
        }

        $timestamp = date('Y-m-d_His');
        $backupPath = $backupDir.'/backup_'.$timestamp;

        // Copy TR files
        $this->copyDirectory(lang_path('tr'), $backupPath.'/tr');

        // Copy EN files
        $this->copyDirectory(lang_path('en'), $backupPath.'/en');

        $this->info("✓ Backup created at: {$backupPath}");
    }

    private function copyDirectory(string $source, string $destination): void
    {
        if (!is_dir($destination)) {
            mkdir($destination, 0755, true);
        }

        $files = $this->findFiles($source, '*.php');
        foreach ($files as $file) {
            $relativePath = str_replace($source.'/', '', $file);
            $destPath = $destination.'/'.$relativePath;
            $destDir = dirname($destPath);

            if (!is_dir($destDir)) {
                mkdir($destDir, 0755, true);
            }

            copy($file, $destPath);
        }
    }

    private function removeUnusedFromFiles(): void
    {
        $this->info('🗑️  Removing unused translations...');
        $this->newLine();

        $languages = ['tr', 'en'];

        foreach ($languages as $lang) {
            $langPath = lang_path($lang);
            $files = $this->findFiles($langPath, '*.php');

            foreach ($files as $file) {
                $this->processFile($file, $lang);
            }
        }
    }

    private function processFile(string $filePath, string $lang): void
    {
        $content = file_get_contents($filePath);
        if ($content === false) {
            return;
        }

        // Get file prefix
        $fileName = pathinfo($filePath, PATHINFO_FILENAME);
        if (str_contains($filePath, '/admin/')) {
            $filePrefix = 'admin/'.$fileName;
        } elseif (str_contains($filePath, '/store/')) {
            $filePrefix = 'store/'.$fileName;
        } else {
            $filePrefix = $fileName;
        }

        // Parse the file and remove unused keys
        $array = require $filePath;
        if (!is_array($array)) {
            return;
        }

        $modified = false;
        $cleanedArray = $this->removeUnusedKeys($array, $filePrefix, $modified);

        if ($modified) {
            if (!$this->option('dry-run')) {
                $this->writeArrayToFile($filePath, $cleanedArray);
                $this->line("  ✓ Cleaned: ".basename($filePath));
            } else {
                $this->line("  → Would clean: ".basename($filePath));
            }
        }
    }

    private function removeUnusedKeys(array $array, string $prefix, bool &$modified): array
    {
        $result = [];

        foreach ($array as $key => $value) {
            $fullKey = $prefix ? $prefix.'.'.$key : $key;

            if (is_array($value)) {
                // Recursively clean nested arrays
                $cleaned = $this->removeUnusedKeys($value, $fullKey, $modified);
                if (!empty($cleaned)) {
                    $result[$key] = $cleaned;
                } else {
                    $modified = true;
                    $this->removedCount++;
                }
            } else {
                // Check if this translation is used
                if (isset($this->unusedTranslations[$fullKey])) {
                    $modified = true;
                    $this->removedCount++;
                    // Skip this key (don't add to result)
                } else {
                    $result[$key] = $value;
                }
            }
        }

        return $result;
    }

    private function writeArrayToFile(string $filePath, array $array): void
    {
        $export = "<?php\n\nreturn " . $this->varExport($array, 1) . ";\n";
        file_put_contents($filePath, $export);
    }

    private function varExport(array $array, int $indent = 0): string
    {
        $indentStr = str_repeat('    ', $indent);
        $output = "[\n";

        foreach ($array as $key => $value) {
            $output .= $indentStr . "    ";

            if (is_string($key)) {
                $output .= "'" . addslashes($key) . "' => ";
            } else {
                $output .= $key . " => ";
            }

            if (is_array($value)) {
                $output .= $this->varExport($value, $indent + 1);
            } elseif (is_string($value)) {
                $output .= "'" . addslashes($value) . "'";
            } elseif (is_bool($value)) {
                $output .= $value ? 'true' : 'false';
            } elseif (is_null($value)) {
                $output .= 'null';
            } else {
                $output .= $value;
            }

            $output .= ",\n";
        }

        $output .= $indentStr . "]";
        return $output;
    }

    private function findFiles(string $directory, string $pattern): array
    {
        if (!is_dir($directory)) {
            return [];
        }

        $files = [];
        try {
            $iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS)
            );

            foreach ($iterator as $file) {
                if ($file->isFile() && fnmatch($pattern, $file->getFilename())) {
                    $files[] = $file->getPathname();
                }
            }
        } catch (\Exception $e) {
            // Skip directories that can't be read
        }

        return $files;
    }
}
