<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Server;
use App\Models\ServerIp;
use App\Services\WalletService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

class DeductHourlyServerCost extends Command
{
    protected $signature = 'servers:deduct-hourly-cost';
    protected $description = 'کسر هزینه ساعتی سرورها و IPها + کسر ماهانه Floating IPs';

    protected $walletService;

    // هزینه‌های ثابت (تومان)
    // Primary IPs - ساعتی ✅
    private const HETZNER_PRIMARY_IPV4_HOURLY = 250;
    private const HETZNER_PRIMARY_IPV6_HOURLY = 0; // ✅ IPv6 رایگان
    
    // Floating IPs - ماهانه ✅
    private const HETZNER_FLOATING_IPV4_MONTHLY = 750000;
    private const HETZNER_FLOATING_IPV6_MONTHLY = 300000;
    
    // Vultr
    private const VULTR_IPV4_HOURLY = 480;
    
    // تنظیمات
    private const SERVER_MINIMUM_BALANCE = 5000;
    private const SUSPEND_HOURS_BEFORE_DELETE_SERVER = 12;
    private const SUSPEND_HOURS_BEFORE_DELETE_IP = 3;
    private const IP_MINIMUM_AGE_HOURS = 48; // ✅ حداقل 48 ساعت برای حذف

    public function __construct(WalletService $walletService)
    {
        parent::__construct();
        $this->walletService = $walletService;
    }

    public function handle()
    {
        $this->info('🚀 شروع کسر هزینه ساعتی سرورها و IPها...');
        $this->info('⏰ زمان: ' . now()->format('Y-m-d H:i:s'));
        
        Log::info('Hourly cost deduction started', [
            'timestamp' => now()->toDateTimeString(),
        ]);
        
        $startTime = microtime(true);

        // مرحله 1: پردازش سرورهای فعال
        $this->processActiveServers();

        // مرحله 2: کسر هزینه Detached Primary IPs ✅
        $this->processDetachedPrimaryIps();

        // مرحله 3: کسر ماهانه Floating IPs (روز اول ماه)
        if (now()->day == 1 && now()->hour == 0) {
            $this->info("\n📅 روز اول ماه: کسر هزینه ماهانه Floating IPs...");
            $this->processMonthlyFloatingIps();
        }

        // مرحله 4: حذف سرورهای suspended قدیمی
        $this->deleteOldSuspendedServers();

        // مرحله 5: حذف IPهای suspended قدیمی
        $this->deleteOldSuspendedIps();

        $executionTime = round(microtime(true) - $startTime, 2);
        $this->info("\n✅ کسر هزینه با موفقیت انجام شد (زمان اجرا: {$executionTime} ثانیه)");
        
        Log::info('Hourly cost deduction completed', [
            'execution_time' => $executionTime,
            'timestamp' => now()->toDateTimeString(),
        ]);
        
        return 0;
    }

    /**
     * پردازش سرورهای فعال
     */
private function processActiveServers()
{
    // ✅ شامل سرورهای خاموش (stopped, off)
    $servers = Server::whereIn('status', ['creating', 'running', 'active', 'stopped', 'off'])
        ->with('user', 'ips')
        ->get();

    $this->info("📊 تعداد سرورها (فعال + خاموش): {$servers->count()}");
    $processedCount = 0;
    $suspendedCount = 0;

    foreach ($servers as $server) {
        $user = $server->user;

        if (!$user) {
            $this->warn("⚠️ سرور #{$server->id}: کاربر یافت نشد");
            continue;
        }

        // بررسی موجودی کافی
        if ($user->wallet_balance < self::SERVER_MINIMUM_BALANCE) {
            $this->handleInsufficientBalance($server, $user);
            $suspendedCount++;
            continue;
        }

        // کسر هزینه سرور
        $serverDeducted = $this->deductServerCost($server, $user);
        
        // کسر هزینه Primary IPs (ساعتی) ✅
        $ipsDeducted = $this->deductPrimaryIpsCost($server, $user);

        if ($serverDeducted || $ipsDeducted) {
            $processedCount++;
            
            // فعال‌سازی سرور اگر قبلاً suspended بود
            if ($server->status === 'suspended') {
                $this->reactivateServer($server);
            }
        }
    }

    $this->info("✔️ پردازش شد: {$processedCount} | مسدود شد: {$suspendedCount}");
}

    /**
     * کسر هزینه سرور
     */
    private function deductServerCost(Server $server, $user)
    {
        $cost = $server->price_hourly_toman;

        if (!$cost || $cost == 0) {
            $this->warn("  ⚠️ سرور #{$server->id}: هزینه تعریف نشده");
            return false;
        }

        $transaction = $this->walletService->deductServerHourlyCost(
            $user,
            $server->id,
            $server->name,
            $cost,
            $server->provider
        );

        if ($transaction) {
            $this->line("  💰 سرور '{$server->name}' (#{$server->id}): -" . number_format($cost) . " تومان");
            return true;
        } else {
            $this->error("  ❌ سرور #{$server->id}: موجودی ناکافی");
            return false;
        }
    }

    /**
     * کسر هزینه Primary IPs متصل به سرور (ساعتی) ✅
     */
    private function deductPrimaryIpsCost(Server $server, $user)
    {
        $totalDeducted = 0;

        // فقط Primary IPs فعال در Hetzner (ساعتی هستند)
        $primaryIps = $server->ips()
            ->where('is_primary', 1)
            ->where('status', 'active')
            ->get();

        foreach ($primaryIps as $ip) {
            $hourlyCost = $this->getPrimaryIpHourlyCost($server->provider, $ip->type);

            if ($hourlyCost == 0) {
                continue; // رایگان (IPv6) یا غیرمجاز
            }

            $transaction = $this->walletService->deductIpHourlyCost(
                $user,
                $ip->id,
                $ip->ip,
                $server->id,
                $hourlyCost,
                $ip->type
            );

            if ($transaction) {
                $this->line("  🌐 Primary IP ({$ip->ip}, {$ip->type}): -" . number_format($hourlyCost) . " تومان");
                $totalDeducted += $hourlyCost;
                
                // به‌روزرسانی last_charged_at
                $ip->update(['last_charged_at' => now()]);
                
                // فعال‌سازی IP اگر suspended بود
                if ($ip->status === 'suspended') {
                    $ip->status = 'active';
                    $ip->suspended_at = null;
                    $ip->save();
                    $this->line("    🔄 IP فعال شد");
                }
            } else {
                $this->warn("  ⚠️ Primary IP {$ip->ip}: موجودی ناکافی");
                
                // مسدود کردن IP
                if ($ip->status !== 'suspended') {
                    $ip->status = 'suspended';
                    $ip->suspended_at = now();
                    $ip->save();
                    $this->warn("    🔒 IP مسدود شد");
                }
            }
        }

        return $totalDeducted > 0;
    }

    /**
     * کسر هزینه Detached Primary IPs (ساعتی) ✅
     */
    private function processDetachedPrimaryIps()
    {
        $detachedIps = ServerIp::where('is_primary', 1)
            ->where('status', 'detached')
            ->where('provider', 'hetzner')
            ->with('user')
            ->get();

        $this->info("\n📊 تعداد Primary IPs (Detached): {$detachedIps->count()}");

        $successCount = 0;
        $suspendedCount = 0;

        foreach ($detachedIps as $ip) {
            $user = $ip->user;

            if (!$user) {
                $this->warn("⚠️ IP {$ip->ip}: کاربر یافت نشد");
                continue;
            }

            $hourlyCost = $this->getPrimaryIpHourlyCost('hetzner', $ip->type);

            if ($hourlyCost == 0) {
                continue; // IPv6 رایگان
            }

            // بررسی موجودی
            if ($user->wallet_balance < $hourlyCost) {
                $this->handleInsufficientBalanceForIp($ip, $user);
                $suspendedCount++;
                continue;
            }

            $transaction = $this->walletService->deduct(
                $user,
                $hourlyCost,
                'ip_hourly',
                "هزینه ساعتی Primary IP {$ip->ip} (Detached)",
                'ip',
                $ip->id
            );

            if ($transaction) {
                $this->line("  🌐 Detached IP ({$ip->ip}, {$ip->type}): -" . number_format($hourlyCost) . " تومان");
                $successCount++;
                
                // به‌روزرسانی last_charged_at
                $ip->update(['last_charged_at' => now()]);

                // فعال‌سازی اگر suspended بود
                if ($ip->status === 'suspended') {
                    $ip->status = 'detached';
                    $ip->suspended_at = null;
                    $ip->save();
                    $this->line("    🔄 IP فعال شد");
                }
            } else {
                $this->warn("  ⚠️ Detached IP {$ip->ip}: موجودی ناکافی");
                $this->handleInsufficientBalanceForIp($ip, $user);
                $suspendedCount++;
            }
        }

        $this->info("✔️ Detached IPs - موفق: {$successCount} | مسدود: {$suspendedCount}");
    }

    /**
     * محاسبه هزینه ساعتی Primary IP ✅
     */
    private function getPrimaryIpHourlyCost($provider, $ipType)
    {
        // فقط Hetzner Primary IPs ساعتی هستند
        if ($provider === 'hetzner') {
            if (strtolower($ipType) === 'ipv6') {
                return self::HETZNER_PRIMARY_IPV6_HOURLY; // 0 (رایگان)
            }
            return self::HETZNER_PRIMARY_IPV4_HOURLY; // 250
        }
        
        return 0;
    }

    /**
     * کسر ماهانه Floating IPs (روز اول ماه) ✅
     */
    private function processMonthlyFloatingIps()
    {
        $floatingIps = ServerIp::where('is_floating', 1)
            ->where('status', 'active')
            ->with(['server.user'])
            ->get();

        $this->info("📊 تعداد Floating IPs فعال: {$floatingIps->count()}");

        $successCount = 0;
        $failedCount = 0;

        foreach ($floatingIps as $ip) {
            try {
                $server = $ip->server;
                if (!$server) {
                    $this->warn("⚠️ سرور مربوط به IP {$ip->ip} یافت نشد");
                    continue;
                }

                $user = $server->user;
                if (!$user) {
                    $this->warn("⚠️ کاربر مربوط به IP {$ip->ip} یافت نشد");
                    continue;
                }

                $monthlyCost = $this->getFloatingIpMonthlyCost($server->provider, $ip->type);

                if ($monthlyCost <= 0) {
                    continue; // رایگان
                }

                $transaction = $this->walletService->deduct(
                    $user,
                    $monthlyCost,
                    'floating_ip_monthly',
                    "هزینه ماهانه Floating IP {$ip->ip} ({$ip->type})",
                    'ip',
                    $ip->id,
                    [
                        'ip_id' => $ip->id,
                        'ip_address' => $ip->ip,
                        'server_id' => $server->id,
                        'ip_type' => $ip->type,
                        'billing_period' => 'monthly',
                    ]
                );

                if ($transaction) {
                    $this->line("  🌍 Floating IP ({$ip->ip}, {$ip->type}): -" . number_format($monthlyCost) . " تومان");
                    $successCount++;
                } else {
                    $this->warn("  ⚠️ Floating IP {$ip->ip}: موجودی ناکافی");
                    
                    // مسدود کردن
                    if ($ip->status !== 'suspended') {
                        $ip->status = 'suspended';
                        $ip->suspended_at = now();
                        $ip->save();
                        $this->warn("    🔒 Floating IP مسدود شد");
                    }
                    
                    $failedCount++;
                }

            } catch (\Exception $e) {
                $failedCount++;
                $this->error("❌ خطا در پردازش Floating IP #{$ip->id}: {$e->getMessage()}");
                Log::error('Floating IP monthly deduction error', [
                    'ip_id' => $ip->id,
                    'error' => $e->getMessage()
                ]);
            }
        }

        $this->info("✔️ Floating IPs - موفق: {$successCount} | ناموفق: {$failedCount}");
    }

    /**
     * محاسبه هزینه ماهانه Floating IP ✅
     */
    private function getFloatingIpMonthlyCost($provider, $ipType)
    {
        if ($provider === 'hetzner') {
            if (strtolower($ipType) === 'ipv6') {
                return self::HETZNER_FLOATING_IPV6_MONTHLY; // 300,000
            }
            return self::HETZNER_FLOATING_IPV4_MONTHLY; // 750,000
        }
        
        // Vultr (ساعتی - محاسبه ماهانه)
        if ($provider === 'vultr') {
            return self::VULTR_IPV4_HOURLY * 730;
        }
        
        return 0;
    }

    /**
     * مدیریت سرور با موجودی ناکافی
     */
    private function handleInsufficientBalance(Server $server, $user)
    {
        if ($server->status !== 'suspended') {
            $server->status = 'suspended';
            $server->suspended_at = now();
            $server->save();

            $this->warn("🔒 سرور #{$server->id} مسدود شد (موجودی: " . number_format($user->wallet_balance) . " تومان)");

            // توقف سرور در Provider
            $this->stopServerAtProvider($server);
        }
    }

    /**
     * مدیریت IP با موجودی ناکافی ✅
     */
    private function handleInsufficientBalanceForIp(ServerIp $ip, $user)
    {
        if ($ip->status !== 'suspended') {
            $ip->status = 'suspended';
            $ip->suspended_at = now();
            $ip->save();

            $this->warn("🔒 IP {$ip->ip} مسدود شد (موجودی: " . number_format($user->wallet_balance) . " تومان)");
        }
    }

    /**
     * توقف سرور در Provider
     */
    private function stopServerAtProvider(Server $server)
    {
        try {
            if ($server->provider === 'vultr' && $server->provider_id) {
                $response = Http::withHeaders([
                    'Authorization' => 'Bearer ' . config('services.vultr.api_key'),
                ])->post("https://api.vultr.com/v2/instances/{$server->provider_id}/halt");

                if ($response->successful()) {
                    $this->line("  🛑 Vultr سرور متوقف شد");
                }
            } elseif ($server->provider === 'hetzner' && $server->provider_id) {
                $response = Http::withHeaders([
                    'Authorization' => 'Bearer ' . config('services.hetzner.api_token'),
                ])->post("https://api.hetzner.cloud/v1/servers/{$server->provider_id}/actions/poweroff");

                if ($response->successful()) {
                    $this->line("  🛑 Hetzner سرور متوقف شد");
                }
            }
        } catch (\Exception $e) {
            Log::error("خطا در توقف سرور {$server->id}: " . $e->getMessage());
        }
    }

    /**
     * فعال‌سازی مجدد سرور
     */
    private function reactivateServer(Server $server)
    {
        $server->status = 'active';
        $server->suspended_at = null;
        $server->save();

        $this->info("  🔄 سرور #{$server->id} فعال شد (شارژ مجدد)");
    }

    /**
     * حذف سرورهای suspended قدیمی
     */
    private function deleteOldSuspendedServers()
    {
        $cutoffTime = now()->subHours(self::SUSPEND_HOURS_BEFORE_DELETE_SERVER);
        
        $oldServers = Server::where('status', 'suspended')
            ->where('suspended_at', '<', $cutoffTime)
            ->get();

        if ($oldServers->isEmpty()) {
            return;
        }

        $this->info("\n🗑️ حذف {$oldServers->count()} سرور suspended قدیمی...");

        foreach ($oldServers as $server) {
            $hoursAgo = $server->suspended_at ? $server->suspended_at->diffInHours(now()) : 0;
            $this->warn("  ⏰ سرور #{$server->id}: {$hoursAgo} ساعت پیش مسدود شده");

            $this->deleteServerFromProvider($server);
            $server->delete();
            $this->line("  ✅ سرور #{$server->id} حذف شد");
        }
    }

    /**
     * حذف سرور از Provider
     */
    private function deleteServerFromProvider(Server $server)
    {
        try {
            if ($server->provider === 'vultr' && $server->provider_id) {
                Http::withHeaders([
                    'Authorization' => 'Bearer ' . config('services.vultr.api_key'),
                ])->delete("https://api.vultr.com/v2/instances/{$server->provider_id}");
            } elseif ($server->provider === 'hetzner' && $server->provider_id) {
                Http::withHeaders([
                    'Authorization' => 'Bearer ' . config('services.hetzner.api_token'),
                ])->delete("https://api.hetzner.cloud/v1/servers/{$server->provider_id}");
            }
        } catch (\Exception $e) {
            Log::error("خطا در حذف سرور {$server->id}: " . $e->getMessage());
        }
    }

    /**
     * حذف IPهای suspended قدیمی ✅ با محدودیت 48 ساعت
     */
    private function deleteOldSuspendedIps()
    {
        $cutoffTime = now()->subHours(self::SUSPEND_HOURS_BEFORE_DELETE_IP);
        $minimumAge = now()->subHours(self::IP_MINIMUM_AGE_HOURS);
        
        $oldIps = ServerIp::where('status', 'suspended')
            ->where('suspended_at', '<', $cutoffTime)
            ->where('created_at', '<', $minimumAge) // ✅ حداقل 48 ساعت از ساخت
            ->get();

        if ($oldIps->isEmpty()) {
            return;
        }

        $this->info("\n🗑️ حذف {$oldIps->count()} IP suspended قدیمی...");

        foreach ($oldIps as $ip) {
            $hoursAgo = $ip->suspended_at ? $ip->suspended_at->diffInHours(now()) : 0;
            $hoursSinceCreation = $ip->created_at->diffInHours(now());
            
            $this->warn("  ⏰ IP {$ip->ip}: {$hoursAgo}h suspended | {$hoursSinceCreation}h از ساخت");

            $this->deleteIpFromProvider($ip);
            $ip->delete();
            $this->line("  ✅ IP {$ip->ip} حذف شد");
        }
    }

    /**
     * حذف IP از Provider
     */
    private function deleteIpFromProvider(ServerIp $ip)
    {
        try {
            $server = $ip->server;
            $provider = $server ? $server->provider : $ip->provider;

            if ($provider === 'hetzner' && $ip->provider_ip_id) {
                // Floating IP
                if ($ip->is_floating) {
                    Http::withHeaders([
                        'Authorization' => 'Bearer ' . config('services.hetzner.api_token'),
                    ])->delete("https://api.hetzner.cloud/v1/floating_ips/{$ip->provider_ip_id}");
                } else {
                    // Primary IP
                    Http::withHeaders([
                        'Authorization' => 'Bearer ' . config('services.hetzner.api_token'),
                    ])->delete("https://api.hetzner.cloud/v1/primary_ips/{$ip->provider_ip_id}");
                }
            }
        } catch (\Exception $e) {
            Log::error("خطا در حذف IP {$ip->id}: " . $e->getMessage());
        }
    }
}