<?php

namespace App\Http\Controllers;

use App\Models\Book;
use App\Models\BookCategory;
use App\Models\BookIssue;
use App\Models\LibrarySetting;
use App\Models\Student;
use App\Models\Teacher;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;

class LibraryController extends Controller
{
    /**
     * Display library dashboard
     */
    public function index()
    {
        // স্ট্যাটিসটিক্স ডাটা
        $stats = [
            'total_books' => Book::count(),
            'available_books' => Book::sum('available_copies'),
            'issued_books' => BookIssue::where('status', 'issued')->count(),
            'overdue_books' => BookIssue::where('status', 'issued')
                                        ->where('due_date', '<', now())
                                        ->count(),
            'total_categories' => BookCategory::count(),
            'total_students' => Student::count()
        ];

        // সাম্প্রতিক ইস্যু
        $recentIssues = BookIssue::with('book', 'student', 'teacher')
                                ->orderBy('issue_date', 'desc')
                                ->limit(10)
                                ->get();

        // জনপ্রিয় বই
        $popularBooks = Book::withCount('issues')
                           ->orderBy('issues_count', 'desc')
                           ->limit(5)
                           ->get();

        // ভিউতে ডাটা পাঠান
        return view('library.index', compact('stats', 'recentIssues', 'popularBooks'));
    }

    /**
     * Book management
     */
    public function books(Request $request)
    {
        $query = Book::with('category');

        if ($request->search) {
            $query->where(function($q) use ($request) {
                $q->where('title', 'like', '%' . $request->search . '%')
                  ->orWhere('title_bn', 'like', '%' . $request->search . '%')
                  ->orWhere('author', 'like', '%' . $request->search . '%')
                  ->orWhere('isbn', 'like', '%' . $request->search . '%')
                  ->orWhere('book_id', 'like', '%' . $request->search . '%');
            });
        }

        if ($request->category) {
            $query->where('category_id', $request->category);
        }

        if ($request->availability) {
            if ($request->availability == 'available') {
                $query->where('available_copies', '>', 0);
            } elseif ($request->availability == 'unavailable') {
                $query->where('available_copies', 0);
            }
        }

        $books = $query->orderBy('title')->paginate(20);
        $categories = BookCategory::all();

        return view('library.books', compact('books', 'categories', 'request'));
    }

    /**
     * Add new book
     */
    public function addBook(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'isbn' => 'nullable|string|unique:books',
            'title' => 'required|string|max:255',
            'title_bn' => 'nullable|string|max:255',
            'author' => 'required|string|max:255',
            'author_bn' => 'nullable|string|max:255',
            'publisher' => 'nullable|string|max:255',
            'category_id' => 'required|exists:book_categories,id',
            'shelf_location' => 'nullable|string|max:50',
            'total_copies' => 'required|integer|min:1',
            'price' => 'nullable|numeric|min:0',
            'pages' => 'nullable|integer|min:1',
            'language' => 'nullable|string|max:50',
            'publication_year' => 'nullable|integer|min:1900|max:' . date('Y'),
            'cover_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            $data = $request->all();
            $data['book_id'] = Book::generateBookId();
            $data['available_copies'] = $request->total_copies;

            // Upload cover image
            if ($request->hasFile('cover_image')) {
                $file = $request->file('cover_image');
                $filename = 'book_' . time() . '_' . $data['book_id'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/books/covers'), $filename);
                $data['cover_image'] = 'uploads/books/covers/' . $filename;
            }

            Book::create($data);

            return redirect()->route('library.books')
                           ->with('success', 'বই সফলভাবে যোগ করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'বই যোগ করতে সমস্যা হয়েছে')
                           ->withInput();
        }
    }

    /**
     * Issue book
     */
    public function issueBook(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'book_id' => 'required|exists:books,id',
            'student_id' => 'nullable|exists:students,id',
            'teacher_id' => 'nullable|exists:teachers,id',
            'due_date' => 'required|date|after:today'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        DB::beginTransaction();

        try {
            $book = Book::findOrFail($request->book_id);

            // Check availability
            if (!$book->isAvailable()) {
                return redirect()->back()
                               ->with('error', 'বইটি বর্তমানে লাইব্রেরিতে নেই');
            }

            // Check max books limit
            if ($request->student_id) {
                $issuedCount = BookIssue::where('student_id', $request->student_id)
                                       ->where('status', 'issued')
                                       ->count();
                
                $maxBooks = LibrarySetting::get('max_books_per_student', 3);
                
                if ($issuedCount >= $maxBooks) {
                    return redirect()->back()
                                   ->with('error', 'এই ছাত্র সর্বোচ্চ ' . $maxBooks . ' টি বই নিতে পারবেন');
                }
            }

            // Create issue record
            BookIssue::create([
                'book_id' => $book->id,
                'student_id' => $request->student_id,
                'teacher_id' => $request->teacher_id,
                'issue_date' => now(),
                'due_date' => $request->due_date,
                'status' => 'issued',
                'issued_by' => auth()->id()
            ]);

            // Update book availability
            $book->decreaseAvailable();

            DB::commit();

            return redirect()->route('library.issues')
                           ->with('success', 'বই ইস্যু করা হয়েছে');

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                           ->with('error', 'বই ইস্যু করতে সমস্যা হয়েছে');
        }
    }

    /**
     * Return book
     */
    public function returnBook(Request $request, $id)
    {
        $issue = BookIssue::findOrFail($id);

        DB::beginTransaction();

        try {
            $fine = 0;
            if ($request->has('calculate_fine')) {
                $fine = $issue->calculateFine();
            }

            $issue->return_date = now();
            $issue->status = 'returned';
            $issue->fine_amount = $fine;
            $issue->returned_to = auth()->id();
            $issue->remarks = $request->remarks;
            $issue->save();

            // Update book availability
            $issue->book->increaseAvailable();

            DB::commit();

            return redirect()->route('library.issues')
                           ->with('success', 'বই ফেরত নেওয়া হয়েছে' . ($fine > 0 ? '। জরিমানা: ' . $fine . ' টাকা' : ''));

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                           ->with('error', 'বই ফেরত নিতে সমস্যা হয়েছে');
        }
    }

    /**
     * Book issues list
     */
    public function issues(Request $request)
    {
        $query = BookIssue::with('book', 'student', 'teacher');

        if ($request->status) {
            if ($request->status == 'overdue') {
                $query->where('status', 'issued')
                      ->where('due_date', '<', now());
            } else {
                $query->where('status', $request->status);
            }
        }

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

        $issues = $query->orderBy('issue_date', 'desc')->paginate(20);

        return view('library.issues', compact('issues', 'request'));
    }

    /**
     * Search books (AJAX)
     */
    public function searchBooks(Request $request)
    {
        $query = Book::where('available_copies', '>', 0);

        if ($request->q) {
            $query->where(function($q) use ($request) {
                $q->where('title', 'like', '%' . $request->q . '%')
                  ->orWhere('title_bn', 'like', '%' . $request->q . '%')
                  ->orWhere('author', 'like', '%' . $request->q . '%')
                  ->orWhere('book_id', 'like', '%' . $request->q . '%');
            });
        }

        $books = $query->limit(10)->get();

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

    /**
     * Generate book barcode
     */
    public function generateBarcode($id)
    {
        $book = Book::findOrFail($id);
        
        $barcode = \SimpleSoftwareIO\QrCode\Facades\QrCode::size(200)
                        ->format('png')
                        ->generate($book->book_id);
        
        return response($barcode)->header('Content-Type', 'image/png');
    }

    /**
     * Download book list PDF
     */
    public function downloadBookList(Request $request)
    {
        $books = Book::with('category')
                    ->orderBy('title')
                    ->get();

        $pdf = \Barryvdh\DomPDF\Facade\Pdf::loadView('library.books-pdf', compact('books'));
        
        return $pdf->download('book_list_' . date('Y-m-d') . '.pdf');
    }

    /**
     * Student book history
     */
    public function studentHistory($studentId)
    {
        $student = Student::findOrFail($studentId);
        
        $issues = BookIssue::with('book')
                          ->where('student_id', $studentId)
                          ->orderBy('issue_date', 'desc')
                          ->get();

        return view('library.student-history', compact('student', 'issues'));
    }

    /**
     * Library settings
     */
    public function settings()
    {
        $settings = LibrarySetting::all()->pluck('value', 'key')->toArray();
        
        return view('library.settings', compact('settings'));
    }

    /**
     * Update settings
     */
    public function updateSettings(Request $request)
    {
        foreach ($request->except('_token') as $key => $value) {
            LibrarySetting::set($key, $value);
        }

        return redirect()->route('library.settings')
                       ->with('success', 'সেটিংস আপডেট করা হয়েছে');
    }

    /**
     * Category management
     */
    public function categories()
    {
        $categories = BookCategory::withCount('books')->get();
        
        return view('library.categories', compact('categories'));
    }

    /**
     * Add category
     */
    public function addCategory(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255|unique:book_categories',
            'name_bn' => 'nullable|string|max:255',
            'description' => 'nullable|string'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            BookCategory::create($request->all());

            return redirect()->route('library.categories')
                           ->with('success', 'ক্যাটাগরি যোগ করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'ক্যাটাগরি যোগ করতে সমস্যা হয়েছে');
        }
    }
}