<?php

namespace App\Modules\Product\AutoVM;

use App\Core\Product\AbstractProduct;
use App\Core\Product\Events\AccountCreated;
use Illuminate\Support\Facades\Log;

/**
 * AutoVM (autovm.net) VPS/cloud panel product module.
 *
 * Transport & endpoints follow the OFFICIAL AutoVM API contract as implemented
 * by the WiseCP AutoVM server module
 * (coremio/modules/Servers/AutoVM/autovm.class.php + AutoVM.php):
 *
 *   - Auth: POST form-field `key` (application/x-www-form-urlencoded,
 *     http_build_query) on EVERY request — NOT a header token, NOT Bearer,
 *     NOT a JSON body. (autovm.class.php:27,529-565)
 *   - Success: HTTP response decodes to an object with `->ok == true`.
 *     (autovm.class.php:562)
 *   - Base URL is the admin-configured panel URL; endpoint is appended directly
 *     (`{base}/vps/create` etc). (autovm.class.php:82,490,...)
 *
 *   Endpoints (autovm.class.php):
 *     - /vps/create   create a VPS               (453-497) → returns ->id
 *     - /vps/info     VPS detail/status          (70-89)
 *     - /vps/start    power on                   (240-259)
 *     - /vps/stop     power off                  (261-280)
 *     - /vps/restart  reboot                     (282-301)
 *     - /vps/delete   terminate                  (196-215)
 *     - /vps/active   unsuspend                  (154-173)
 *     - /vps/inactive suspend                    (175-194)
 *     - /vps/update   upgrade / change package   (366-391)
 *     - /vps/install  reinstall OS               (217-238)
 *     - /vps/os       OS list (testConnection)   (134-152)
 *     - /user/info    lookup user by email       (345-364) → returns ->id
 *     - /user/create  create user                (499-521) → returns ->id
 *     - /server/ip    list free IPs on a server  (324-343) → returns ->ips
 *
 *   createAccount flow (autovm.class.php:53-68): resolve the AutoVM user by
 *   email via /user/info; if none, create it via /user/create; then create the
 *   VPS via /vps/create. The remote identity is the VPS id (`->id`), stored as
 *   the service account_id / module_handler_id (config.vpsid in WiseCP) and
 *   resolved back via $this->remoteId($params). The internal procp server_id is
 *   never used as the remote id.
 *
 *   Host/credentials (panel URL + API key) always resolve through
 *   $this->serverConfig($params) — assigned server first, else module_config.
 */
class AutoVM extends AbstractProduct
{
    /**
     * AutoVM modülü atanmış procp sunucusu gerektirmez — panel URL + API key
     * module-config'ten gelir; opsiyonel atanmış sunucu serverConfig fallback'i sağlar.
     */
    public function requiresServer(): bool
    {
        return false;
    }

    /**
     * Yeni bir AutoVM VPS'i oluşturur.
     *
     * Akış (WiseCP autovm.class.php:53-68 create()):
     *   1) /user/info ile e-postadan kullanıcı id'si çöz; yoksa
     *   2) /user/create ile kullanıcı oluştur; sonra
     *   3) /vps/create ile VPS oluştur → uzak-id = yanıt `->id` (config.vpsid).
     *
     * @param  array  $params
     * @return array İşlem sonucu
     */
    public function createAccount(array $params)
    {
        $email = $params['email'] ?? $params['client_email'] ?? '';

        // VPS yerleşim parametreleri (config option → module_config fallback).
        $serverId = $this->pick($params, ['server_id_remote', 'serverId'], ['server', 'serverId'], 'autovm_server_id');
        $planId = $this->pick($params, ['plan_id', 'planId'], ['plan', 'planId'], 'autovm_plan_id');
        $osId = $this->pick($params, ['os_id', 'osId'], ['os', 'osId'], 'autovm_os_id');
        $datastoreId = $this->pick($params, ['datastore_id', 'datastoreId'], ['datastore', 'datastoreId'], 'autovm_datastore_id');
        $ipId = $this->pick($params, ['ip_id', 'ipId'], ['ip', 'ipId'], 'autovm_ip_id');

        $missing = [];
        if (empty($email)) {
            $missing[] = 'email';
        }
        if (empty($serverId)) {
            $missing[] = 'server_id';
        }
        if (empty($planId)) {
            $missing[] = 'plan_id';
        }
        if (empty($osId)) {
            $missing[] = 'os_id';
        }

        if (! empty($missing)) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_param_missing', ['param' => implode(', ', $missing)]),
            ];
        }

        // 1) Kullanıcıyı e-postadan çöz (/user/info → ->id).
        $userId = null;
        $userInfo = $this->callAutoVmApi('/user/info', ['email' => $email], $params);
        if ($userInfo['status'] === 'success') {
            $userId = $userInfo['body']['id'] ?? null;
        }

        // 2) Kullanıcı yoksa oluştur (/user/create → ->id).
        if (empty($userId)) {
            $userCreate = $this->callAutoVmApi('/user/create', [
                'firstName' => (string) ($params['first_name'] ?? ''),
                'lastName' => (string) ($params['last_name'] ?? ''),
                'email' => $email,
                'password' => (string) ($params['password'] ?? ''),
            ], $params);

            if ($userCreate['status'] !== 'success' || empty($userCreate['body']['id'])) {
                $result = [
                    'status' => 'error',
                    'message' => $userCreate['message'] ?? __('admin/modules.autovm_user_create_failed'),
                ];
                AccountCreated::dispatch($params, $result);

                return $result;
            }

            $userId = $userCreate['body']['id'];
        }

        // 3) VPS oluştur (/vps/create → ->id). WiseCP alan adları (autovm.class.php:468-483).
        $hostname = $params['hostname'] ?? $params['domain'] ?? '';

        $createData = [
            'userId' => $userId,
            'serverId' => $serverId,
            'osId' => $osId,
            'planId' => $planId,
            'hostname' => $hostname,
        ];

        if (! empty($datastoreId)) {
            $createData['datastoreId'] = $datastoreId;
        }
        if (! empty($ipId)) {
            $createData['ipId'] = $ipId;
        }
        if (! empty($params['password'])) {
            $createData['password'] = $params['password'];
        }

        // Opsiyonel kaynak override'ları (config option → API alanı, WiseCP adları).
        foreach ([
            'vpsRam' => 'ram',
            'vpsCpuMhz' => 'cpu',
            'vpsCpuCore' => 'core',
            'vpsHard' => 'hard',
            'vpsBandwidth' => 'bandwidth',
        ] as $apiKey => $optionName) {
            $value = $params[$apiKey] ?? $this->configOption($params, $optionName);
            if (is_numeric($value)) {
                $createData[$apiKey] = $value;
            }
        }

        $response = $this->callAutoVmApi('/vps/create', $createData, $params);

        if ($response['status'] === 'success') {
            $vpsId = $this->extractId($response['body']);

            $result = [
                'status' => 'success',
                'message' => __('admin/modules.autovm_account_created_success'),
                'data' => $response['body'] ?? [],
            ];

            // Uzak VPS id'sini servise geri yaz (account_id/module_handler_id = config.vpsid).
            if ($vpsId !== null) {
                $result['account_id'] = $vpsId;
                $result['module_handler_id'] = $vpsId;
            }

            AccountCreated::dispatch($params, $result);

            return $result;
        }

        $result = [
            'status' => 'error',
            'message' => $response['message'] ?? __('admin/modules.autovm_account_create_failed'),
            'data' => $response['body'] ?? [],
        ];

        AccountCreated::dispatch($params, $result);

        return $result;
    }

    /**
     * VPS'i askıya alır (/vps/inactive — WiseCP suspend()).
     */
    public function suspendAccount(array $params)
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_machine_id_required'),
            ];
        }

        $response = $this->callAutoVmApi('/vps/inactive', ['id' => $vpsId], $params);

        return $response['status'] === 'success'
            ? ['status' => 'success', 'message' => __('admin/modules.autovm_account_suspended_success')]
            : [
                'status' => 'error',
                'message' => $response['message'] ?? __('admin/modules.autovm_account_suspend_failed'),
                'data' => $response['body'] ?? [],
            ];
    }

    /**
     * Askıya alınmış VPS'i aktifleştirir (/vps/active — WiseCP unsuspend()).
     */
    public function unsuspendAccount(array $params)
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_machine_id_required'),
            ];
        }

        $response = $this->callAutoVmApi('/vps/active', ['id' => $vpsId], $params);

        return $response['status'] === 'success'
            ? ['status' => 'success', 'message' => __('admin/modules.autovm_account_unsuspended_success')]
            : [
                'status' => 'error',
                'message' => $response['message'] ?? __('admin/modules.autovm_account_unsuspend_failed'),
                'data' => $response['body'] ?? [],
            ];
    }

    /**
     * VPS'i kalıcı olarak siler (/vps/delete — WiseCP terminate()).
     */
    public function terminateAccount(array $params)
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_machine_id_required'),
            ];
        }

        $response = $this->callAutoVmApi('/vps/delete', ['id' => $vpsId], $params);

        return $response['status'] === 'success'
            ? ['status' => 'success', 'message' => __('admin/modules.autovm_account_terminated_success')]
            : [
                'status' => 'error',
                'message' => $response['message'] ?? __('admin/modules.autovm_account_terminate_failed'),
                'data' => $response['body'] ?? [],
            ];
    }

    /**
     * VPS OS'unu (parola ile birlikte) yeniden kurar (/vps/install).
     *
     * AutoVM'de "parola değiştir" ayrı endpoint değildir; parola OS reinstall
     * (/vps/install — autovm.class.php:217-238) sırasında set edilir. OS id +
     * yeni parola gerekir; ikisi de yoksa dürüstçe hata döner (sahte-success yok).
     */
    public function changeAccountPassword(array $params)
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_machine_id_required'),
            ];
        }

        $password = $params['password'] ?? $params['new_password'] ?? '';
        $osId = $this->pick($params, ['os_id', 'osId'], ['os', 'osId'], 'autovm_os_id');

        if (empty($password) || empty($osId)) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_change_password_unsupported'),
            ];
        }

        $response = $this->callAutoVmApi('/vps/install', [
            'id' => $vpsId,
            'os' => $osId,
            'password' => $password,
        ], $params);

        return $response['status'] === 'success'
            ? ['status' => 'success', 'message' => __('admin/modules.autovm_password_changed_success')]
            : [
                'status' => 'error',
                'message' => $response['message'] ?? __('admin/modules.autovm_password_change_failed'),
                'data' => $response['body'] ?? [],
            ];
    }

    /**
     * Paket/plan değiştir = VPS kaynaklarını günceller (/vps/update — WiseCP upgrade()).
     *
     * Alanlar autovm.class.php:366-377: planId + ram/cpuMhz/cpuCore/hard/bandwidth.
     * Yeni plan id gereklidir (yalnız plan adı değil).
     */
    public function changeAccountPackage(array $params)
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_machine_id_required'),
            ];
        }

        $planId = $this->pick($params, ['plan_id', 'planId'], ['plan', 'planId'], 'autovm_plan_id');

        if (empty($planId)) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_plan_id_required'),
            ];
        }

        $updateData = [
            'id' => $vpsId,
            'planId' => $planId,
        ];

        // Opsiyonel kaynak override'ları (WiseCP upgrade alan adları).
        foreach ([
            'ram' => 'ram',
            'cpuMhz' => 'cpu',
            'cpuCore' => 'core',
            'hard' => 'hard',
            'bandwidth' => 'bandwidth',
        ] as $apiKey => $optionName) {
            $value = $params[$apiKey] ?? $this->configOption($params, $optionName);
            if (is_numeric($value)) {
                $updateData[$apiKey] = $value;
            }
        }

        $response = $this->callAutoVmApi('/vps/update', $updateData, $params);

        return $response['status'] === 'success'
            ? ['status' => 'success', 'message' => __('admin/modules.autovm_package_changed_success')]
            : [
                'status' => 'error',
                'message' => $response['message'] ?? __('admin/modules.autovm_package_change_failed'),
                'data' => $response['body'] ?? [],
            ];
    }

    /**
     * Bağlantı testi — OS listesi çekilerek panel URL + API key doğrulanır
     * (/vps/os — WiseCP testConnect() → osList()).
     */
    public function testConnection(array $params = [])
    {
        $response = $this->callAutoVmApi('/vps/os', [], $params);

        if ($response['status'] === 'success') {
            return [
                'status' => 'success',
                'message' => __('admin/modules.autovm_connection_test_success'),
                'data' => $response['body'] ?? [],
            ];
        }

        return [
            'status' => 'error',
            'message' => __('admin/modules.autovm_connection_test_failed'),
            'data' => $response['body'] ?? [],
        ];
    }

    /**
     * Admin panelinde gösterilecek alanları döndürür
     */
    public function adminFields()
    {
        return [
            // Field key `hostname` — serverConfig helper'ının host anahtarlarından biri
            // (AutoVM panel URL; endpoint bu tabana eklenir).
            'hostname' => [
                'name' => __('admin/modules.autovm_field_backend_url'),
                'type' => 'text',
                'description' => __('admin/modules.autovm_field_backend_url_description'),
                'required' => true,
            ],
            // Field key `api_key` — serverConfig helper'ının password anahtarlarından biri
            // (AutoVM API key; her isteğe `key` form alanı olarak gönderilir).
            'api_key' => [
                'name' => __('admin/modules.autovm_field_admin_token'),
                'type' => 'password',
                'description' => __('admin/modules.autovm_field_admin_token_description'),
                'required' => true,
            ],
            'use_ssl' => [
                'name' => __('admin/modules.autovm_field_use_ssl'),
                'type' => 'checkbox',
                'description' => __('admin/modules.autovm_field_use_ssl_description'),
                'default' => true,
            ],
        ];
    }

    /**
     * Müşteri panelinde gösterilecek alanları döndürür
     */
    public function clientFields()
    {
        return [
            'hostname' => [
                'name' => __('admin/modules.autovm_field_client_hostname'),
                'type' => 'text',
                'description' => __('admin/modules.autovm_field_client_hostname_description'),
                'required' => true,
            ],
        ];
    }

    /**
     * Server yönetimi için gösterilecek alanları döndürür
     */
    public function serverFields()
    {
        return [
            'api_key' => [
                'name' => __('admin/modules.autovm_field_admin_token'),
                'type' => 'password',
                'description' => __('admin/modules.autovm_field_admin_token_description'),
                'required' => true,
            ],
        ];
    }

    /**
     * Admin panelde gösterilecek özel butonları döndürür
     */
    public function getAdminButtons(): array
    {
        return [
            [
                'action' => 'list_os',
                'label' => __('admin/modules.autovm_action_list_os'),
                'icon' => 'fas fa-compact-disc',
                'class' => 'btn-outline-info',
            ],
            [
                'action' => 'machine_info',
                'label' => __('admin/modules.autovm_action_machine_info'),
                'icon' => 'fas fa-info-circle',
                'class' => 'btn-outline-primary',
            ],
        ];
    }

    /**
     * Admin özel action'ı işler
     */
    public function adminCustomAction(string $action, array $params): array
    {
        switch ($action) {
            case 'list_os':
                $response = $this->callAutoVmApi('/vps/os', [], $params);

                if ($response['status'] !== 'success') {
                    return [
                        'status' => 'error',
                        'message' => $response['message'] ?? __('admin/modules.autovm_list_os_failed'),
                    ];
                }

                return [
                    'status' => 'success',
                    'message' => __('admin/modules.autovm_list_os_success'),
                    'data' => $response['body'] ?? [],
                ];

            case 'machine_info':
                $vpsId = $this->remoteId($params);

                if ($vpsId === null) {
                    return [
                        'status' => 'error',
                        'message' => __('admin/modules.autovm_machine_id_required'),
                    ];
                }

                $response = $this->callAutoVmApi('/vps/info', ['id' => $vpsId], $params);

                if ($response['status'] !== 'success') {
                    return [
                        'status' => 'error',
                        'message' => $response['message'] ?? __('admin/modules.autovm_machine_info_failed'),
                    ];
                }

                return [
                    'status' => 'success',
                    'message' => __('admin/modules.autovm_machine_info_success'),
                    'data' => $response['body'] ?? [],
                ];

            default:
                return [
                    'status' => 'error',
                    'message' => __('admin/modules.autovm_action_not_supported', ['action' => $action]),
                ];
        }
    }

    /**
     * Client area'da gösterilecek action'ları döndürür
     */
    public function getClientActions(): array
    {
        $actions = parent::getClientActions();

        // AutoVM inline parola değiştirme (reinstall gerektirir) — varsayılan
        // change_password action'ını kaldır.
        unset($actions['change_password']);

        $actions['start'] = [
            'label' => __('admin/modules.autovm_action_start'),
            'icon' => 'fas fa-play',
            'class' => 'btn-outline-success',
            'enabled' => true,
        ];

        $actions['stop'] = [
            'label' => __('admin/modules.autovm_action_stop'),
            'icon' => 'fas fa-stop',
            'class' => 'btn-outline-danger',
            'enabled' => true,
        ];

        $actions['restart'] = [
            'label' => __('admin/modules.autovm_action_restart'),
            'icon' => 'fas fa-sync',
            'class' => 'btn-outline-warning',
            'enabled' => true,
        ];

        return $actions;
    }

    /**
     * Client action'ı işler
     */
    public function handleClientAction(string $action, array $params): array
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_machine_id_required'),
            ];
        }

        switch ($action) {
            case 'start':
                $response = $this->callAutoVmApi('/vps/start', ['id' => $vpsId], $params);

                return $response['status'] === 'success'
                    ? ['status' => 'success', 'message' => __('admin/modules.autovm_machine_started_success')]
                    : ['status' => 'error', 'message' => $response['message'] ?? __('admin/modules.autovm_machine_start_failed')];

            case 'stop':
                $response = $this->callAutoVmApi('/vps/stop', ['id' => $vpsId], $params);

                return $response['status'] === 'success'
                    ? ['status' => 'success', 'message' => __('admin/modules.autovm_machine_stopped_success')]
                    : ['status' => 'error', 'message' => $response['message'] ?? __('admin/modules.autovm_machine_stop_failed')];

            case 'restart':
                $response = $this->callAutoVmApi('/vps/restart', ['id' => $vpsId], $params);

                return $response['status'] === 'success'
                    ? ['status' => 'success', 'message' => __('admin/modules.autovm_machine_restarted_success')]
                    : ['status' => 'error', 'message' => $response['message'] ?? __('admin/modules.autovm_machine_restart_failed')];

            default:
                return parent::handleClientAction($action, $params);
        }
    }

    /**
     * Kaynak kullanım bilgilerini döndürür (CPU, RAM, Disk, Bandwidth).
     *
     * AutoVM VPS info endpoint'inden (/vps/info) kullanım verisi çeker.
     */
    public function getResourceUsage(array $params): ?array
    {
        $vpsId = $this->remoteId($params);

        if ($vpsId === null) {
            return null;
        }

        $response = $this->callAutoVmApi('/vps/info', ['id' => $vpsId], $params);

        if ($response['status'] !== 'success' || empty($response['body'])) {
            return null;
        }

        $body = $response['body'];

        if (! is_array($body)) {
            return null;
        }

        // AutoVM info yanıtı VPS detayını `vps` altında verir (autovm.class.php get_info/get_status).
        $stats = (isset($body['vps']) && is_array($body['vps'])) ? $body['vps'] : $body;

        $resources = [];

        if (isset($stats['cpu']) && is_array($stats['cpu'])) {
            $resources[] = [
                'name' => 'CPU',
                'used' => (float) ($stats['cpu']['used'] ?? 0),
                'limit' => (float) ($stats['cpu']['limit'] ?? 100),
                'unit' => '%',
                'percentage' => (float) ($stats['cpu']['percentage'] ?? 0),
            ];
        }

        if (isset($stats['memory']) && is_array($stats['memory'])) {
            $resources[] = [
                'name' => 'Memory',
                'used' => (float) ($stats['memory']['used'] ?? 0),
                'limit' => (float) ($stats['memory']['limit'] ?? 0),
                'unit' => 'MB',
                'percentage' => (float) ($stats['memory']['percentage'] ?? 0),
            ];
        }

        if (isset($stats['disk']) && is_array($stats['disk'])) {
            $resources[] = [
                'name' => 'Disk Space',
                'used' => (float) ($stats['disk']['used'] ?? 0),
                'limit' => (float) ($stats['disk']['limit'] ?? 0),
                'unit' => 'GB',
                'percentage' => (float) ($stats['disk']['percentage'] ?? 0),
            ];
        }

        if (isset($stats['bandwidth']) && is_array($stats['bandwidth'])) {
            $resources[] = [
                'name' => 'Bandwidth',
                'used' => (float) ($stats['bandwidth']['used'] ?? 0),
                'limit' => (float) ($stats['bandwidth']['limit'] ?? 0),
                'unit' => 'GB',
                'percentage' => (float) ($stats['bandwidth']['percentage'] ?? 0),
            ];
        }

        return $resources;
    }

    /**
     * $params → config_option → module_config sırasıyla bir yerleşim değeri okur.
     *
     * @param  array  $paramKeys       $params içinde denenecek anahtarlar
     * @param  array  $configOptNames  configOption() ile denenecek adlar
     * @param  string $moduleConfigKey moduleConfig() fallback anahtarı
     * @return mixed
     */
    private function pick(array $params, array $paramKeys, array $configOptNames, string $moduleConfigKey)
    {
        foreach ($paramKeys as $key) {
            if (isset($params[$key]) && $params[$key] !== '') {
                return $params[$key];
            }
        }

        foreach ($configOptNames as $name) {
            $value = $this->configOption($params, $name);
            if ($value !== null && $value !== '') {
                return $value;
            }
        }

        return $this->moduleConfig($params, $moduleConfigKey);
    }

    /**
     * AutoVM API yanıt gövdesinden oluşturulan kaydın id'sini güvenle çıkarır.
     *
     * @param  mixed  $body
     */
    private function extractId($body): ?string
    {
        if (! is_array($body)) {
            return null;
        }

        $candidate = $body['id'] ?? ($body['vps']['id'] ?? ($body['data']['id'] ?? null));

        return ($candidate !== null && $candidate !== '') ? (string) $candidate : null;
    }

    /**
     * AutoVM API'si ile iletişim kurar (WiseCP autovm.class.php:529-565 curlRequest).
     *
     * Sözleşme:
     *   - Her istek POST, gövde `http_build_query($data)`
     *     (application/x-www-form-urlencoded).
     *   - `key` form alanı olarak API key eklenir (header/Bearer DEĞİL).
     *   - Başarı: yanıt JSON'u `ok == true` ise. Aksi halde hata.
     *
     * Base URL + API key her zaman $this->serverConfig($params) üzerinden çözülür
     * (atanmış sunucu öncelikli, yoksa module_config) — inline $this->config yok.
     *
     * PCI/GÜVENLİK: API key/parola/ham-yanıt ASLA loglanmaz — yalnız endpoint,
     * method ve http_code.
     *
     * @param  string  $endpoint  Base URL sonrası yol (ör. '/vps/create')
     * @param  array   $data      `key` DIŞI gönderilecek form alanları
     * @param  array   $params    Modül param bağlamı (server/module_config için)
     * @return array{status:string,message:string,body:array}
     */
    protected function callAutoVmApi(string $endpoint, array $data, array $params)
    {
        $cfg = $this->serverConfig($params);

        $host = trim((string) $cfg['hostname']);
        $key = (string) $cfg['password']; // serverConfig password'ü api_key/token alanlarından toplar
        $secure = (bool) $cfg['secure'];

        if ($host === '' || $key === '') {
            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_config_missing'),
                'body' => [],
            ];
        }

        // Panel URL tam bir URL (https://host[/path]) olabilir; şema yoksa ekle.
        if (preg_match('#^https?://#i', $host)) {
            $base = rtrim($host, '/');
        } else {
            $protocol = $secure ? 'https' : 'http';
            $base = $protocol . '://' . rtrim($host, '/');
        }

        $url = $base . '/' . ltrim($endpoint, '/');

        // `key` her istekte gider (WiseCP: her metot $data'ya 'key' ekler).
        $postData = array_merge(['key' => $key], $data);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);

        curl_close($ch);

        if ($response === false || $curlError) {
            // Güvenlik: yalnız endpoint yolu + method — key/ham-yanıt loglanmaz.
            Log::error('AutoVM API cURL error', [
                'endpoint' => $endpoint,
                'method' => 'POST',
            ]);

            return [
                'status' => 'error',
                'message' => __('admin/modules.autovm_api_connection_error'),
                'body' => [],
            ];
        }

        // WiseCP quirk: yanıt "}{" ile birleşik gelebilir — ilk JSON nesnesini al.
        if (is_string($response) && strpos($response, '}{') !== false) {
            $response = explode('}{', $response, 2)[0] . '}';
        }

        $body = json_decode((string) $response, true);

        if ($httpCode >= 400 || ! is_array($body)) {
            // Ham yanıt gövdesi (kimlik bilgisi içerebilir) loglanmaz — sadece kod.
            Log::warning('AutoVM API error response', [
                'endpoint' => $endpoint,
                'method' => 'POST',
                'http_code' => $httpCode,
            ]);

            return [
                'status' => 'error',
                'message' => (is_array($body) && ! empty($body['message']))
                    ? $body['message']
                    : __('admin/modules.autovm_api_call_failed', ['code' => $httpCode]),
                'body' => is_array($body) ? $body : [],
            ];
        }

        // AutoVM başarısı: gövdede `ok == true` (autovm.class.php:562). Aksi = hata,
        // HTTP 200 olsa bile — sahte-success YOK.
        $ok = ! empty($body['ok']);

        if (! $ok) {
            return [
                'status' => 'error',
                'message' => ! empty($body['message']) ? $body['message'] : __('admin/modules.autovm_api_call_failed', ['code' => $httpCode]),
                'body' => $body,
            ];
        }

        return [
            'status' => 'success',
            'message' => $body['message'] ?? '',
            'body' => $body,
        ];
    }

    /**
     * Yapılandırma doğrulaması — panel URL + API key (serverConfig üzerinden).
     *
     * @return bool
     *
     * @throws \Exception Eksik yapılandırma durumunda
     */
    public function validateConfig()
    {
        $cfg = $this->serverConfig([]);

        if (trim((string) $cfg['hostname']) === '') {
            throw new \Exception(__('admin/modules.autovm_config_hostname_missing'));
        }

        if (trim((string) $cfg['password']) === '') {
            throw new \Exception(__('admin/modules.autovm_config_api_key_missing'));
        }

        return true;
    }
}
