<?php

declare(strict_types=1);

namespace ServerManager\Controllers;

use ServerManager\Core\App;
use ServerManager\Core\Session;
use ServerManager\Models\Server;
use ServerManager\Services\SSHService;
use ServerManager\Services\AuditService;
use ServerManager\Models\CommandHistory;

class TerminalController
{
    private \ServerManager\Core\View $view;
    private Server $serverModel;
    private AuditService $auditService;

    public function __construct()
    {
        $this->view = App::getInstance()->getView();
        $this->serverModel = new Server();
        $this->auditService = new AuditService();
    }

    public function index(int $id): void
    {
        $server = $this->serverModel->findById($id);

        if (!$server) {
            $this->view->error(404);
        }

        $userId = (int) Session::get('user_id');
        if (!$this->serverModel->canView($id, $userId)) {
            $this->view->error(404);
        }

        $commandHistory = new CommandHistory();
        $history = $commandHistory->getByServer($id, 50);

        $this->view->display('terminal.index', [
            'title' => 'Terminal - ' . $server['name'] . ' - ServerManager',
            'server' => $server,
            'commandHistory' => $history,
        ]);
    }

    public function execute(int $id): void
    {
        $server = $this->serverModel->findById($id);

        if (!$server) {
            $this->view->json(['success' => false, 'message' => 'Server not found'], 404);
        }

        $userId = (int) Session::get('user_id');
        if (!$this->serverModel->canView($id, $userId)) {
            $this->view->json(['success' => false, 'message' => 'Forbidden'], 403);
        }

        $command = $_POST['command'] ?? '';

        if (empty($command)) {
            $this->view->json(['success' => false, 'message' => 'Command is required']);
        }

        $blockedCommands = ['rm -rf /', 'mkfs', 'dd if=', ':(){ :|:& };:'];
        foreach ($blockedCommands as $blocked) {
            if (stripos($command, $blocked) !== false) {
                $this->auditService->log('blocked_command', 'server', $id, [
                    'command' => $command,
                    'reason' => 'Blocked dangerous command pattern',
                ]);

                $this->view->json([
                    'success' => false,
                    'message' => 'This command has been blocked for safety reasons.',
                ]);
            }
        }

        try {
            $ssh = new SSHService();
            if (!$ssh->connect($server)) {
                throw new \RuntimeException('Could not establish SSH connection');
            }
            $this->auditService->logCredentialAccess($id, 'Terminal command execution');

            $result = $ssh->exec($command);
            $ssh->disconnect();

            $commandHistory = new CommandHistory();
            $commandHistory->log(
                $id,
                Session::get('user_id'),
                $command,
                $result['output'],
                $result['exit_status'] ?? 0
            );

            $this->auditService->logServerAction($id, 'command_executed', $command);

            $this->view->json([
                'success' => true,
                'output' => $result['output'],
                'exit_status' => $result['exit_status'],
                'stderr' => $result['stderr'],
            ]);
        } catch (\Throwable $e) {
            $this->view->json([
                'success' => false,
                'message' => 'Failed to execute command: ' . $e->getMessage(),
            ]);
        }
    }

    public function history(int $id): void
    {
        $commandHistory = new CommandHistory();
        $history = $commandHistory->getByServer($id, 100);

        $this->view->json([
            'success' => true,
            'data' => $history,
        ]);
    }

    public function clearHistory(int $id): void
    {
        $commandHistory = new CommandHistory();
        $commandHistory->clearHistory($id);

        $this->auditService->log('command_history_cleared', 'server', $id);

        $this->view->json([
            'success' => true,
            'message' => 'Command history cleared.',
        ]);
    }
}
