<?php

namespace App\Services\Router;

use App\Models\Router;
use RouterOS\Client;
use RouterOS\Query;

class MikroTikHotspotService
{
    protected static function client(Router $router): ?Client
    {
        // Adjust if your helper is different (connect() / make() / etc.)
        return MikroTikLive::client($router);
    }

    /* =======================
     *  PROFILES
     * ======================= */

    public static function listProfiles(Router $router): array
    {
        $client = static::client($router);
        if (!$client) return [];

        $rows = $client->query(new Query('/ip/hotspot/user/profile/print'))->read();

        $out = [];
        foreach ($rows as $row) {
            $out[] = [
                'id'                => $row['.id'] ?? null,
                'name'              => $row['name'] ?? '',
                'rate_limit'        => $row['rate-limit'] ?? null,
                'shared_users'      => $row['shared-users'] ?? null,
                'idle_timeout'      => $row['idle-timeout'] ?? null,
                'keepalive_timeout' => $row['keepalive-timeout'] ?? null,
                'parent_queue'      => $row['parent-queue'] ?? null,
                'comment'           => $row['comment'] ?? null,
            ];
        }
        return $out;
    }

    public static function createProfile(Router $router, array $data): void
    {
        $client = static::client($router);
        if (!$client) return;

        $q = (new Query('/ip/hotspot/user/profile/add'))
            ->equal('name', $data['name']);

        if (!empty($data['rate_limit'])) {
            $q->equal('rate-limit', $data['rate_limit']);
        }
        if (!empty($data['shared_users'])) {
            $q->equal('shared-users', $data['shared_users']);
        }
        if (!empty($data['idle_timeout'])) {
            $q->equal('idle-timeout', $data['idle_timeout']);
        }
        if (!empty($data['keepalive_timeout'])) {
            $q->equal('keepalive-timeout', $data['keepalive_timeout']);
        }
        if (!empty($data['parent_queue'])) {
            $q->equal('parent-queue', $data['parent_queue']);
        }
        if (!empty($data['comment'])) {
            $q->equal('comment', $data['comment']);
        }

        $client->query($q)->read();
    }

    public static function updateProfile(Router $router, string $id, array $data): void
    {
        $client = static::client($router);
        if (!$client) return;

        $q = (new Query('/ip/hotspot/user/profile/set'))
            ->equal('.id', $id);

        foreach ([
            'name'              => 'name',
            'rate-limit'        => 'rate_limit',
            'shared-users'      => 'shared_users',
            'idle-timeout'      => 'idle_timeout',
            'keepalive-timeout' => 'keepalive_timeout',
            'parent-queue'      => 'parent_queue',
            'comment'           => 'comment',
        ] as $rosKey => $inputKey) {
            if (array_key_exists($inputKey, $data) && $data[$inputKey] !== null && $data[$inputKey] !== '') {
                $q->equal($rosKey, $data[$inputKey]);
            }
        }

        $client->query($q)->read();
    }

    public static function deleteProfile(Router $router, string $id): void
    {
        $client = static::client($router);
        if (!$client) return;

        $q = (new Query('/ip/hotspot/user/profile/remove'))
            ->equal('.id', $id);

        $client->query($q)->read();
    }

    /* =======================
     *  USERS (vouchers)
     * ======================= */

    public static function listUsers(Router $router): array
    {
        $client = static::client($router);
        if (!$client) return [];

        $rows = $client->query(new Query('/ip/hotspot/user/print'))->read();

        $out = [];
        foreach ($rows as $row) {
            $out[] = [
                'id'         => $row['.id'] ?? null,
                'name'       => $row['name'] ?? '',
                'password'   => $row['password'] ?? '',
                'profile'    => $row['profile'] ?? '',
                'uptime'     => $row['uptime'] ?? '',
                'limit_uptime' => $row['limit-uptime'] ?? '',
                'comment'    => $row['comment'] ?? '',
                'disabled'   => $row['disabled'] ?? 'false',
            ];
        }
        return $out;
    }

    public static function createUser(Router $router, array $data): void
    {
        $client = static::client($router);
        if (!$client) return;

        $q = (new Query('/ip/hotspot/user/add'))
            ->equal('name', $data['name'])
            ->equal('password', $data['password'])
            ->equal('profile', $data['profile']);

        if (!empty($data['limit_uptime'])) {
            $q->equal('limit-uptime', $data['limit_uptime']);
        }
        if (!empty($data['comment'])) {
            $q->equal('comment', $data['comment']);
        }

        $client->query($q)->read();
    }

    public static function updateUser(Router $router, string $id, array $data): void
    {
        $client = static::client($router);
        if (!$client) return;

        $q = (new Query('/ip/hotspot/user/set'))
            ->equal('.id', $id);

        foreach ([
            'name'         => 'name',
            'password'     => 'password',
            'profile'      => 'profile',
            'limit-uptime' => 'limit_uptime',
            'comment'      => 'comment',
            'disabled'     => 'disabled',
        ] as $rosKey => $inputKey) {
            if (array_key_exists($inputKey, $data) && $data[$inputKey] !== null && $data[$inputKey] !== '') {
                $q->equal($rosKey, $data[$inputKey]);
            }
        }

        $client->query($q)->read();
    }

    public static function deleteUser(Router $router, string $id): void
    {
        $client = static::client($router);
        if (!$client) return;

        $q = (new Query('/ip/hotspot/user/remove'))
            ->equal('.id', $id);

        $client->query($q)->read();
    }

    /* =======================
     *  ACTIVE SESSIONS
     * ======================= */



    /**
     * List active hotspot sessions from MikroTik.
     */
    
    /**
     * Disconnect a single active session by its internal .id.
     */
    public static function disconnectSession(Router $router, string $id): void
    {
        $client = self::client($router);

        $query = (new Query('/ip/hotspot/active/remove'))->equal('.id', $id);
        $client->query($query)->read();
    }


    /**
     * Disconnect all active sessions.
     */
    public static function disconnectAll(Router $router): void
    {
        $client = self::client($router);
        $rows   = $client->query(new Query('/ip/hotspot/active/print'))->read();

        foreach ($rows as $row) {
            if (! isset($row['.id'])) continue;
            $q = (new Query('/ip/hotspot/active/remove'))->equal('.id', $row['.id']);
            $client->query($q)->read();
        }
    }

    /**
     * Disconnect by MAC address (all sessions using that MAC).
     */
    public static function disconnectByMac(Router $router, string $mac): void
    {
        $client = self::client($router);

        $rows = $client->query(
            (new Query('/ip/hotspot/active/print'))->where('mac-address', $mac)
        )->read();

        foreach ($rows as $row) {
            if (! isset($row['.id'])) continue;
            $q = (new Query('/ip/hotspot/active/remove'))->equal('.id', $row['.id']);
            $client->query($q)->read();
        }
    }


    /**
     * Disable hotspot user (by username / profile user).
     */
    public static function disableUser(Router $router, string $username): void
    {
        $client = self::client($router);

        // find the user row first
        $listQuery = (new Query('/ip/hotspot/user/print'))->where('name', $username);
        $rows      = $client->query($listQuery)->read();

        if (empty($rows)) {
            return;
        }

        $id = $rows[0]['.id'] ?? null;

        if ($id) {
            $setQuery = (new Query('/ip/hotspot/user/set'))
                ->equal('.id', $id)
                ->equal('disabled', 'yes');

            $client->query($setQuery)->read();
        }
    }



















    public static function listActive(Router $router): array
    {
        $client = static::client($router);
        if (!$client) return [];

        $rows = $client->query(new Query('/ip/hotspot/active/print'))->read();

        $out = [];
        foreach ($rows as $row) {
            $out[] = [
                'id'        => $row['.id'] ?? null,
                'user'      => $row['user'] ?? '',
                'address'   => $row['address'] ?? '',
                'mac'       => $row['mac-address'] ?? '',
                'uptime'    => $row['uptime'] ?? '',
                'bytes_in'  => $row['bytes-in'] ?? '',
                'bytes_out' => $row['bytes-out'] ?? '',
                'login_by'  => $row['login-by'] ?? '',
            ];
        }
        return $out;
    }

    /* =======================
     *  LOGS (simple)
     * ======================= */

    public static function listHotspotLogs(Router $router, int $limit = 100): array
    {
        $client = static::client($router);
        if (!$client) return [];

        $q = (new Query('/log/print'))->equal('where', 'topics~"hotspot"');
        $rows = $client->query($q)->read();

        return array_slice($rows, -$limit);
    }







 /* ===================== LOGS ===================== */

    /**
     * System hotspot log: /log print where topics contains "hotspot"
     */
    public static function logs(Router $router, int $limit = 200, ?string $search = null): array
    {
        $client  = self::connect($router);
        $request = new Request('/log/print');
        $request->setArgument('?topics', 'hotspot');

        if ($search) {
            $request->setArgument('?message', $search);
        }

        $resp = $client->sendSync($request);
        $rows = self::collect($resp);

        // Normalize & sort latest first (MikroTik returns latest last)
        $rows = array_reverse($rows);

        if ($limit > 0) {
            $rows = array_slice($rows, 0, $limit);
        }

        return $rows;
    }

    /**
     * User log – still based on /log, but filtered by username in message
     */
    public static function userLogs(Router $router, int $limit = 200, ?string $user = null): array
    {
        $client  = self::connect($router);
        $request = new Request('/log/print');
        $request->setArgument('?topics', 'hotspot');

        if ($user) {
            $request->setArgument('?message', $user);
        }

        $resp = $client->sendSync($request);
        $rows = self::collect($resp);

        $rows = array_reverse($rows);

        if ($limit > 0) {
            $rows = array_slice($rows, 0, $limit);
        }

        return $rows;
    }

    public static function generateVoucher(Router $router, Plan $plan, string $phone): ?string
{
    $client = MikroTikClientFactory::fromRouter($router); // whatever you already use
    $client->connect();

    // simple voucher code
    $code = strtoupper('BB'.substr(md5(uniqid($phone, true)), 0, 8));

    $comment = 'BlueBando '.$plan->name.' | '.$phone;

    $client->write('/ip/hotspot/user/add', [
        'name'          => $code,
        'password'      => $code,
        'profile'       => $plan->profile,
        'comment'       => $comment,
        // You can also map validity_hours to 'limit-uptime' if you prefer voucher-level limit
        // 'limit-uptime'  => $plan->validity_hours.'h',
    ])->read();

    $client->disconnect();

    return $code;
}

public static function createVoucherFromPlan(\App\Models\Router $router, \App\Models\Plan $plan, string $phone): array
{
    // Generate voucher code
    $code = (string) random_int(10000000, 99999999);

    // Convert validity_hours → limit-uptime string (e.g. "3h0m0s")
    $hours = (int) ($plan->validity_hours ?? 24);
    $limitUptime = $hours . 'h0m0s';

    $client = MikroTikLive::connect($router); // you already have this helper

    // Create user in MikroTik
    $client->query('/ip/hotspot/user/add', [
        'name'         => $code,
        'password'     => $code,
        'profile'      => $plan->profile,
        'limit-uptime' => $limitUptime,
        'comment'      => 'BlueBando auto voucher for ' . $phone,
    ])->read();

    // Calculate expiry (simple: now + validity_hours)
    $expiresAt = now()->addHours($hours);

    return [
        'code'       => $code,
        'expires_at' => $expiresAt,
    ];
}


}
