<?php

namespace App\Http\Controllers\Mentorship;

use App\Http\Controllers\Controller;
use App\Models\Mentorship\Payment;
use App\Models\Mentorship\Application;
use App\Services\Mentorship\PaymentService as MentorshipPaymentService;
use App\Http\Requests\Mentorship\PaymentRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;

class PaymentController extends Controller
{
    protected MentorshipPaymentService $paymentService;

    public function __construct(MentorshipPaymentService $paymentService)
    {
        $this->paymentService = $paymentService;
    }

    /**
     * Display a listing of payments.
     */
    public function index(Request $request)
    {
        $user = auth()->user();

        // Mentors with 'view own mentorship payments' but not full 'view mentorship payments'
        // are redirected to their own payments page
        if (!$user->can('view mentorship payments') && $user->can('view own mentorship payments')) {
            return redirect()->route('mentorship.payments.my-payments');
        }

        abort_unless($user->can('view mentorship payments'), 403);

        $filters = [
            'status' => $request->get('status'),
            'programme_id' => $request->get('programme_id'),
            'user_id' => $request->get('user_id'),
            'search' => $request->get('search'),
            'sort_by' => $request->get('sort_by', 'created_at'),
            'sort_order' => $request->get('sort_order', 'desc'),
        ];

        $payments = $this->paymentService->getPayments($filters);

        return view('mentorship.payments.index', compact('payments', 'filters'));
    }

    /**
     * Show payment initiation form.
     */
    public function create(Request $request)
    {
        $applicationId = $request->get('application_id');
        $application = $applicationId ? Application::with(['programme'])->find($applicationId) : null;

        if (!$application) {
            return redirect()->route('mentorship.public.index')
                ->withErrors(['error' => 'Application not found.']);
        }

        if (!$application->payment_required) {
            return redirect()->route('mentorship.public.status', $application)
                ->withErrors(['error' => 'No payment required for this application.']);
        }

        if ($application->payment_status === 'paid') {
            return redirect()->route('mentorship.public.status', $application)
                ->with('success', 'Payment already completed.');
        }

        return view('mentorship.payments.create', compact('application'));
    }

    /**
     * Initiate payment for an application.
     */
    public function store(PaymentRequest $request)
    {
        $application = Application::findOrFail($request->application_id);

        try {
            $result = $this->paymentService->initiatePayment(
                application: $application,
                phone: $request->input('phone_number', ''),
                paymentMethod: $request->input('payment_method', 'mobile'),
                cardNumber: $request->input('card_number'),
                cardExpiry: $request->input('card_expiry'),
                cardCvv: $request->input('card_cvv'),
            );

            if ($result['success']) {
                return redirect()
                    ->route('mentorship.payments.status', ['payment' => $result['payment_id']])
                    ->with('success', $result['message']);
            }

            return back()
                ->withInput()
                ->withErrors(['payment' => $result['message']]);
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->withErrors(['payment' => $e->getMessage()]);
        }
    }

    /**
     * Display the specified payment.
     */
    public function show(Payment $payment)
    {
        abort_unless(
            auth()->user()->can('view mentorship payments') ||
            $payment->user_id === auth()->id(),
            403
        );

        $payment->load(['application', 'programme', 'user']);

        return view('mentorship.payments.show', compact('payment'));
    }

    /**
     * Show payment status page.
     */
    public function status(Payment $payment)
    {
        $payment->load(['application', 'programme']);

        return view('mentorship.payments.status', compact('payment'));
    }

    /**
     * Check payment status (AJAX).
     */
    public function checkStatus(Payment $payment): JsonResponse
    {
        try {
            $result = $this->paymentService->checkStatus($payment);

            return response()->json($result);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 422);
        }
    }

    /**
     * Handle payment callback from MTN MoMo.
     */
    public function callback(Request $request)
    {
        try {
            $payment = $this->paymentService->handleCallback($request->all());

            Log::info('Payment callback processed', [
                'payment_id' => $payment->id,
                'reference' => $payment->reference,
            ]);

            return response()->json(['success' => true]);
        } catch (\Exception $e) {
            Log::error('Payment callback failed', [
                'error' => $e->getMessage(),
                'data' => $request->all(),
            ]);

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

    /**
     * Retry a failed payment.
     */
    public function retry(Payment $payment)
    {
        try {
            $result = $this->paymentService->retry($payment);

            if ($result['success']) {
                return redirect()
                    ->route('mentorship.payments.status', ['payment' => $result['payment_id']])
                    ->with('success', $result['message']);
            }

            return back()->withErrors(['payment' => $result['message']]);
        } catch (\Exception $e) {
            return back()->withErrors(['payment' => $e->getMessage()]);
        }
    }

    /**
     * Display payment receipt.
     */
    public function receipt(Payment $payment)
    {
        abort_unless(
            auth()->user()->can('view mentorship payments') ||
            auth()->user()->can('view own mentorship payments') && $payment->user_id === auth()->id() ||
            $payment->user_id === auth()->id(),
            403
        );

        if ($payment->status !== Payment::STATUS_SUCCESSFUL) {
            return back()->withErrors(['error' => 'Receipt only available for successful payments.']);
        }

        $receipt = $this->paymentService->generateReceipt($payment);

        return view('mentorship.payments.receipt', compact('payment', 'receipt'));
    }

    /**
     * Get payment statistics.
     */
    public function statistics(Request $request): JsonResponse
    {
        abort_unless(auth()->user()->can('view mentorship payments'), 403);

        $programmeId = $request->get('programme_id');

        $statistics = $this->paymentService->getStatistics($programmeId);

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

    /**
     * My payments (for current user).
     */
    public function myPayments(Request $request)
    {
        $payments = Payment::with(['application', 'programme'])
            ->where('user_id', auth()->id())
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return view('mentorship.payments.my-payments', compact('payments'));
    }
}
