<?php

namespace App;

use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;

class GitHandler
{
    private $storagePath;

    public function __construct($storagePath = '/tmp/botajs_git')
    {
        $this->storagePath = $storagePath;
        if (!is_dir($this->storagePath)) {
            mkdir($this->storagePath, 0755, true);
        }
    }

    /**
     * Generate SSH key pair
     */
    public function generateSSHKey()
    {
        $rsa = \phpseclib3\Crypt\RSA::createKey(4096);

        $publicKey = $rsa->getPublicKey()->toString('OpenSSH');
        $privateKey = $rsa->toString('PKCS8');

        return [
            'public' => $publicKey,
            'private' => $privateKey,
        ];
    }

    /**
     * Export bot to GitHub
     */
    public function exportBot($botId, $gitRepoUrl, $branch, $commitMessage, $sshPrivateKey, $userEmail, $botajsApiKey)
    {
        try {
            $tempDir = $this->storagePath . '/' . uniqid('export_');
            $sshKeyDir = $tempDir . '_keys';
            mkdir($sshKeyDir, 0755, true);

            $sshKeyPath = $sshKeyDir . '/deploy_key';
            file_put_contents($sshKeyPath, $sshPrivateKey);
            chmod($sshKeyPath, 0600);

            $this->cloneRepository($gitRepoUrl, $tempDir, $sshKeyPath);

            $botajsClient = new BotAJSClient($botajsApiKey);
            $botData = $botajsClient->getBot($botId);
            $commandsData = $botajsClient->getBotCommands($botId);

            $bot = $botData['bot'] ?? [];
            $commands = $commandsData['commands'] ?? [];

            $this->generateBotFiles($bot, $commands, $tempDir);

            $this->commitAndPush(
                $tempDir,
                $sshKeyPath,
                $commitMessage ?? "Update bot: {$botId}",
                $branch ?? 'main',
                $userEmail
            );

            $this->cleanupDirectory($tempDir);
            if (isset($sshKeyDir) && is_dir($sshKeyDir)) {
                $this->cleanupDirectory($sshKeyDir);
            }

            return [
                'success' => true,
                'message' => 'Bot exported successfully',
                'commands_exported' => count($commands),
            ];

        } catch (\Exception $e) {
            if (isset($tempDir) && is_dir($tempDir)) {
                $this->cleanupDirectory($tempDir);
            }
            if (isset($sshKeyDir) && is_dir($sshKeyDir)) {
                $this->cleanupDirectory($sshKeyDir);
            }
            throw new \Exception('Export failed: ' . $e->getMessage());
        }
    }

    /**
     * Import bot from GitHub
     */
    public function importBot($botId, $gitRepoUrl, $branch, $sshPrivateKey, $botajsApiKey)
    {
        try {
            $tempDir = $this->storagePath . '/' . uniqid('import_');
            $sshKeyDir = $tempDir . '_keys';
            mkdir($sshKeyDir, 0755, true);

            $sshKeyPath = $sshKeyDir . '/deploy_key';
            file_put_contents($sshKeyPath, $sshPrivateKey);
            chmod($sshKeyPath, 0600);

            $this->cloneRepository($gitRepoUrl, $tempDir, $sshKeyPath);

            if ($branch && $branch !== 'main') {
                $this->runGitCommand(['checkout', $branch], $tempDir, $sshKeyPath);
            }

            // Look for commands in the root commands directory
            $commandsDir = $tempDir . '/commands';

            if (!is_dir($commandsDir)) {
                $this->cleanupDirectory($tempDir);
                throw new \Exception("Commands directory not found: /commands (expected in repository root)");
            }

            $importedCount = 0;
            $botajsClient = new BotAJSClient($botajsApiKey);
            $files = glob($commandsDir . '/*.js');

            foreach ($files as $file) {
                $commandName = basename($file, '.js');
                $commandName = str_replace('_', '/', $commandName);
                $commandName = str_replace('default', '*', $commandName);

                $code = file_get_contents($file);
                $code = preg_replace('/\/\*\*[\s\S]*?\*\//', '', $code);
                $code = trim($code);

                $botajsClient->createCommand(
                    $botId,
                    $commandName,
                    base64_encode($code),
                    false
                );

                $importedCount++;
            }

            $this->cleanupDirectory($tempDir);
            if (isset($sshKeyDir) && is_dir($sshKeyDir)) {
                $this->cleanupDirectory($sshKeyDir);
            }

            return [
                'success' => true,
                'message' => 'Bot imported successfully',
                'commands_imported' => $importedCount,
            ];

        } catch (\Exception $e) {
            if (isset($tempDir) && is_dir($tempDir)) {
                $this->cleanupDirectory($tempDir);
            }
            if (isset($sshKeyDir) && is_dir($sshKeyDir)) {
                $this->cleanupDirectory($sshKeyDir);
            }
            throw new \Exception('Import failed: ' . $e->getMessage());
        }
    }

    /**
     * Clone repository using SSH
     */
    private function cloneRepository($repoUrl, $targetDir, $sshKeyPath)
    {
        $this->runGitCommand(['clone', $repoUrl, $targetDir], null, $sshKeyPath);
    }

    /**
     * Generate bot files structure
     */
    private function generateBotFiles($bot, $commands, $targetDir)
    {
        // Create bot.json in root with bot metadata
        $botConfig = [
            'id' => $bot['botId'],
            'name' => $bot['info']['first_name'] ?? 'Unknown',
            'platform' => $bot['platform'],
            'language' => $bot['language'],
            'token' => '***SECURE_TOKEN***',
            'created_at' => $bot['created_at'],
            'updated_at' => $bot['updated_at']
        ];

        file_put_contents(
            $targetDir . '/bot.json',
            json_encode($botConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
        );

        // Create commands directory in root
        $commandsDir = $targetDir . '/commands';
        @mkdir($commandsDir, 0755, true);

        foreach ($commands as $command) {
            $fileName = str_replace(['/', '*'], ['_', 'default'], $command['command']) . '.js';
            $commandFile = $commandsDir . '/' . $fileName;

            $decodedCode = !empty($command['code']) ? base64_decode($command['code']) : '// No code provided';

            $fileContent = "/**\n";
            $fileContent .= " * Command: {$command['command']}\n";
            $fileContent .= " * Created: {$command['created_at']}\n";
            $fileContent .= " * Updated: {$command['updated_at']}\n";
            if (!empty($command['aliases'])) {
                $aliases = is_array($command['aliases']) ? implode(', ', $command['aliases']) : $command['aliases'];
                $fileContent .= " * Aliases: {$aliases}\n";
            }
            $fileContent .= " */\n\n";
            $fileContent .= $decodedCode;

            file_put_contents($commandFile, $fileContent);
        }

        $botName = $bot['info']['first_name'] ?? 'Bot';
        $botUsername = $bot['info']['username'] ?? $bot['info']['phoneNumberId'] ?? 'N/A';
        $platform = ucfirst($bot['platform']);
        $language = strtoupper($bot['language']);

        // Generate comprehensive README
        $readme = "# {$botName} – BotAJS {$platform} Bot\n\n";
        $readme .= "This is a {$platform} bot built with **BotAJS** – a modern, cross-platform bot framework that supports Telegram, WhatsApp, Discord, and more.\n\n";
        $readme .= "You can import this repository directly into your BotAJS project or use it as a reference.\n\n";

        // Bot info section
        $readme .= "## Bot Information\n\n";
        if ($bot['platform'] === 'telegram') {
            $readme .= "- **Bot Username:** @{$botUsername}\n";
        } elseif ($bot['platform'] === 'whatsapp') {
            $readme .= "- **Phone Number ID:** {$botUsername}\n";
        }
        $readme .= "- **Platform:** {$platform}\n";
        $readme .= "- **Language:** {$language}\n";
        $readme .= "- **Bot ID:** `{$bot['botId']}`\n";
        $readme .= "- **Created:** {$bot['created_at']}\n";
        $readme .= "- **Last Updated:** {$bot['updated_at']}\n\n";

        // Documentation links
        $readme .= "**Documentation:** https://jobianss-organization.gitbook.io/bota-documentation\n\n";

        // Commands section
        $readme .= "## Available Commands\n\n";
        $readme .= "This bot includes " . count($commands) . " command(s):\n\n";

        foreach ($commands as $command) {
            $cmdName = $command['command'];
            $readme .= "- **`{$cmdName}`**";
            if (!empty($command['aliases'])) {
                $aliases = is_array($command['aliases']) ? implode('`, `', $command['aliases']) : $command['aliases'];
                $readme .= " (aliases: `{$aliases}`)";
            }
            $readme .= "\n";
        }
        $readme .= "\n";

        // Project structure
        $readme .= "## Project Structure\n\n";
        $readme .= "```\n";
        $readme .= ".\n";
        $readme .= "├── commands/\n";
        foreach ($commands as $command) {
            $fileName = str_replace(['/', '*'], ['_', 'default'], $command['command']) . '.js';
            $readme .= "│   ├── {$fileName}\n";
        }
        $readme .= "├── bot.json          # Bot metadata\n";
        $readme .= "└── README.md         # This file\n";
        $readme .= "```\n\n";

        // How to import
        $readme .= "## How to Import to BotAJS\n\n";
        $readme .= "1. **Fork or clone this repository**\n";
        $readme .= "   ```bash\n";
        $readme .= "   git clone <your-repo-url>\n";
        $readme .= "   ```\n\n";
        $readme .= "2. **Go to BotAJS Dashboard**\n";
        $readme .= "   - Visit: https://app.botajs.top\n";
        $readme .= "   - Select your bot\n";
        $readme .= "   - Go to Git Integration\n\n";
        $readme .= "3. **Import from Git**\n";
        $readme .= "   - Paste your repository URL\n";
        $readme .= "   - Click \"Import\"\n";
        $readme .= "   - All commands will be synced automatically!\n\n";

        // Key examples
        $readme .= "## Key Code Examples\n\n";
        $readme .= "### Basic Reply\n";
        $readme .= "```javascript\n";
        $readme .= "await ctx.reply(`Hello \${ctx.from.first_name}! 👋`);\n";
        $readme .= "```\n\n";

        if ($bot['platform'] === 'telegram') {
            $readme .= "### Telegram Shortcuts\n";
            $readme .= "```javascript\n";
            $readme .= "// Using ctx.bot (TelegramBot instance)\n";
            $readme .= "await ctx.bot.sendMessage(ctx.chat.id, \"Quick message!\");\n";
            $readme .= "```\n\n";
            $readme .= "### Inline Keyboards\n";
            $readme .= "```javascript\n";
            $readme .= "await ctx.reply(\"Choose an option:\", {\n";
            $readme .= "  reply_markup: {\n";
            $readme .= "    inline_keyboard: [\n";
            $readme .= "      [{ text: \"Button 1\", callback_data: \"btn1\" }],\n";
            $readme .= "      [{ text: \"Visit Site\", url: \"https://botajs.top\" }]\n";
            $readme .= "    ]\n";
            $readme .= "  }\n";
            $readme .= "});\n";
            $readme .= "```\n\n";
        } elseif ($bot['platform'] === 'whatsapp') {
            $readme .= "### WhatsApp Buttons\n";
            $readme .= "```javascript\n";
            $readme .= "await ctx.reply(\"Choose an option:\", {\n";
            $readme .= "  buttons: [\n";
            $readme .= "    { id: \"btn1\", title: \"Option 1\" },\n";
            $readme .= "    { id: \"btn2\", title: \"Option 2\" }\n";
            $readme .= "  ]\n";
            $readme .= "});\n";
            $readme .= "```\n\n";
        }

        // Useful resources
        $readme .= "## Useful Resources\n\n";
        $readme .= "- **BotAJS Documentation:** https://jobianss-organization.gitbook.io/bota-documentation\n";
        $readme .= "- **Dashboard:** https://app.botajs.top\n";
        $readme .= "- **API Reference:** https://jobianss-organization.gitbook.io/bota-documentation/api-reference\n";
        if ($bot['platform'] === 'telegram') {
            $readme .= "- **Telegram Bot API:** https://core.telegram.org/bots/api\n";
        } elseif ($bot['platform'] === 'whatsapp') {
            $readme .= "- **WhatsApp Business API:** https://developers.facebook.com/docs/whatsapp\n";
        }
        $readme .= "\n";

        // Deploy section
        $readme .= "## Deploy\n\n";
        $readme .= "You can host your bot on:\n\n";
        $readme .= "- **BotAJS Cloud** (Recommended) – Automatic deployment from Git\n";
        $readme .= "- Railway / Render / Fly.io\n";
        $readme .= "- VPS with PM2 or Docker\n";
        $readme .= "- Heroku, DigitalOcean, AWS, etc.\n\n";

        // Contributing
        $readme .= "## Contributing\n\n";
        $readme .= "Feel free to fork this repository and submit pull requests!\n\n";

        // Footer
        $readme .= "---\n\n";
        $readme .= "Made with ❤️ using **BotAJS**\n\n";
        $readme .= "_This repository was automatically generated by BotAJS Git Integration_\n";

        file_put_contents($targetDir . '/README.md', $readme);
    }

    /**
     * Commit and push changes
     */
    private function commitAndPush($repoDir, $sshKeyPath, $message, $branch, $userEmail)
    {
        $this->runGitCommand(['add', '-A'], $repoDir, $sshKeyPath);

        $env = [
            'GIT_AUTHOR_NAME' => 'BotAJS Deploy',
            'GIT_AUTHOR_EMAIL' => $userEmail,
            'GIT_COMMITTER_NAME' => 'BotAJS Deploy',
            'GIT_COMMITTER_EMAIL' => $userEmail,
        ];
        $this->runGitCommand(['commit', '-m', $message], $repoDir, $sshKeyPath, $env);

        $this->runGitCommand(['push', 'origin', $branch], $repoDir, $sshKeyPath);
    }

    /**
     * Run git command with SSH
     */
    private function runGitCommand($args, $cwd = null, $sshKeyPath = null, $extraEnv = [])
    {
        $process = new Process(['git', ...$args], $cwd);

        $env = $_ENV;
        if ($sshKeyPath) {
            $env['GIT_SSH_COMMAND'] = "ssh -i {$sshKeyPath} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null";
        }
        $env = array_merge($env, $extraEnv);

        $process->setEnv($env);
        $process->setTimeout(300);
        $process->run();

        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }

        return $process->getOutput();
    }

    /**
     * Clean up directory
     */
    private function cleanupDirectory($dir)
    {
        if (!is_dir($dir)) return;

        $files = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
            \RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($files as $fileinfo) {
            $fileinfo->isDir() ? rmdir($fileinfo->getRealPath()) : unlink($fileinfo->getRealPath());
        }

        rmdir($dir);
    }
}