<?php

namespace App\Jobs;

use App\Models\Router;
use App\Models\RouterInterface;
use App\Models\RouterStat;
use App\Services\Router\MikroTikClient;
use Carbon\Carbon;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class PollRouterJob implements ShouldQueue
{
    use Dispatchable, Queueable;

    public function __construct(public Router $router) {}

    public function handle(): void
    {
        $r = $this->router->fresh();
        try {
            $api = MikroTikClient::for($r);

            $res = $api->getResources();
            $board = $api->getBoardInfo();

            $r->fill([
                'model'          => $res['platform'] ?? $board['model'] ?? $r->model,
                'board_name'     => $board['board-name'] ?? $r->board_name,
                'serial'         => $board['serial-number'] ?? $r->serial,
                'cpu_load'       => isset($res['cpu-load']) ? (int)$res['cpu-load'] : null,
                'total_memory'   => isset($res['total-memory']) ? (int)$res['total-memory'] : null,
                'free_memory'    => isset($res['free-memory']) ? (int)$res['free-memory'] : null,
                'total_hdd'      => isset($res['total-hdd-space']) ? (int)$res['total-hdd-space'] : null,
                'free_hdd'       => isset($res['free-hdd-space']) ? (int)$res['free-hdd-space'] : null,
                'uptime_seconds' => self::parseUptime($res['uptime'] ?? null),
                'status'         => 'online',
                'last_seen'      => now(),
            ])->save();

            // interfaces snapshot
            foreach ($api->getInterfaces() as $iface) {
                $name = $iface['name'] ?? null; if(!$name) continue;
                RouterInterface::updateOrCreate(
                    ['router_id'=>$r->id,'name'=>$name],
                    [
                        'enabled' => ($iface['disabled'] ?? 'false') !== 'true',
                        'running' => ($iface['running'] ?? 'true') === 'true',
                    ]
                );
            }

            // point-in-time stat
            RouterStat::create([
                'router_id'    => $r->id,
                'cpu_load'     => (int)($res['cpu-load'] ?? 0),
                'rx_bps'       => null, // optional aggregate
                'tx_bps'       => null,
                'free_memory'  => (int)($res['free-memory'] ?? 0),
                'free_hdd'     => (int)($res['free-hdd-space'] ?? 0),
                'collected_at' => Carbon::now(),
            ]);

        } catch (Exception $e) {
            $r->update(['status'=>'offline']);
        }
    }

    protected static function parseUptime(?string $uptime): ?int
    {
        if(!$uptime) return null;
        // RouterOS uptime like "1w2d03:04:05" or "03:04:05"
        $weeks = $days = 0; $h=0;$m=0;$s=0;
        if(preg_match('/(?:(\d+)w)?(?:(\d+)d)?(\d{1,2}):(\d{2}):(\d{2})/', $uptime, $M)){
            $weeks=(int)($M[1]??0); $days=(int)($M[2]??0); $h=(int)$M[3]; $m=(int)$M[4]; $s=(int)$M[5];
        }
        return ($weeks*7*86400)+($days*86400)+($h*3600)+($m*60)+$s;
    }
}
