<?php

namespace App\Http\Controllers;

use App\Models\Book;
use App\Models\Category;
use App\Models\Loan;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class BacaOnlineController extends Controller
{
    public function index(Request $request): View
    {
        $filters = $request->only(['search', 'kategori', 'tahun', 'penulis']);
        
        $query = Book::with('category')->whereJsonContains('tipe_akses', 'online');

        if ($request->filled('search')) {
            $query->where('judul', 'like', '%' . $request->search . '%');
        }

        if ($request->filled('kategori')) {
            $query->whereHas('category', function($q) use ($request) {
                $q->where('name', $request->kategori);
            });
        }

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

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

        $semuaBuku = $query->latest()->get();

        $filterOptions = [
            'kategori' => Category::pluck('name')->unique()->sort()->values(),
            'tahun' => Book::pluck('tahun')->unique()->sortDesc()->values(),
            'penulis' => Book::pluck('penulis')->unique()->sort()->values(),
        ];

        return view('katalog.index', [
            'semuaBuku' => $semuaBuku,
            'filterOptions' => $filterOptions,
            'input' => $request->query(),
            'pageTitle' => 'Baca Buku Online',
            'mode' => 'online', 
        ]);
    }

    public function ringkasan(int $id): View
    {
        $book = Book::with('category')->findOrFail($id);

        return view('katalog.ringkasan', [
            'buku' => $book,
            'pageTitle' => 'Baca Buku Online',
            'actionRoute' => 'baca.request_code',
            'previousRoute' => 'baca.index',
            'actionButtonText' => 'Baca Sekarang',
            'actionButtonIcon' => 'bi-book-half',
        ]);
    }

    public function showCodeRequestPage(int $id): View
    {
        $book = Book::findOrFail($id);
        $sessionKey = 'access_code_for_book_' . $id;

        if (session()->has($sessionKey)) {
            $accessCode = session($sessionKey);
        } else {
            $accessCode = 'BCO-' . date('Ymd') . '-' . $book->id . '-' . Str::upper(Str::random(4));
            session([$sessionKey => $accessCode]);
        }

        session(['book_verified_' . $id => false]);

        return view('baca.request_code', [
            'book' => $book,
            'accessCode' => $accessCode
        ]);
    }

    public function verifyCode(Request $request, int $id): RedirectResponse
    {
        $request->validate(['kode_akses' => 'required|string']);
        $correctCode = session('access_code_for_book_' . $id);

        if ($request->input('kode_akses') === $correctCode) {
            session(['book_verified_' . $id => true]);
            
            // Track history
            Loan::updateOrCreate(
                [
                    'user_id' => Auth::id(),
                    'book_id' => $id,
                    'status' => 'Online',
                ],
                [
                    'loan_code' => $correctCode,
                    'borrowed_at' => now(),
                ]
            );

            session()->forget('access_code_for_book_' . $id);
            return redirect()->route('baca.view_book', ['id' => $id]);
        }

        return back()->with('error', 'Kode akses yang Anda masukkan salah!');
    }

    public function viewBook(int $id): View|RedirectResponse
    {
        if (!session('book_verified_' . $id, false)) {
            return redirect()->route('baca.request_code', ['id' => $id])
                ->with('error', 'Silakan masukkan kode akses terlebih dahulu.');
        }
        $book = Book::findOrFail($id);
        return view('baca.view_book', ['book' => $book]);
    }

    public function streamPdf(int $id): BinaryFileResponse|Response
    {
        if (!session('book_verified_' . $id, false)) {
            abort(403, 'Akses Ditolak.');
        }
        $book = Book::findOrFail($id);
        $fileName = $book->file_pdf ?? 'sample.pdf';
        $filePath = 'books/' . $fileName;
        
        if (!Storage::disk('local')->exists($filePath)) {
             abort(404, 'File PDF tidak ditemukan di server.');
        }

        $absolutePath = Storage::disk('local')->path($filePath);

        return response()->file($absolutePath);
    }
}
