<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Router;
use App\Services\Router\MikroTikLive;

class RouterTestController extends Controller
{
    public function __invoke(Request $request)
    {
        // Keep original contract (so existing JS still works)
        $data = $request->validate([
            'host'      => 'required|string|max:255',
            'api_port'  => 'nullable|integer|min:1|max:65535',
            'username'  => 'required|string|max:190',
            'password'  => 'required|string|max:190',
            'use_tls'   => 'nullable|boolean',
            // OPTIONAL: if edit page sends this we’ll update that router row directly
            'router_id' => 'nullable|integer|exists:routers,id',
        ]);

        $payload = [
            'host'     => $data['host'],
            'username' => $data['username'],
            'password' => $data['password'],
            'api_port' => $data['api_port'] ?? 8728,
            'use_tls'  => (bool)($data['use_tls'] ?? false),
        ];

        try {
            // Call your service (this was already working before)
            $result = MikroTikLive::testRaw($payload);
        } catch (\Throwable $e) {
            // Never let an exception bubble to the browser – return a clean JSON error
            $result = [
                'ok'      => false,
                'message' => $e->getMessage(),
            ];
        }

        // If we know which router this is, update its metrics so /routers can show them
        $router = null;

        if (!empty($data['router_id'])) {
            $router = Router::find($data['router_id']);
        }

        // Fallback: try to locate router by host if router_id wasn’t sent
        if (!$router) {
            $router = Router::where('host', $data['host'])->first();
        }

        if ($router) {
            $this->updateRouterMetrics($router, $result, $payload);
        }

        // HTTP 200 on success, 422 if test failed
        $statusCode = (!empty($result['ok']) && $result['ok']) ? 200 : 422;

        return response()->json($result, $statusCode);
    }

    /**
     * Write MikroTik test results into the existing routers table columns.
     */
    protected function updateRouterMetrics(Router $router, array $result, array $payload): void
    {
        $isOk = !empty($result['ok']) && $result['ok'];

        // High-level status fields
        $router->last_status = $isOk ? 'online' : 'offline';
        $router->status      = $router->last_status; // keep enum in sync

        // Keep connection details in sync with what was tested
        $router->host     = $payload['host'];
        $router->api_port = $payload['api_port'];
        $router->port     = $payload['api_port']; // you also have `port` smallint
        $router->username = $payload['username'];
        $router->use_tls  = $payload['use_tls'];

        // If you want to store plain password here (you already have password_enc too)
        $router->password = $payload['password'] ?? $router->password;

        // Latency
        if (isset($result['latency_ms']) && is_numeric($result['latency_ms'])) {
            $router->last_latency_ms = (int)$result['latency_ms'];
        }

        // Identity / model / board name
        if (!empty($result['identity'])) {
            $router->last_identity = $result['identity'];
        }
        if (!empty($result['model'])) {
            $router->last_model = $result['model'];
            $router->model      = $result['model'];
        }
        if (!empty($result['board_name'])) {
            $router->board_name = $result['board_name'];
        }

        // CPU
        if (isset($result['cpu']) && $result['cpu'] !== null) {
            $cpu = $result['cpu'];
            // Last_cpu is stored as text, cpu_load as numeric
            $router->last_cpu = is_numeric($cpu) ? ($cpu . '%') : (string)$cpu;
            if (is_numeric($cpu)) {
                $router->cpu_load = (int)$cpu;
            }
        }

        // Memory (optional, only if MikroTikLive returns total/free)
        if (isset($result['total_memory']) && is_numeric($result['total_memory'])) {
            $router->total_memory = (int)$result['total_memory'];
        }
        if (isset($result['free_memory']) && is_numeric($result['free_memory'])) {
            $router->free_memory = (int)$result['free_memory'];
        }

        // HDD (optional)
        if (isset($result['total_hdd']) && is_numeric($result['total_hdd'])) {
            $router->total_hdd = (int)$result['total_hdd'];
        }
        if (isset($result['free_hdd']) && is_numeric($result['free_hdd'])) {
            $router->free_hdd = (int)$result['free_hdd'];
        }

        // Uptime
        if (!empty($result['uptime'])) {
            $router->last_uptime = $result['uptime'];  // e.g. "3d9h6m4s"
        }
        if (isset($result['uptime_seconds']) && is_numeric($result['uptime_seconds'])) {
            $router->uptime_seconds = (int)$result['uptime_seconds'];
        }

        // Timestamps
        $router->last_checked_at = now();
        $router->last_seen       = now();

        $router->save();
    }
}