<?php

namespace App\Controllers;

use App\Models\Server;
use App\Models\Client;
use App\Utils\View;
use App\Services\ASNService;

class ServerController
{
    public function index()
    {
        $serverModel = new Server();
        $sql = "SELECT s.*, c.name as client_name FROM servers s JOIN clients c ON s.client_id = c.id";
        $stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
        $stmt->execute();
        $servers = $stmt->fetchAll();

        View::render('layouts.admin', [
            'title' => 'Gerenciar Servidores',
            'content' => __DIR__ . '/../../resources/views/admin/servers/index.php',
            'servers' => $servers
        ]);
    }

    public function create()
    {
        $clientModel = new Client();
        $clients = $clientModel->where('status', 'active');

        View::render('layouts.admin', [
            'title' => 'Novo Servidor',
            'content' => __DIR__ . '/../../resources/views/admin/servers/form.php',
            'clients' => $clients
        ]);
    }

    public function store()
    {
        $clientModel = new Client();
        $client = $clientModel->find($_POST['client_id']);

        if (!$client) {
            View::redirect('/admin/servers');
            return;
        }

        // Validate IP vs ASN
        if (!ASNService::validateIP($_POST['ip_v4'], $client['asn'])) {
            $_SESSION['flash_error'] = "O IP informado não pertence ao ASN do cliente ({$client['asn']}).";
            // Keep input data
            $_SESSION['old_input'] = $_POST;
            View::redirect('/admin/servers/create');
            return;
        }

        $data = [
            'client_id' => $_POST['client_id'],
            'name' => $_POST['name'],
            'ip_v4' => $_POST['ip_v4'],
            'ip_v6' => $_POST['ip_v6'] ?? null,
            'serial_key' => bin2hex(random_bytes(16)),
            'status' => 'active'
        ];

        $sql = "INSERT INTO servers (client_id, name, ip_v4, ip_v6, serial_key, status) VALUES (:client_id, :name, :ip_v4, :ip_v6, :serial_key, :status)";
        $stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
        $stmt->execute($data);

        // Pangolin Integration - Sincroniza o cliente após adicionar servidor
        try {
            $pangolinService = new \App\Services\PangolinService();
            if ($pangolinService->isEnabled() && $client['status'] === 'active') {
                $pangolinService->syncClient($_POST['client_id'], 'add');
            }
        } catch (\Exception $e) {
            error_log("Pangolin Sync Error (Server Create): " . $e->getMessage());
        }

        View::redirect('/admin/servers');
    }

    public function edit($id)
    {
        $serverModel = new Server();
        $server = $serverModel->find($id);

        if (!$server) {
            View::redirect('/admin/servers');
        }

        $clientModel = new Client();
        $clients = $clientModel->where('status', 'active');

        View::render('layouts.admin', [
            'title' => 'Editar Servidor',
            'content' => __DIR__ . '/../../resources/views/admin/servers/form.php',
            'server' => $server,
            'clients' => $clients
        ]);
    }

    public function update($id)
    {
        $serverModel = new Server();
        $server = $serverModel->find($id);

        if (!$server) {
            View::redirect('/admin/servers');
            return;
        }

        // If IP changed, validate again
        if ($_POST['ip_v4'] !== $server['ip_v4']) {
            $clientModel = new Client();
            $client = $clientModel->find($_POST['client_id']);

            if (!ASNService::validateIP($_POST['ip_v4'], $client['asn'])) {
                $_SESSION['flash_error'] = "O IP informado não pertence ao ASN do cliente ({$client['asn']}).";
                View::redirect('/admin/servers/edit/' . $id);
                return;
            }
        }

        // Guardar IPs antigos para remover do Pangolin se mudaram
        $oldIpV4 = $server['ip_v4'];
        $oldIpV6 = $server['ip_v6'];
        $oldClientId = $server['client_id'];
        $oldStatus = $server['status'];

        $data = [
            'id' => $id,
            'client_id' => $_POST['client_id'],
            'name' => $_POST['name'],
            'ip_v4' => $_POST['ip_v4'],
            'ip_v6' => $_POST['ip_v6'] ?? null,
            'status' => $_POST['status']
        ];

        $sql = "UPDATE servers SET client_id=:client_id, name=:name, ip_v4=:ip_v4, ip_v6=:ip_v6, status=:status WHERE id=:id";
        $stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
        $stmt->execute($data);

        // Pangolin Integration - Sincroniza se IP, status ou cliente mudou
        try {
            $pangolinService = new \App\Services\PangolinService();
            if ($pangolinService->isEnabled()) {
                $clientModel = new Client();
                $client = $clientModel->find($_POST['client_id']);

                // Coletar IPs que mudaram para remover
                $ipsToRemove = [];
                if ($oldIpV4 !== $_POST['ip_v4']) {
                    $ipsToRemove[] = $oldIpV4;
                }
                if ($oldIpV6 !== ($_POST['ip_v6'] ?? null)) {
                    $ipsToRemove[] = $oldIpV6;
                }

                // Se o servidor era ativo e agora está inativo, remove os IPs
                if ($oldStatus === 'active' && $_POST['status'] === 'inactive') {
                    $pangolinService->removeServerIps([$_POST['ip_v4'], $_POST['ip_v6'] ?? null]);
                }
                // Se o servidor era inativo e agora está ativo, adiciona os IPs
                elseif ($oldStatus === 'inactive' && $_POST['status'] === 'active') {
                    if ($client && $client['status'] === 'active') {
                        $pangolinService->syncClient($_POST['client_id'], 'add');
                    }
                }
                // Se os IPs mudaram
                elseif (!empty($ipsToRemove) && $_POST['status'] === 'active') {
                    $pangolinService->removeServerIps($ipsToRemove);
                    if ($client && $client['status'] === 'active') {
                        $pangolinService->syncClient($_POST['client_id'], 'add');
                    }
                }

                // Se o cliente mudou, sincroniza o cliente antigo também
                if ($oldClientId != $_POST['client_id']) {
                    $oldClient = $clientModel->find($oldClientId);
                    if ($oldClient && $oldClient['status'] === 'active') {
                        $pangolinService->removeServerIps([$oldIpV4, $oldIpV6]);
                    }
                }
            }
        } catch (\Exception $e) {
            error_log("Pangolin Sync Error (Server Update): " . $e->getMessage());
        }

        View::redirect('/admin/servers');
    }

    public function delete($id)
    {
        $serverModel = new Server();
        $server = $serverModel->find($id);

        if (!$server) {
            View::redirect('/admin/servers');
            return;
        }

        // Capturar IPs antes de deletar
        $ipsToRemove = [$server['ip_v4']];
        if (!empty($server['ip_v6'])) {
            $ipsToRemove[] = $server['ip_v6'];
        }

        // Pangolin Integration - Remove os IPs do servidor antes de deletá-lo
        try {
            $pangolinService = new \App\Services\PangolinService();
            if ($pangolinService->isEnabled() && $server['status'] === 'active') {
                $clientModel = new Client();
                $client = $clientModel->find($server['client_id']);
                if ($client && $client['status'] === 'active') {
                    $pangolinService->removeServerIps($ipsToRemove);
                }
            }
        } catch (\Exception $e) {
            error_log("Pangolin Sync Error (Server Delete): " . $e->getMessage());
        }

        // Delete the server
        $serverModel->delete($id);

        View::redirect('/admin/servers');
    }

    public function resetMachineId($id)
    {
        $serverModel = new Server();
        $server = $serverModel->find($id);

        if ($server) {
            $sql = "UPDATE servers SET machine_id = NULL WHERE id = :id";
            $stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
            $stmt->execute(['id' => $id]);

            // Log action
            $logSql = "INSERT INTO api_logs (server_id, action, message, ip_address) VALUES (:sid, 'reset_machine', 'Machine ID reset by admin', :ip)";
            $logStmt = \App\Config\Database::getInstance()->getConnection()->prepare($logSql);
            $logStmt->execute([
                'sid' => $id,
                'ip' => $_SERVER['REMOTE_ADDR'] ?? null
            ]);
        }

        View::redirect('/admin/servers/edit/' . $id);
    }
}
