<?php
require_once __DIR__ . '/RouterosAPI.php';
require_once __DIR__ . '/../includes/db.php';

class MikroTik {
    private $api;
    private $cfg;
    public  $lastError = '';
    public  $connected = false;

    public function __construct($branchId = null) {
    $db = db();
    $this->cfg = [];
    
    // Jika ada branchId, load config MikroTik dari cabang tersebut
    if ($branchId) {
        try {
            $stmt = $db->prepare("SELECT setting_key, setting_value FROM mikrotik_config WHERE branch_id = ?");
            $stmt->execute([$branchId]);
            while ($row = $stmt->fetch()) {
                $this->cfg[$row['setting_key']] = $row['setting_value'];
            }
        } catch (Exception $e) {
            // Fallback ke config pusat
        }
    }
    
    // Jika config cabang kosong, load dari config pusat
    if (empty($this->cfg)) {
        try {
            $stmt = $db->query("SELECT setting_key, setting_value FROM mikrotik_config WHERE branch_id IS NULL OR branch_id = 0");
            while ($row = $stmt->fetch()) {
                $this->cfg[$row['setting_key']] = $row['setting_value'];
            }
        } catch (Exception $e) {
            $this->cfg = require __DIR__ . '/../config/mikrotik.php';
        }
    }
    
    // Default values
    $this->cfg['host']    = $this->cfg['host'] ?? '	id1.sisbro.id';
    $this->cfg['user']    = $this->cfg['user'] ?? 'kuci';
    $this->cfg['pass']    = $this->cfg['pass'] ?? 'kuci';
    $this->cfg['port']    = $this->cfg['port'] ?? 49212;
    $this->cfg['timeout'] = min(3, (int)($this->cfg['timeout'] ?? 3));
    
    $this->api = new RouterosAPI();
}

    /**
     * Connect dengan timeout protection
     */
    public function connect($timeout = null) {
        if ($this->connected) return true;
        
        $timeout = $timeout ?? (int)$this->cfg['timeout'];
        $timeout = min(3, max(1, $timeout));
        
        set_time_limit(5);
        
        try {
            $result = $this->api->connect(
                $this->cfg['host'],
                $this->cfg['user'],
                $this->cfg['pass'],
                (int)$this->cfg['port'],
                $timeout
            );
            
            if (!$result) {
                $this->lastError = $this->api->error ?: 'Connection failed';
                return false;
            }
            
            $this->connected = true;
            return true;
            
        } catch (Exception $e) {
            $this->lastError = $e->getMessage();
            return false;
        }
    }

    public function disconnect() {
        if ($this->connected) {
            $this->api->disconnect();
            $this->connected = false;
        }
    }

    /**
     * Helper: Pastikan terhubung, return false jika gagal
     */
    private function ensureConnected($timeout = 3) {
        if (!$this->connect($timeout)) {
            return false;
        }
        return true;
    }

    /**
     * Helper: Cek apakah command terakhir sukses (tidak ada error)
     */
    private function isSuccess() {
        return empty($this->api->error);
    }

    public function testConnection() {
        if (!$this->connect(2)) {
            return ['success' => false, 'error' => $this->lastError];
        }
        
        try {
            $identity = $this->api->comm('/system/identity/print');
            $resources = $this->api->comm('/system/resource/print');
            $this->disconnect();
            
            return [
                'success'  => true,
                'identity' => $identity[0]['name'] ?? 'Unknown',
                'version'  => $resources[0]['version'] ?? 'Unknown',
                'uptime'   => $resources[0]['uptime'] ?? 'Unknown',
                'board'    => $resources[0]['board-name'] ?? 'Unknown',
                'cpu'      => $resources[0]['cpu-load'] ?? '0'
            ];
        } catch (Exception $e) {
            $this->disconnect();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public function getPPPoEStatus() {
        if (!$this->ensureConnected(3)) {
            return ['success' => false, 'error' => $this->lastError];
        }
        
        try {
            $secrets = $this->api->comm('/ppp/secret/print');
            $actives = $this->api->comm('/ppp/active/print');
            $this->disconnect();
            
            $activeMap = [];
            foreach ($actives as $active) {
                $activeMap[$active['name']] = $active;
            }
            
            $online = $offline = [];
            foreach ($secrets as $secret) {
                $name = $secret['name'];
                $isDisabled = isset($secret['disabled']) && $secret['disabled'] === 'true';
                $isActive = isset($activeMap[$name]);
                
                $data = [
                    'name' => $name,
                    'profile' => $secret['profile'] ?? 'default',
                    'service' => $secret['service'] ?? 'any',
                    'disabled' => $isDisabled,
                    'comment' => $secret['comment'] ?? '',
                ];
                
                if ($isActive) {
                    $data['status'] = 'online';
                    $data['address'] = $activeMap[$name]['caller-id'] ?? '-';
                    $data['uptime'] = $activeMap[$name]['uptime'] ?? '-';
                    $online[] = $data;
                } else {
                    $data['status'] = 'offline';
                    $offline[] = $data;
                }
            }
            
            return [
                'success' => true,
                'total_secrets' => count($secrets),
                'total_online' => count($online),
                'total_offline' => count($offline),
                'total_disabled' => count(array_filter($secrets, fn($s) => isset($s['disabled']) && $s['disabled'] === 'true')),
                'online' => $online,
                'offline' => $offline,
            ];
        } catch (Exception $e) {
            $this->disconnect();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    /**
     * Mengambil daftar PPP Profiles dari MikroTik
     */
    public function getPPPProfiles() {
        if (!$this->ensureConnected(3)) return [];
        
        try {
            // Gunakan comm() BUKAN write()+read() agar semua profiles terbaca
            $list = $this->api->comm('/ppp/profile/print');
            $this->disconnect();
            return is_array($list) ? $list : [];
        } catch (\Throwable $e) {
            $this->lastError = $e->getMessage();
            $this->disconnect();
            return [];
        }
    }

    public function getAllSecrets() {
        if (!$this->ensureConnected(3)) return [];
        $list = $this->api->comm('/ppp/secret/print');
        $this->disconnect();
        return $list ?: [];
    }

    public function getActiveConnections() {
        if (!$this->ensureConnected(3)) return [];
        $list = $this->api->comm('/ppp/active/print');
        $this->disconnect();
        return $list ?: [];
    }

    public function getSystemInfo() {
        if (!$this->ensureConnected(3)) return null;
        $info = $this->api->comm('/system/resource/print');
        $identity = $this->api->comm('/system/identity/print');
        $this->disconnect();
        
        return [
            'identity' => $identity[0]['name'] ?? 'Unknown',
            'version'  => $info[0]['version'] ?? 'Unknown',
            'board'    => $info[0]['board-name'] ?? 'Unknown',
            'uptime'   => $info[0]['uptime'] ?? 'Unknown',
            'cpu_load' => $info[0]['cpu-load'] ?? '0',
        ];
    }

    public function addSecret($username, $password, $profile, $service = 'pppoe', $comment = '') {
        if (!$this->ensureConnected(5)) return ['success' => false, 'error' => $this->lastError];
        
        $params = [
            'name' => $username,
            'password' => $password,
            'profile' => $profile,
            'service' => $service,
            'disabled' => 'no'
        ];
        if ($comment) $params['comment'] = $comment;
        
        $this->api->comm('/ppp/secret/add', $params);
        $success = $this->isSuccess();
        $error = $this->api->error;
        $this->disconnect();
        
        return ['success' => $success, 'error' => $error];
    }

    public function enableSecret($username) {
        if (!$this->ensureConnected(5)) return ['success' => false, 'error' => $this->lastError];
        
        $secrets = $this->api->comm('/ppp/secret/print', ['?name' => $username]);
        if (empty($secrets)) {
            $this->disconnect();
            return ['success' => false, 'error' => 'User not found'];
        }
        
        $this->api->comm('/ppp/secret/set', ['.id' => $secrets[0]['.id'], 'disabled' => 'no']);
        $success = $this->isSuccess();
        $error = $this->api->error;
        $this->disconnect();
        
        return ['success' => $success, 'error' => $error];
    }

    public function disableSecret($username) {
        if (!$this->ensureConnected(5)) return ['success' => false, 'error' => $this->lastError];
        
        $secrets = $this->api->comm('/ppp/secret/print', ['?name' => $username]);
        if (empty($secrets)) {
            $this->disconnect();
            return ['success' => false, 'error' => 'User not found'];
        }
        
        $this->api->comm('/ppp/secret/set', ['.id' => $secrets[0]['.id'], 'disabled' => 'yes']);
        $success = $this->isSuccess();
        $error = $this->api->error;
        $this->disconnect();
        
        return ['success' => $success, 'error' => $error];
    }

    public function removeSecret($username) {
        if (!$this->ensureConnected(5)) return ['success' => false, 'error' => $this->lastError];
        
        $secrets = $this->api->comm('/ppp/secret/print', ['?name' => $username]);
        if (empty($secrets)) {
            $this->disconnect();
            return ['success' => true, 'error' => ''];
        }
        
        $this->api->comm('/ppp/secret/remove', ['.id' => $secrets[0]['.id']]);
        $success = $this->isSuccess();
        $error = $this->api->error;
        $this->disconnect();
        
        return ['success' => $success, 'error' => $error];
    }

    public function killActiveConnection($username) {
        if (!$this->ensureConnected(5)) return ['killed' => 0, 'error' => $this->lastError];
        
        $actives = $this->api->comm('/ppp/active/print', ['?name' => $username]);
        $killed = 0;
        $lastError = '';
        
        foreach ($actives as $active) {
            $this->api->comm('/ppp/active/remove', ['.id' => $active['.id']]);
            if ($this->isSuccess()) {
                $killed++;
            } else {
                $lastError = $this->api->error;
            }
        }
        
        $this->disconnect();
        return ['killed' => $killed, 'error' => $lastError];
    }

    /**
     * OPTIMIZED: Hanya 1 koneksi untuk kill + disable
     */
    public function suspendCustomer($username) {
        if (!$this->ensureConnected(5)) return ['success' => false, 'error' => $this->lastError];
        
        $lastError = '';
        
        // 1. Kill active connection
        $actives = $this->api->comm('/ppp/active/print', ['?name' => $username]);
        foreach ($actives as $active) {
            $this->api->comm('/ppp/active/remove', ['.id' => $active['.id']]);
            if (!$this->isSuccess()) $lastError = $this->api->error;
        }
        
        // 2. Disable secret
        $secrets = $this->api->comm('/ppp/secret/print', ['?name' => $username]);
        $success = true;
        if (!empty($secrets)) {
            $this->api->comm('/ppp/secret/set', ['.id' => $secrets[0]['.id'], 'disabled' => 'yes']);
            if (!$this->isSuccess()) {
                $success = false;
                $lastError = $this->api->error;
            }
        } else {
            $success = false;
            $lastError = 'User not found';
        }
        
        $this->disconnect();
        return ['success' => $success, 'error' => $lastError];
    }

    /**
     * OPTIMIZED: Hanya 1 koneksi untuk enable
     */
    public function restoreCustomer($username) {
        if (!$this->ensureConnected(5)) return ['success' => false, 'error' => $this->lastError];
        
        $secrets = $this->api->comm('/ppp/secret/print', ['?name' => $username]);
        $success = false;
        $error = '';
        
        if (!empty($secrets)) {
            $this->api->comm('/ppp/secret/set', ['.id' => $secrets[0]['.id'], 'disabled' => 'no']);
            $success = $this->isSuccess();
            $error = $this->api->error;
        } else {
            $error = 'User not found';
        }
        
        $this->disconnect();
        return ['success' => $success, 'error' => $error];
    }

    public function kickUser($username) {
        return $this->killActiveConnection($username);
    }
}