<?php

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class WalletService
{
    /**
     * Supported wallet types
     */
    const WALLET_TYPES = [
        'metamask',
        'coinbase',
        'trust',
        'okx',
        'imtoken',
        'onchain',
        'defi'
    ];

    /**
     * Connect wallet and create/update user session
     */
    public function connect(string $walletAddress, string $walletType, ?string $inviteCode = null): array
    {
        try {
            $isNewUser = false;
            
            // Find or create user by wallet address (unique per address; DB has unique on wallet_address)
            $user = User::firstOrCreate(
                ['wallet_address' => strtolower($walletAddress)],
                [
                    'name' => 'User ' . substr($walletAddress, 0, 8),
                    'email' => $walletAddress . '@wallet.local',
                    'password' => bcrypt(Str::random(32)), // Random password for wallet users
                    'wallet_type' => $walletType,
                    'balance' => 0,
                    'locked_balance' => 0,
                    'account_weight_score' => '0.00',
                    'authorization_quota' => '0',
                    'available_quota' => '0',
                    'invite_code' => $this->generateInviteCode(),
                    'is_active' => true,
                    'is_verified' => false,
                ]
            );
            
            $isNewUser = $user->wasRecentlyCreated;

            if ($isNewUser) {
                \App\Services\NotificationService::createWelcome($user);
            }

            // Handle referral if invite_code provided and user is new
            if ($inviteCode && $isNewUser && !$user->referred_by) {
                $referrer = User::where('invite_code', strtoupper($inviteCode))->first();
                
                if ($referrer && $referrer->id !== $user->id) {
                    $user->update(['referred_by' => $referrer->id]);
                    
                    // Create referral records for multi-level commission (Level 1, 2, 3)
                    $this->createReferralRecords($user, $referrer);
                }
            }

            // Update wallet type if changed
            if ($user->wallet_type !== $walletType) {
                $user->update(['wallet_type' => $walletType]);
            }

            // Update last login
            $user->update(['last_login_at' => now()]);

            return [
                'success' => true,
                'user' => $user,
                'message' => 'Wallet connected successfully'
            ];
        } catch (\Exception $e) {
            Log::error('Wallet connect error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Failed to connect wallet'
            ];
        }
    }
    
    /**
     * Create multi-level referral records
     */
    private function createReferralRecords(User $newUser, User $referrer): void
    {
        $currentReferrer = $referrer;
        $level = 1;
        
        while ($currentReferrer && $level <= 3) {
            // Calculate commission percent based on referrer's account weight score
            $commissionPercent = $this->calculateCommissionPercent($currentReferrer->account_weight_score, $level);
            
            \App\Models\Referral::create([
                'user_id' => $currentReferrer->id,
                'referred_user_id' => $newUser->id,
                'level' => $level,
                'commission_percent' => $commissionPercent,
                'total_earnings' => 0,
                'withdrawable' => 0,
            ]);
            
            // Move to next level (referrer's referrer)
            if ($currentReferrer->referred_by) {
                $currentReferrer = User::find($currentReferrer->referred_by);
                $level++;
            } else {
                break;
            }
        }
    }
    
    /**
     * Calculate commission percent based on account weight score and level
     * Based on invitation rules: Level 1 (3%), Level 2 (2%), Level 3 (1%)
     */
    private function calculateCommissionPercent(float $accountWeightScore, int $level): float
    {
        $baseCommission = [1 => 3.0, 2 => 2.0, 3 => 1.0];
        $basePercent = $baseCommission[$level] ?? 0;
        
        // Account weight score affects base commission
        // Higher score = higher commission potential
        // For now, return base commission based on level
        // Can be enhanced later based on account_weight_score thresholds
        
        return $basePercent;
    }

    /**
     * Disconnect wallet (clear session)
     */
    public function disconnect(): array
    {
        return [
            'success' => true,
            'message' => 'Wallet disconnected'
        ];
    }

    /**
     * Generate unique invite code
     */
    private function generateInviteCode(): string
    {
        do {
            $code = strtoupper(substr(md5(uniqid(rand(), true)), 0, 10));
        } while (User::where('invite_code', $code)->exists());

        return $code;
    }

    /**
     * Check if wallet is connected
     */
    public function isConnected(?string $walletAddress): bool
    {
        if (!$walletAddress) {
            return false;
        }

        return User::where('wallet_address', strtolower($walletAddress))
            ->where('is_active', true)
            ->exists();
    }

    /**
     * Auto-reconnect logic (5 second window)
     */
    public function attemptReconnect(string $walletAddress, string $walletType): ?User
    {
        $user = User::where('wallet_address', strtolower($walletAddress))
            ->where('is_active', true)
            ->first();

        if ($user) {
            $user->update([
                'wallet_type' => $walletType,
                'last_login_at' => now()
            ]);
            return $user;
        }

        return null;
    }
}

