<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessTopUp;
use App\Models\Coupon;
use App\Models\CreditCoupon;
use App\Models\TopUp;
use App\Models\WalletTransaction;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Carbon\Carbon;
    use Stripe\Stripe;
use Stripe\Checkout\Session;
use Illuminate\Support\Facades\DB;

class TopUpController extends Controller
{

    /**
     * Display authenticated user's top-up history.
     */
    public function index(Request $request)
    {
        $user = Auth::user();

        $topUps = TopUp::where('user_id', $user->id)
            ->latest()
            ->paginate(20);

        return response()->json([
            'success' => true,
            'data' => $topUps,
        ]);
    }

    /**
     * Store a new top-up for authenticated user.
     * Supports coupon discount.
     */



public function store(Request $request)
{
    $validated = $request->validate([
        'amount'  => ['required', 'numeric', 'min:10'],
        'phone'   => ['required', 'numeric'],
        'pm_type' => ['required', 'in:wallet,stripe'],
        'coupon'  => ['nullable', 'string'],
    ]);

    $user = Auth::user();

    $amount   = $validated['amount'];
    $discount = 0;


    $coupon = null;
    if (! empty($validated['coupon'])) {
        $now = Carbon::now();

        $coupon = CreditCoupon::where('code', $validated['coupon'])
            ->where('is_active', true)
            ->where(function ($q) use ($now) {
                $q->whereNull('valid_from')->orWhere('valid_from', '<=', $now);
            })
            ->where(function ($q) use ($now) {
                $q->whereNull('valid_to')->orWhere('valid_to', '>=', $now);
            })
            ->first();

        if ($coupon) {
            $discount = $coupon->amount ?? 0;
        }
    }

    $finalAmount = max(0, round($amount - $discount, 2));

    $topUp = DB::transaction(function () use ($validated, $user, $finalAmount, $coupon) {

        $topUp = TopUp::create([
            'amount'   => $finalAmount,
            'phone'    => $validated['phone'],
            'pm_type'  => $validated['pm_type'],
            'status'   => 'pending',
            'is_paid'  => false,
            'user_id'  => $user->id,
        ]);

        // If coupon covers full amount, complete top-up immediately
        if ($finalAmount <= 0) {
            $topUp->update([
                'status'  => 'completed',
                'is_paid' => true,
            ]);

            if ($coupon) {
                $coupon->user_id = $user->id;
                $coupon->is_active = false;
                $coupon->save();
            }

            ProcessTopUp::dispatchSync($topUp);

            return $topUp;
        }

        // --------------------------------
        // WALLET PAYMENT
        // --------------------------------
        if ($validated['pm_type'] === 'wallet') {

            $wallet = $user->wallet;

            if (! $wallet || ! $wallet->is_active) {
                throw new \Exception('Wallet is not available.');
            }

            if ($wallet->balance < $finalAmount) {
                return $topUp;
            }

            WalletTransaction::create([
                'pm_type'   => 'wallet',
                'type'      => 'debit',
                'status'    => 'completed',
                'amount'    => $finalAmount,
                'wallet_id' => $wallet->id,
                'user_id'   => $user->id,
            ]);

            $topUp->update([
                'status'  => 'completed',
                'is_paid' => true,
            ]);

            if ($coupon) {
                $coupon->user_id = $user->id;
                $coupon->is_active = false;
                $coupon->save();
            }

            ProcessTopUp::dispatchSync($topUp);
        }

        return $topUp;
    });

    /**
     * --------------------------------
     * STRIPE CHECKOUT
     * --------------------------------
     */
    if ($validated['pm_type'] === 'stripe') {

        Stripe::setApiKey(config('services.stripe.secret'));

        // If top-up already paid (coupon covered or processed), return immediate response
        if ($topUp->is_paid || $finalAmount <= 0) {
            return response()->json([
                'success' => true,
                'message' => 'Top-up completed. No payment needed.',
                'data' => $topUp,
            ]);
        }

        $session = Session::create([
            'mode' => 'payment',
            'payment_method_types' => ['card'],
            'line_items' => [[
                'price_data' => [
                    'currency' => 'usd',
                    'unit_amount' => (int) round($finalAmount * 100),
                    'product_data' => [
                        'name' => 'Mobile Top-Up',
                    ],
                ],
                'quantity' => 1,
            ]],
            'success_url' => route('stripe.topup.success') . '?session_id={CHECKOUT_SESSION_ID}',
            'cancel_url'  => route('stripe.topup.cancel'),
            'metadata' => [
                'topup_id' => $topUp->id,
                'user_id'  => $user->id,
                'amount'   => $finalAmount,
                'coupon_code' => $coupon ? $coupon->code : null,
            ],
        ]);

        return response()->json([
            'success' => true,
            'checkout_url' => $session->url,
        ]);
    }

    return response()->json([
        'success'         => true,
        'message'         => $topUp->is_paid
            ? 'Top-up completed using wallet.'
            : 'Top-up created. Awaiting payment.',
        'original_amount' => $amount,
        'discount'        => $discount,
        'final_amount'    => $finalAmount,
        'wallet_balance'  => optional($user->wallet)->balance,
        'data'            => $topUp,
    ], 201);
}
public function success(Request $request)
{
    $sessionId = $request->query('session_id');

    abort_if(! $sessionId, 400, 'Missing session ID');

    Stripe::setApiKey(config('services.stripe.secret'));

    $session = Session::retrieve($sessionId);

    abort_if($session->payment_status !== 'paid', 400, 'Payment not completed');

    $topUpId = $session->metadata->topup_id ?? null;

    abort_if(! $topUpId, 400, 'Missing top-up metadata');

    $topUp = TopUp::where('id', $topUpId)
        ->where('status', 'pending')
        ->firstOrFail();

    $topUp->update([
        'status'  => 'completed',
        'is_paid' => true,
    ]);

    // If Stripe metadata contained a coupon code, mark that coupon as used
    $couponCode = $session->metadata->coupon_code ?? null;
    if ($couponCode) {
        $creditCoupon = CreditCoupon::where('code', $couponCode)
            ->where('is_active', true)
            ->first();

        if ($creditCoupon) {
            $creditCoupon->user_id = $topUp->user_id;
            $creditCoupon->is_active = false;
            $creditCoupon->save();
        }
    }

    ProcessTopUp::dispatch($topUp);

    return redirect()->route('topup.success');
}

}
