<?php

namespace App\Http\Controllers\SelfPaced\Learner;

use App\Http\Requests\SelfPaced\StorePaymentProofRequest;
use App\Http\Controllers\Controller;
use App\Models\SelfPaced\Course;
use App\Models\SelfPaced\BookPurchase;
use App\Services\PaystackService;
use App\Services\PaymentProofService;
use App\Services\BookService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;

/**
 * BookController (Learner)
 *
 * Handles course book purchases and downloads.
 *
 * Requirements: 9.6, 9.7, 9.8, 9.9, 9.10, 9.11
 */
class BookController extends Controller
{
    public function __construct(
        protected PaystackService $paystackService,
        protected PaymentProofService $proofService,
        protected BookService $bookService
    ) {
        $this->middleware('auth');
    }

    /**
     * Initialize book purchase payment
     *
     * @param Request $request
     * @param Course $course
     * @return JsonResponse
     */
    public function initPurchase(Request $request, Course $course): JsonResponse
    {
        if (!$course->hasBook()) {
            return response()->json(['error' => 'Book not available'], 404);
        }

        // For cash payment
        if ($request->input('method') === 'cash') {
            return response()->json(['method' => 'cash']);
        }

        // For Paystack
        $reference = $this->paystackService->generateReference('SP-BOOK-');
        $config = \App\Models\SelfPaced\PaystackConfig::getActive();

        if (!$config) {
            return response()->json(['error' => 'Paystack not configured'], 500);
        }

        $inlineConfig = $this->paystackService->buildInlineConfig(
            publicKey: $config->public_key,
            email: auth()->user()->email,
            amount: (float)$course->book_fee,
            reference: $reference,
            currency: 'KES',
            metadata: [
                'course_id' => $course->id,
                'fee_type' => 'book',
                'user_id' => auth()->id(),
            ]
        );

        return response()->json($inlineConfig);
    }

    /**
     * Verify book purchase payment
     *
     * @param Request $request
     * @param Course $course
     * @return JsonResponse
     */
    public function verifyPurchase(Request $request, Course $course): JsonResponse
    {
        if (!$course->hasBook()) {
            return response()->json(['error' => 'Book not available'], 404);
        }

        $reference = $request->input('reference');
        $config = \App\Models\SelfPaced\PaystackConfig::getActive();

        if (!$config) {
            return response()->json(['error' => 'Payment system error'], 500);
        }

        // Verify with Paystack
        $result = $this->paystackService->verifyTransaction(
            $reference,
            $config->secret_key
        );

        if ($result['status'] !== 'success') {
            return response()->json(['error' => 'Payment verification failed'], 400);
        }

        // Record purchase and generate download URL
        $result = $this->bookService->recordPurchaseAndGenerateUrl(
            $course,
            auth()->user()->email,
            $reference,
            $course->book_fee,
            'KES',
            auth()->id()
        );

        // Send download email
        $this->bookService->dispatchDownloadEmail(
            $result['purchase'],
            $result['downloadUrl']
        );

        return response()->json([
            'success' => true,
            'download_url' => $result['downloadUrl'],
        ]);
    }

    /**
     * Submit cash payment proof for book
     *
     * @param StorePaymentProofRequest $request
     * @param Course $course
     * @return RedirectResponse
     */
    public function submitProof(StorePaymentProofRequest $request, Course $course): RedirectResponse
    {
        if (!$course->hasBook()) {
            return redirect()->back()->with('error', 'Book not available');
        }

        // Get or create enrollment
        $enrollment = auth()->user()->enrollments()
            ->where('course_id', $course->id)
            ->first();

        if (!$enrollment) {
            // For book purchase, we don't require enrollment
            // Just store the proof with user_id
            try {
                // Create a temporary enrollment-like structure
                // or handle differently for non-enrolled purchases
                return redirect()->back()->with('error', 'Please enroll in the course first');
            } catch (\Exception $e) {
                return redirect()->back()->with('error', $e->getMessage());
            }
        }

        try {
            $proof = $this->proofService->storeProof(
                $enrollment,
                $request->file('file'),
                $request->input('proof_type'),
                'book',
                $course->book_fee,
                'KES'
            );

            return redirect()->back()->with('success', 'Book payment proof submitted for verification');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', $e->getMessage());
        }
    }

    /**
     * Download book with signed URL
     *
     * @param Request $request
     * @param Course $course
     * @param BookPurchase $purchase
     * @return StreamedResponse
     */
    public function download(Request $request, Course $course, BookPurchase $purchase): StreamedResponse
    {
        // Validate purchase belongs to course
        if ($purchase->course_id !== $course->id) {
            abort(403, 'Purchase does not match course');
        }

        // Record download
        $purchase->recordDownload();

        // Stream book
        return $this->bookService->streamBook($course);
    }

    /**
     * Download book via signed URL (used in email links)
     * 
     * @param BookPurchase $bookPurchase
     * @return StreamedResponse
     */
    public function downloadSigned(BookPurchase $bookPurchase): StreamedResponse
    {
        // Verify the authenticated user owns this purchase
        if (auth()->user()->id !== $bookPurchase->enrollment->user_id) {
            abort(403, 'Unauthorized access to this book purchase');
        }

        // Record download
        $bookPurchase->recordDownload();

        // Stream book
        return $this->bookService->streamBook($bookPurchase->enrollment->course);
    }
}
