<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class ThreeCXWebSocketManager extends Command
{
    protected $signature = 'threecx:ws {action : start|stop|status|restart}';
    protected $description = 'Manage 3CX WebSocket listener runtime (start/stop/status/restart)';

    private $pidFile = 'threecx_ws_listener.pid';

    public function handle()
    {
        $action = $this->argument('action');

        switch ($action) {
            case 'start':
                $this->startListener();
                break;
            case 'stop':
                $this->stopListener();
                break;
            case 'status':
                $this->statusListener();
                break;
            case 'restart':
                $this->stopListener();
                sleep(2);
                $this->startListener();
                break;
            default:
                $this->error("Invalid action: {$action}. Use: start|stop|status|restart");
        }
    }

    protected function startListener()
    {
        $pidPath = storage_path("app/{$this->pidFile}");

        if (file_exists($pidPath)) {
            $pid = (int) file_get_contents($pidPath);
            if ($this->isProcessRunning($pid)) {
                $this->error("Listener already running with PID: {$pid}");
                return;
            } else {
                // Stale PID file
                unlink($pidPath);
                $this->warn("Removed stale PID file");
            }
        }

        $this->info("🚀 Starting 3CX WebSocket listener...");

        // Create logs directory if it doesn't exist
        if (!File::exists(storage_path('logs'))) {
            File::makeDirectory(storage_path('logs'), 0755, true);
        }

        // Run in background & redirect output to log file
        $logFile = storage_path('logs/threecx_ws_listener.log');
        $command = sprintf(
            'php %s threecx:ws-run >> %s 2>&1 & echo $!',
            base_path('artisan'),
            $logFile
        );

        // For Windows compatibility
        if (PHP_OS_FAMILY === 'Windows') {
            $command = sprintf(
                'start /B php %s threecx:ws-run > %s 2>&1',
                base_path('artisan'),
                $logFile
            );
        }

        $pid = shell_exec($command);

        if ($pid && PHP_OS_FAMILY !== 'Windows') {
            file_put_contents($pidPath, trim($pid));
            $this->info("✅ Listener started with PID: " . trim($pid));
            $this->info("📋 Logs: {$logFile}");
        } else {
            $this->info("✅ Listener started (Windows mode)");
            $this->info("📋 Logs: {$logFile}");
        }
    }

    protected function stopListener()
    {
        $pidPath = storage_path("app/{$this->pidFile}");

        if (!file_exists($pidPath)) {
            $this->warn('No PID file found. Trying to stop any running listener...');
            
            // Try to kill by process name (Linux/Mac)
            if (PHP_OS_FAMILY !== 'Windows') {
                shell_exec("pkill -f 'threecx:ws-run'");
                $this->info("Attempted to stop any running threecx:ws-run processes");
            }
            return;
        }

        $pid = (int) file_get_contents($pidPath);
        
        if (PHP_OS_FAMILY === 'Windows') {
            // Windows process termination
            shell_exec("taskkill /F /PID {$pid} 2>nul");
        } else {
            // Unix/Linux process termination
            if (posix_kill($pid, SIGTERM)) {
                $this->info("✅ Listener stopped (PID: {$pid})");
            } else {
                $this->warn("Failed to stop listener. PID may not exist. Trying force kill...");
                posix_kill($pid, SIGKILL);
            }
        }

        unlink($pidPath);
        $this->info("🗑️ PID file removed");
    }

    protected function statusListener()
    {
        $pidPath = storage_path("app/{$this->pidFile}");

        if (!file_exists($pidPath)) {
            $this->info('📴 Listener not running (no PID file)');
            return;
        }

        $pid = (int) file_get_contents($pidPath);
        
        if ($this->isProcessRunning($pid)) {
            $this->info("✅ Listener is running (PID: {$pid})");
            
            // Show recent log entries
            $logFile = storage_path('logs/threecx_ws_listener.log');
            if (file_exists($logFile)) {
                $this->info("📋 Recent log entries:");
                $this->line(shell_exec("tail -5 {$logFile}"));
            }
        } else {
            $this->warn("❌ PID file exists but process not running (stale PID: {$pid})");
            unlink($pidPath);
            $this->info("🗑️ Removed stale PID file");
        }
    }

    protected function isProcessRunning($pid)
    {
        if (PHP_OS_FAMILY === 'Windows') {
            $output = shell_exec("tasklist /FI \"PID eq {$pid}\" 2>nul");
            return strpos($output, (string)$pid) !== false;
        } else {
            return posix_kill($pid, 0);
        }
    }
}
