<?php

namespace App\Http\Controllers\Admin\Rental;

use App\Http\Controllers\Controller;
use App\Http\Requests\Rental\CloseRentalRequest;
use App\Http\Requests\Rental\StoreRentalRequest;
use App\Models\Car;
use App\Models\Customer;
use App\Models\Rental\Rental;
use App\Services\Rental\RentalService;
use Carbon\Carbon;
use Illuminate\Http\Request;

class RentalController extends Controller
{
    protected $rentalService;

    public function __construct(RentalService $rentalService)
    {
        $this->rentalService = $rentalService;
    }

    public function index(Request $request)
    {
        $this->authorize('viewAny', Rental::class);

        $query = Rental::with(['car', 'customer'])->latest();
        
        $user = auth()->user();
        if (!$user->isAdmin() && $user->branch_id) {
            $query->where('branch_id', $user->branch_id);
        }

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

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

        if ($request->date_from) {
            $query->whereDate('start_date', '>=', $request->date_from);
        }

        if ($request->date_to) {
            $query->whereDate('start_date', '<=', $request->date_to);
        }

        $rentals = $query->paginate(10);

        return view('admin.rentals.index', compact('rentals'));
    }

    public function create()
    {
        $this->authorize('create', Rental::class);

        $user = auth()->user();
        $query = Car::where('rental_status', 'available');
        
        // If user is admin and doesn't have a branch_id, start with empty car list
        // and force them to select a branch first in the view.
        if ($user->isAdmin() && !$user->branch_id) {
            $query->whereRaw('1=0');
        } else if ($user->branch_id) {
            $query->where('branch_id', $user->branch_id);
        }
        
        $cars = $query->get();
        $customers = Customer::all();
        $branches = \App\Models\Branch::where('status', 'active')->orderBy('name')->get();

        return view('admin.rentals.create', compact('cars', 'customers', 'branches'));
    }

    public function getCarsByBranch($branchId = null)
    {
        $query = Car::where('rental_status', 'available');
        
        if ($branchId && $branchId !== 'null' && $branchId !== 'undefined') {
            $query->where('branch_id', $branchId);
        } else {
            // If no branch is selected, return empty for admins, 
            // though non-admins will be caught by global scope.
            if (auth()->user()->isAdmin()) {
                return response()->json([]);
            }
        }
        
        $cars = $query->get(['id', 'title', 'daily_price', 'allowed_km_per_day', 'extra_km_price', 'mileage']);
        
        return response()->json($cars);
    }

    public function store(StoreRentalRequest $request)
    {
        $this->authorize('create', Rental::class);

        try {
            $data = $request->validated();

            if ($request->hasFile('paper_contract')) {
                $path = $request->file('paper_contract')->store('contracts', 'public');
                $data['paper_contract'] = $path;
            }

            // Clean additional terms from empty entries
            if (isset($data['additional_terms'])) {
                $data['additional_terms'] = array_values(array_filter($data['additional_terms']));
            }

            $rental = $this->rentalService->createRental($data);

            return redirect()->route('admin.rentals.show', $rental)
                ->with('success', 'Rental contract created successfully.');
        } catch (\Exception $e) {
            return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function show(Rental $rental)
    {
        $this->authorize('view', $rental);
        $rental->load(['car', 'customer', 'addons', 'payments', 'violations']);

        $overdueDays = $this->rentalService->getOverdueDays($rental);

        return view('admin.rentals.show', compact('rental', 'overdueDays'));
    }

    public function closeScreen(Rental $rental)
    {
        $this->authorize('close', $rental);

        if ($rental->status !== 'open') {
            return redirect()->route('admin.rentals.show', $rental)
                ->with('error', 'This rental is already closed or cancelled.');
        }

        return view('admin.rentals.close', compact('rental'));
    }

    public function close(CloseRentalRequest $request, Rental $rental)
    {
        $this->authorize('close', $rental);

        try {
            $this->rentalService->closeRental($rental, $request->validated());

            return redirect()->route('admin.rentals.show', $rental)
                ->with('success', 'Rental contract closed successfully.');
        } catch (\Exception $e) {
            return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function generatePdf(Rental $rental)
    {
        $this->authorize('view', $rental);
        $rental->load(['car', 'customer', 'addons', 'payments']);

        return view('admin.rentals.pdf', compact('rental'));
    }

    public function calendar(Request $request)
    {
        $this->authorize('viewAny', Rental::class);

        $month = $request->month ? Carbon::parse($request->month) : Carbon::now();
        $daysInMonth = $month->daysInMonth;

        $cars = Car::with(['rentals' => function ($q) use ($month) {
            $q->where(function ($query) use ($month) {
                $query->whereBetween('start_date', [$month->copy()->startOfMonth(), $month->copy()->endOfMonth()])
                    ->orWhereBetween('end_date', [$month->copy()->startOfMonth(), $month->copy()->endOfMonth()]);
            });
        }])->get();

        return view('admin.rentals.calendar', compact('cars', 'month', 'daysInMonth'));
    }

    public function dashboard()
    {
        $activeRentalsCount = Rental::where('status', 'open')->count();
        $monthlyRevenue = Rental::whereMonth('created_at', Carbon::now()->month)
            ->whereYear('created_at', Carbon::now()->year)
            ->sum('total_amount');
        $totalContracts = Rental::count();
        $availableCarsCount = Car::where('rental_status', 'available')->count();

        $recentRentals = Rental::with(['car', 'customer'])->latest()->take(5)->get();

        return view('admin.rentals.dashboard', compact(
            'activeRentalsCount',
            'monthlyRevenue',
            'totalContracts',
            'availableCarsCount',
            'recentRentals'
        ));
    }
}
