<?php

namespace App\Observers;

use App\Models\Commission;
use App\Models\PointsLog;
use App\Models\Ticket;
use App\Models\Transaction;
use App\Models\VipLevel;
use App\Services\FcmService;

class TransactionObserver
{
    /**
     * Handle the Transaction "created" event.
     */
    public function created(Transaction $transaction): void
    {
        // Al crear un retiro, congelamos/descontamos el saldo inmediatamente de la wallet del usuario
        if ($transaction->type === 'withdrawal' && $transaction->status === 'pending') {
            $transaction->user->decrement('wallet_balance', $transaction->amount);

            // Enviar Push al usuario
            FcmService::sendNotification(
                $transaction->user,
                'Retiro Registrado',
                'Tu solicitud de retiro por ₡'.number_format($transaction->amount).' ha sido registrada con éxito.'
            );
        }
    }

    /**
     * Handle the Transaction "updated" event.
     */
    public function updated(Transaction $transaction): void
    {
        // Solo actuar si el estado cambia a 'approved' (Aprobado)
        if ($transaction->wasChanged('status') && $transaction->status === 'approved') {
            $user = $transaction->user;

            // CASO A: Depósito de dinero a la Wallet
            if ($transaction->type === 'deposit') {
                $user->increment('wallet_balance', $transaction->amount);

                // Enviar Push
                FcmService::sendNotification(
                    $user,
                    '¡Billetera Recargada!',
                    'Se han acreditado ₡'.number_format($transaction->amount).' a tu billetera.'
                );
            }

            // CASO B: Compra de tarjetas coleccionables
            if ($transaction->type === 'purchase') {
                $raffle = $transaction->raffle;
                $raffleTitle = $raffle?->title ?? 'Sorteo';
                $quantity = $transaction->quantity ?? 1;

                // Emitir las tarjetas: sortea rarezas y acredita llaves según rareza
                $cards = app(\App\Services\CardShopService::class)->fulfill($transaction);

                // Enviar Push al usuario sobre la compra.
                // Pagos verificados por el admin (SINPE/transferencia): las tarjetas
                // quedan pendientes de revelar en la app.
                if (in_array($transaction->payment_method, ['sinpe', 'transfer'], true)) {
                    FcmService::sendNotification(
                        $user,
                        '¡Pago Aprobado! 🎉',
                        'Tu compra del sorteo \'' . $raffleTitle . '\' fue verificada. Tienes ' . count($cards) . ' tarjeta(s) esperando ser reveladas en Mi Álbum 🎴✨'
                    );
                } else {
                    $keysEarned = array_sum(array_map(fn ($card) => $card->keys_granted, $cards));
                    $keysText = $keysEarned > 0 ? " y ganaste $keysEarned llave(s) para abrir cofres 🔑" : '';
                    FcmService::sendNotification(
                        $user,
                        '¡Compra Confirmada!',
                        'Tus ' . count($cards) . " tarjetas del sorteo '$raffleTitle' ya están en tu álbum 🎴$keysText"
                    );
                }

                // 2. Sumar Puntos de Fidelidad (₡1.000 = 1 punto)
                $pointsToAward = floor($transaction->amount / 1000);
                if ($pointsToAward > 0) {
                    $multiplier = 1.00;

                    // Aplicar multiplicador del Nivel VIP si el usuario lo posee
                    if ($user->vipLevel) {
                        $multiplier = (float) $user->vipLevel->bonus_multiplier;
                    }

                    $finalPoints = (int) round($pointsToAward * $multiplier);
                    $user->increment('points_balance', $finalPoints);

                    // Guardar log de puntos
                    PointsLog::create([
                        'user_id' => $user->id,
                        'points' => $finalPoints,
                        'action_type' => 'purchase_reward',
                        'description' => 'Puntos acumulados por compra de llaves (Sorteo: ' . $raffleTitle . ')',
                    ]);
                }

                // 3. Recalcular Nivel VIP del Usuario de forma dinámica
                $totalSoldKeysCount = Transaction::where('user_id', $user->id)
                    ->where('type', 'purchase')
                    ->where('status', 'approved')
                    ->sum('quantity');

                // Buscar nivel VIP correspondiente
                $matchingVipLevel = VipLevel::where('min_tickets', '<=', $totalSoldKeysCount)
                    ->orderBy('min_tickets', 'desc')
                    ->first();

                if ($matchingVipLevel && $user->vip_level_id !== $matchingVipLevel->id) {
                    $user->update(['vip_level_id' => $matchingVipLevel->id]);
                }

                // 4. Lógica de Comisión para el Revendedor
                if ($transaction->reseller_id) {
                    $reseller = $transaction->reseller;

                    if ($reseller) {
                        // Comisión: 10% efectivo / 15% crédito
                        $preference = $reseller->commission_preference;
                        $rate = $preference === 'cash' ? 0.10 : 0.15;
                        $commissionAmount = $transaction->amount * $rate;

                        // Registrar comisión generada
                        Commission::create([
                            'reseller_profile_id' => $reseller->id,
                            'transaction_id' => $transaction->id,
                            'amount' => $commissionAmount,
                            'payout_type' => $preference,
                            'status' => 'paid',
                        ]);

                        // Acreditar saldo de la comisión a la wallet del dueño del perfil
                        $resellerUser = $reseller->user;
                        if ($resellerUser) {
                            $resellerUser->increment('wallet_balance', $commissionAmount);

                            // Registrar la transacción de cobro de comisión
                            Transaction::create([
                                'user_id' => $resellerUser->id,
                                'amount' => $commissionAmount,
                                'type' => 'commission_payout',
                                'payment_method' => 'wallet',
                                'payment_reference' => "COMISIÓN-LLAVES-{$transaction->raffle_id}",
                                'status' => 'approved',
                            ]);

                            // Enviar Push al revendedor
                            $payoutTypeText = $preference === 'cash' ? 'efectivo' : 'crédito';
                            FcmService::sendNotification(
                                $resellerUser,
                                '¡Nueva Comisión Ganada!',
                                'Ganaste ₡' . number_format($commissionAmount) . " en $payoutTypeText por ventas de llaves del sorteo '$raffleTitle'."
                            );
                        }

                        // Actualizar estadísticas del revendedor
                        $reseller->increment('total_sales_count', $quantity);
                        $reseller->increment('total_commissions_earned', $commissionAmount);
                    }
                }

                // 5. Lógica de Afiliados Nivel 1 (10% de comisión directa al patrocinador)
                if ($user->referred_by_id) {
                    $sponsor = $user->referredBy;
                    if ($sponsor) {
                        $affiliateCommission = $transaction->amount * 0.10;
                        $sponsor->increment('wallet_balance', $affiliateCommission);

                        // Registrar la transacción de comisión de afiliado
                        Transaction::create([
                            'user_id' => $sponsor->id,
                            'amount' => $affiliateCommission,
                            'type' => 'commission_payout',
                            'payment_method' => 'wallet',
                            'payment_reference' => "AFILIADO-NIVEL1-COMPRA-{$user->id}",
                            'status' => 'approved',
                        ]);

                        // Enviar Push al patrocinador
                        FcmService::sendNotification(
                            $sponsor,
                            '¡Comisión de Afiliado!',
                            'Ganaste ₡' . number_format($affiliateCommission) . " por la compra de tu referido {$user->name}."
                        );
                    }
                }
            }

            // CASO C: Retiro aprobado
            if ($transaction->type === 'withdrawal') {
                FcmService::sendNotification(
                    $user,
                    'Retiro Procesado',
                    'Tu transferencia bancaria por ₡'.number_format($transaction->amount).' ha sido aprobada y enviada.'
                );
            }
        }

        // Si la transacción cambia a 'rejected' (Rechazada) y era un Retiro
        // devolvemos el saldo congelado al balance de la Wallet del usuario
        if ($transaction->wasChanged('status') && $transaction->status === 'rejected') {
            if ($transaction->type === 'withdrawal') {
                $transaction->user->increment('wallet_balance', $transaction->amount);

                // Enviar Push
                FcmService::sendNotification(
                    $transaction->user,
                    'Retiro Rechazado',
                    'Tu solicitud de retiro por ₡'.number_format($transaction->amount).' fue rechazada y los fondos fueron devueltos.'
                );
            }

            if ($transaction->type === 'purchase') {
                // Enviar Push
                FcmService::sendNotification(
                    $transaction->user,
                    'Compra Rechazada',
                    'Tu pago para el sorteo no pudo ser verificado. Por favor contacta a soporte.'
                );
            }
        }
    }

    /**
     * Handle the Transaction "deleted" event.
     */
    public function deleted(Transaction $transaction): void
    {
        //
    }

    /**
     * Handle the Transaction "restored" event.
     */
    public function restored(Transaction $transaction): void
    {
        //
    }

    /**
     * Handle the Transaction "force deleted" event.
     */
    public function forceDeleted(Transaction $transaction): void
    {
        //
    }
}
