<?php

namespace App\Http\Controllers\Member;

use App\Http\Controllers\Controller;
use App\Services\SavingsWalletService;
use App\Services\LockedSavingsService;
use App\Services\WalletService;
use App\Services\NotificationService;
use App\Models\SavingsPlan;
use App\Models\SavingsLock;
use App\Models\WalletTransfer;
use App\Models\WalletTransaction;
use App\Models\UnlockRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class SavingsController extends Controller
{
    protected $savingsService;
    protected $lockedSavingsService;
    protected $walletService;

    public function __construct(
        SavingsWalletService $savingsService,
        LockedSavingsService $lockedSavingsService,
        WalletService $walletService
    ) {
        $this->savingsService = $savingsService;
        $this->lockedSavingsService = $lockedSavingsService;
        $this->walletService = $walletService;
    }

    /**
     * Dashboard épargne
     */
    public function index()
    {
        $user = Auth::user();
        
        $wallet = $this->walletService->getOrCreateWallet($user);
        $savingsWallet = $this->savingsService->getOrCreateSavingsWallet($user);
        $plans = SavingsPlan::active()->get();
        
        // Blocages actifs (épargnes bloquées indépendantes)
        $activeLocks = $this->lockedSavingsService->getActiveLocks($user);
        $totalLockedAmount = $this->lockedSavingsService->getTotalLockedAmount($user);
        $totalPendingInterest = $this->lockedSavingsService->getTotalPendingInterest($user);
        
        // Historique des transferts (20 derniers)
        $transfers = WalletTransfer::where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->take(20)
            ->get();

        // Demandes de déblocage
        $unlockRequests = UnlockRequest::where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->take(10)
            ->get();

        return view('member.savings.index', compact(
            'wallet',
            'savingsWallet',
            'plans',
            'activeLocks',
            'totalLockedAmount',
            'totalPendingInterest',
            'transfers',
            'unlockRequests'
        ));
    }

    /**
     * Transférer vers épargne BLOQUÉE
     */
    public function transferToSavings(Request $request)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1000'
        ]);

        try {
            $user = Auth::user();
            
            // Simple transfert vers wallet épargne SANS blocage
            $transfer = $this->savingsService->transferToSavings($user, $request->amount, null);

            // Notification de transfert vers épargne
            NotificationService::walletTransfer($user->id, 'savings_deposit', $request->amount, 'Transfert vers épargne');

            return response()->json([
                'success' => true,
                'message' => 'Transfert vers épargne effectué avec succès !',
                'transfer' => $transfer
            ]);

        } catch (\Exception $e) {
            Log::error('Transfer to savings failed', [
                'error' => $e->getMessage(),
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Créer une épargne bloquée via un plan
     */
    public function createLockedSavings(Request $request)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1000',
            'lock_duration' => 'required|in:1,3,6,12'
        ]);

        try {
            $user = Auth::user();

            $lock = $this->lockedSavingsService->createLock(
                $user,
                $request->amount,
                (int) $request->lock_duration
            );

            // Notification d'épargne bloquée
            NotificationService::savingsLocked(
                $user->id,
                $request->amount,
                $lock->unlock_at?->format('d/m/Y')
            );

            return response()->json([
                'success' => true,
                'message' => 'Épargne bloquée créée avec succès !',
                'lock' => $lock,
                'unlock_date' => $lock->unlock_at?->format('d/m/Y H:i')
            ]);

        } catch (\Exception $e) {
            Log::error('Create locked savings failed', [
                'error' => $e->getMessage(),
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Transférer depuis épargne (non bloquée)
     */
    public function transferFromSavings(Request $request)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1000'
        ]);

        try {
            $user = Auth::user();
            $transfer = $this->savingsService->transferFromSavings($user, $request->amount);

            // Notification de déblocage d'épargne
            NotificationService::savingsUnlocked($user->id, $request->amount);

            return response()->json([
                'success' => true,
                'message' => 'Transfert vers wallet principal effectué avec succès !',
                'transfer' => $transfer
            ]);

        } catch (\Exception $e) {
            Log::error('Transfer from savings failed', [
                'error' => $e->getMessage(),
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Bloquer le wallet épargne (quand débloqué)
     */
    public function lockSavingsWallet(Request $request)
    {
        $request->validate([
            'lock_duration' => 'required|in:1,3,6,12'
        ]);

        try {
            $user = Auth::user();
            $savingsWallet = $this->savingsService->getOrCreateSavingsWallet($user);

            // Bloquer le wallet épargne
            $this->savingsService->lockWallet($user, (int) $request->lock_duration);  // Cast en integer

            // Notification de blocage de fonds
            $durationText = $request->lock_duration . ' mois';
            $endDate = now()->addMonths((int) $request->lock_duration)->format('d/m/Y');
            NotificationService::fundsLocked($user->id, $savingsWallet->balance ?? 0, $durationText, $endDate);

            return response()->json([
                'success' => true,
                'message' => 'Wallet épargne bloqué avec succès !',
                'redirect' => route('member.savings.index')
            ]);

        } catch (\Exception $e) {
            Log::error('Lock savings wallet failed', [
                'error' => $e->getMessage(),
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Déblocage anticipé d'une épargne bloquée
     */
    public function earlyUnlock(Request $request)
    {
        $request->validate([
            'lock_id' => 'required|exists:savings_locks,id'
        ]);

        try {
            $user = Auth::user();
            $lock = SavingsLock::findOrFail($request->lock_id);
            
            if ($lock->user_id !== $user->id) {
                return response()->json([
                    'success' => false,
                    'message' => 'Non autorisé'
                ], 403);
            }

            $lock = $this->lockedSavingsService->earlyUnlock($user, $lock);

            // Notification de déblocage anticipé
            NotificationService::savingsUnlocked($user->id, $lock->amount);

            return response()->json([
                'success' => true,
                'message' => 'Déblocage anticipé effectué. Votre capital initial a été retourné (intérêts perdus).',
                'lock' => $lock
            ]);

        } catch (\Exception $e) {
            Log::error('Early unlock failed', [
                'error' => $e->getMessage(),
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Demander un déblocage d'urgence (l'ancien système)
     */
    public function requestUnlock(Request $request)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1000',
            'reason' => 'required|string|min:20|max:500'
        ]);

        try {
            $user = Auth::user();
            $unlockRequest = $this->savingsService->requestEmergencyUnlock(
                $user,
                $request->amount,
                $request->reason
            );

            return response()->json([
                'success' => true,
                'message' => 'Demande de déblocage envoyée avec succès. Un administrateur la traitera sous peu.',
                'unlock_request' => $unlockRequest
            ]);

        } catch (\Exception $e) {
            Log::error('Unlock request failed', [
                'error' => $e->getMessage(),
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Historique des transferts avec recherche avancée
     */
    public function transfers(Request $request)
    {
        $user = Auth::user();
        
        // Query de base pour WalletTransfer
        $transfersQuery = WalletTransfer::where('user_id', $user->id);
        
        // Query de base pour WalletTransaction
        $transactionsQuery = WalletTransaction::where('user_id', $user->id);
        
        // Filtres de recherche
        if ($request->filled('direction')) {
            $transfersQuery->where(function($q) use ($request) {
                if ($request->direction === 'to_savings') {
                    $q->where('from_wallet_type', 'main')->where('to_wallet_type', 'savings');
                } else {
                    $q->where('from_wallet_type', 'savings')->where('to_wallet_type', 'main');
                }
            });
        }
        
        if ($request->filled('status')) {
            $transfersQuery->where('status', $request->status);
            $transactionsQuery->where('status', $request->status);
        }
        
        if ($request->filled('type')) {
            $transactionsQuery->where('type', $request->type);
        }
        
        if ($request->filled('from')) {
            $fromDate = \Carbon\Carbon::parse($request->from)->startOfDay();
            $transfersQuery->where('created_at', '>=', $fromDate);
            $transactionsQuery->where('created_at', '>=', $fromDate);
        }
        
        if ($request->filled('to')) {
            $toDate = \Carbon\Carbon::parse($request->to)->endOfDay();
            $transfersQuery->where('created_at', '<=', $toDate);
            $transactionsQuery->where('created_at', '<=', $toDate);
        }
        
        if ($request->filled('search')) {
            $search = $request->search;
            $transfersQuery->where(function($q) use ($search) {
                $q->where('reference', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%")
                  ->orWhere('amount', 'like', "%{$search}%");
            });
            
            $transactionsQuery->where(function($q) use ($search) {
                $q->where('reference', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%")
                  ->orWhere('amount', 'like', "%{$search}%");
            });
        }
        
        // Récupérer les transferts
        $transfers = $transfersQuery->orderBy('created_at', 'desc')->paginate(15, ['*'], 'transfers');
        
        // Récupérer toutes les transactions du wallet (sans pagination pour stats)
        $allTransactions = $transactionsQuery->get();
        
        // Récupérer les blocages d'épargne
        $locks = SavingsLock::where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->limit(10)
            ->get();
        
        // Statistiques
        $stats = [
            'total_transferred' => $transfers->sum('amount'),
            'total_fees' => $transfers->sum('fee'),
            'total_credits' => $allTransactions->where('amount', '>', 0)->sum('amount'),
            'total_debits' => abs($allTransactions->where('amount', '<', 0)->sum('amount')),
            'transfers_count' => $transfers->total(),
            'transactions_count' => $allTransactions->count()
        ];
        
        return view('member.savings.transfers', compact('transfers', 'locks', 'stats'));
    }
}
