<?php

namespace App\Http\Controllers\Member;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Wallet;
use App\Models\WalletTransaction;
use App\Models\Withdrawal;
use App\Services\WalletService;
use App\Services\NotificationService;
use App\Models\Setting;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class WalletController extends Controller
{
    protected WalletService $walletService;

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

    public function index(Request $request)
    {
        $user = auth()->user();
        $wallet = $this->walletService->getOrCreateWallet($user);

        $query = WalletTransaction::where('wallet_id', $wallet->id);

        // Filtres
        if ($request->filled('type')) {
            $type = $request->string('type')->lower();
            if ($type === 'credit') {
                $query->where('amount', '>', 0);
            } elseif ($type === 'debit') {
                $query->where('amount', '<', 0);
            }
        }

        if ($request->filled('status')) {
            $query->where('status', $request->input('status'));
        }

        if ($request->filled('from')) {
            $query->whereDate('created_at', '>=', $request->input('from'));
        }

        if ($request->filled('to')) {
            $query->whereDate('created_at', '<=', $request->input('to'));
        }

        if ($request->filled('q')) {
            $search = $request->input('q');
            $query->where(function ($q) use ($search) {
                $q->where('description', 'like', "%{$search}%")
                    ->orWhere('reference', 'like', "%{$search}%")
                    ->orWhere('type', 'like', "%{$search}%");
            });
        }

        $query->orderBy('created_at', 'desc');

        // Export
        if ($request->input('export') === 'csv') {
            $rows = $query->get();
            return response()->streamDownload(function () use ($rows) {
                $out = fopen('php://output', 'w');
                fputcsv($out, ['Date', 'Type', 'Description', 'Montant', 'Statut']);
                foreach ($rows as $tx) {
                    fputcsv($out, [
                        optional($tx->created_at)->format('d/m/Y H:i'),
                        $tx->amount > 0 ? 'Crédit' : 'Débit',
                        $tx->description,
                        $tx->amount,
                        $tx->status,
                    ]);
                }
                fclose($out);
            }, 'transactions_wallet.csv', ['Content-Type' => 'text/csv']);
        }

        if ($request->input('export') === 'pdf') {
            $rows = $query->get();
            $html = view('exports.wallet-transactions', compact('rows', 'wallet'))->render();
            return response($html)
                ->header('Content-Type', 'text/html')
                ->header('Content-Disposition', 'attachment; filename="transactions_wallet.html"');
        }

        $transactions = $query->paginate(20);

        // Statistiques
        $since = Carbon::now()->subDays(30);
        $incomesLast30 = WalletTransaction::where('wallet_id', $wallet->id)
            ->where('created_at', '>=', $since)
            ->where('amount', '>', 0)
            ->sum('amount') ?? 0;

        $outcomesLast30 = WalletTransaction::where('wallet_id', $wallet->id)
            ->where('created_at', '>=', $since)
            ->where('amount', '<', 0)
            ->sum(DB::raw('ABS(amount)')) ?? 0;
        
        return view('member.wallet.index', compact('wallet', 'transactions', 'incomesLast30', 'outcomesLast30'));
    }

    public function withdrawals(Request $request)
    {
        $user = auth()->user();
        $wallet = $this->walletService->getOrCreateWallet($user);

        $query = Withdrawal::where('user_id', $user->id);

        if ($request->filled('status')) {
            $query->where('status', $request->input('status'));
        }
        if ($request->filled('from')) {
            $query->whereDate('created_at', '>=', $request->input('from'));
        }
        if ($request->filled('to')) {
            $query->whereDate('created_at', '<=', $request->input('to'));
        }
        if ($request->filled('q')) {
            $search = $request->input('q');
            $query->where(function ($q) use ($search) {
                $q->where('reference', 'like', "%{$search}%")
                    ->orWhere('payment_method', 'like', "%{$search}%")
                    ->orWhere('payment_details', 'like', "%{$search}%");
            });
        }

        $query->orderBy('created_at', 'desc');

        if ($request->input('export') === 'csv') {
            $rows = $query->get();
            return response()->streamDownload(function () use ($rows) {
                $out = fopen('php://output', 'w');
                fputcsv($out, ['Date', 'Référence', 'Montant', 'Frais', 'Net', 'Statut']);
                foreach ($rows as $wd) {
                    fputcsv($out, [
                        optional($wd->created_at)->format('d/m/Y H:i'),
                        $wd->reference,
                        $wd->amount,
                        $wd->fee,
                        $wd->net_amount,
                        $wd->status,
                    ]);
                }
                fclose($out);
            }, 'retraits.csv', ['Content-Type' => 'text/csv']);
        }

        if ($request->input('export') === 'pdf') {
            $rows = $query->get();
            $html = view('exports.withdrawals', compact('rows', 'wallet'))->render();
            return response($html)
                ->header('Content-Type', 'text/html')
                ->header('Content-Disposition', 'attachment; filename="retraits.html"');
        }
        
        $withdrawals = $query->paginate(20);
        
        return view('member.wallet.withdrawals', compact('wallet', 'withdrawals'));
    }

    public function requestWithdrawal(Request $request)
    {
        $minWithdrawal = floatval(Setting::get('min_withdrawal_amount', 5000));

        $allowed = config('payment.withdrawal_methods', []);
        $request->validate([
            'amount' => 'required|numeric|min:' . $minWithdrawal,
            'payment_method' => 'required|in:' . implode(',', $allowed),
            'payment_details' => 'required|string',
        ]);

        $user = auth()->user();

        try {
            $detailsKey = config('payment.withdrawal_details_map.' . $request->payment_method, 'input');
            $details = [ $detailsKey => trim($request->payment_details) ];

            $this->walletService->requestWithdrawal(
                $user,
                $request->amount,
                $request->payment_method,
                $details
            );

            // Notification de demande de retrait
            NotificationService::withdrawalCreated($user->id, $request->amount);

            return back()->with('success', 'Demande de retrait soumise');
        } catch (\Throwable $e) {
            return back()->with('error', $e->getMessage());
        }
    }
}
